tdesktop/Telegram/SourceFiles/storage/storage_user_photos.h

195 lines
3.7 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <rpl/event_stream.h>
#include "storage/storage_facade.h"
namespace Storage {
struct UserPhotosSetBack {
UserPhotosSetBack(UserId userId, PhotoId photoId)
: userId(userId), photoId(photoId) {
}
UserId userId = 0;
PhotoId photoId = 0;
};
struct UserPhotosAddNew {
UserPhotosAddNew(UserId userId, PhotoId photoId)
: userId(userId), photoId(photoId) {
}
UserId userId = 0;
PhotoId photoId = 0;
};
struct UserPhotosAddSlice {
UserPhotosAddSlice(
UserId userId,
std::vector<PhotoId> &&photoIds,
int count)
: userId(userId)
, photoIds(std::move(photoIds))
, count(count) {
}
UserId userId = 0;
std::vector<PhotoId> photoIds;
int count = 0;
};
struct UserPhotosRemoveOne {
UserPhotosRemoveOne(
UserId userId,
PhotoId photoId)
: userId(userId)
, photoId(photoId) {
}
UserId userId = 0;
PhotoId photoId = 0;
};
struct UserPhotosRemoveAfter {
UserPhotosRemoveAfter(
UserId userId,
PhotoId photoId)
: userId(userId)
, photoId(photoId) {
}
UserId userId = 0;
PhotoId photoId = 0;
};
struct UserPhotosKey {
UserPhotosKey(
UserId userId,
PhotoId photoId)
: userId(userId)
, photoId(photoId) {
}
UserPhotosKey(UserId userId, bool back) : userId(userId), back(back) {
}
bool operator==(const UserPhotosKey &other) const {
return (userId == other.userId)
&& (photoId == other.photoId)
&& (back == other.back);
}
bool operator!=(const UserPhotosKey &other) const {
return !(*this == other);
}
UserId userId = 0;
PhotoId photoId = 0;
bool back = false;
};
struct UserPhotosQuery {
UserPhotosQuery(
UserPhotosKey key,
int limitBefore,
int limitAfter)
: key(key)
, limitBefore(limitBefore)
, limitAfter(limitAfter) {
}
UserPhotosKey key;
int limitBefore = 0;
int limitAfter = 0;
};
struct UserPhotosResult {
std::optional<int> count;
std::optional<int> skippedBefore;
int skippedAfter = 0;
std::deque<PhotoId> photoIds;
};
struct UserPhotosSliceUpdate {
UserPhotosSliceUpdate(
UserId userId,
const std::deque<PhotoId> *photoIds,
std::optional<int> count)
: userId(userId)
, photoIds(photoIds)
, count(count) {
}
UserId userId = 0;
const std::deque<PhotoId> *photoIds = nullptr;
std::optional<int> count;
};
class UserPhotos {
public:
void add(UserPhotosSetBack &&query);
void add(UserPhotosAddNew &&query);
void add(UserPhotosAddSlice &&query);
void remove(UserPhotosRemoveOne &&query);
void remove(UserPhotosRemoveAfter &&query);
rpl::producer<UserPhotosResult> query(UserPhotosQuery &&query) const;
rpl::producer<UserPhotosSliceUpdate> sliceUpdated() const;
private:
class List {
public:
void setBack(PhotoId photoId);
void addNew(PhotoId photoId);
void addSlice(
std::vector<PhotoId> &&photoIds,
int count);
void removeOne(PhotoId photoId);
void removeAfter(PhotoId photoId);
rpl::producer<UserPhotosResult> query(UserPhotosQuery &&query) const;
struct SliceUpdate {
const std::deque<PhotoId> *photoIds = nullptr;
std::optional<int> count;
};
rpl::producer<SliceUpdate> sliceUpdated() const;
private:
void sendUpdate();
void detachBack();
void attachBack();
std::optional<int> _count;
std::deque<PhotoId> _photoIds;
PhotoId _backPhotoId = PhotoId(0);
rpl::event_stream<SliceUpdate> _sliceUpdated;
};
using SliceUpdate = List::SliceUpdate;
std::map<UserId, List>::iterator enforceLists(UserId user);
std::map<UserId, List> _lists;
rpl::event_stream<UserPhotosSliceUpdate> _sliceUpdated;
rpl::lifetime _lifetime;
};
} // namespace Storage