mirror of https://github.com/procxx/kepka.git
Remove all legacy media overview code.
This commit is contained in:
parent
273ac5eaf1
commit
9bbcbd4bb3
|
@ -1040,8 +1040,7 @@ namespace {
|
|||
existing->updateMedia(m.has_media() ? (&m.vmedia) : nullptr);
|
||||
existing->updateReplyMarkup(m.has_reply_markup() ? (&m.vreply_markup) : nullptr);
|
||||
existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
|
||||
existing->addToOverview(AddToOverviewNew);
|
||||
|
||||
existing->addToUnreadMentions(AddToUnreadMentionsMethod::New);
|
||||
if (auto sharedMediaTypes = existing->sharedMediaTypes()) {
|
||||
Auth().storage().add(Storage::SharedMediaAddNew(
|
||||
peerId,
|
||||
|
|
|
@ -36,25 +36,17 @@ namespace {
|
|||
|
||||
using Type = Storage::SharedMediaType;
|
||||
|
||||
inline MediaOverviewType SharedMediaTypeToOverview(Type type) {
|
||||
switch (type) {
|
||||
case Type::Photo: return OverviewPhotos;
|
||||
case Type::Video: return OverviewVideos;
|
||||
case Type::MusicFile: return OverviewMusicFiles;
|
||||
case Type::File: return OverviewFiles;
|
||||
case Type::VoiceFile: return OverviewVoiceFiles;
|
||||
case Type::Link: return OverviewLinks;
|
||||
default: break;
|
||||
}
|
||||
return OverviewCount;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
base::optional<Storage::SharedMediaType> SharedMediaOverviewType(
|
||||
Storage::SharedMediaType type) {
|
||||
if (SharedMediaTypeToOverview(type) != OverviewCount) {
|
||||
return type;
|
||||
switch (type) {
|
||||
case Type::Photo:
|
||||
case Type::Video:
|
||||
case Type::MusicFile:
|
||||
case Type::File:
|
||||
case Type::VoiceFile:
|
||||
case Type::Link: return type;
|
||||
}
|
||||
return base::none;
|
||||
}
|
||||
|
|
|
@ -66,14 +66,6 @@ HistoryItem *createUnsupportedMessage(History *history, MsgId msgId, MTPDmessage
|
|||
return HistoryMessage::create(history, msgId, flags, replyTo, viaBotId, date, from, QString(), text);
|
||||
}
|
||||
|
||||
Storage::SharedMediaType ConvertSharedMediaType(MediaOverviewType type) {
|
||||
return static_cast<Storage::SharedMediaType>(type);
|
||||
}
|
||||
|
||||
MediaOverviewType ConvertSharedMediaType(Storage::SharedMediaType type) {
|
||||
return static_cast<MediaOverviewType>(type);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void HistoryInit() {
|
||||
|
@ -90,9 +82,6 @@ History::History(const PeerId &peerId)
|
|||
if (peer->isUser() && peer->asUser()->botInfo) {
|
||||
outboxReadBefore = INT_MAX;
|
||||
}
|
||||
for (auto &countData : _overviewCountData) {
|
||||
countData = -1; // not loaded yet
|
||||
}
|
||||
}
|
||||
|
||||
void History::clearLastKeyboard() {
|
||||
|
@ -1173,28 +1162,6 @@ HistoryItem *History::addNewGame(MsgId id, MTPDmessage::Flags flags, UserId viaB
|
|||
return addNewItem(createItemGame(id, flags, viaBotId, replyTo, date, from, postAuthor, game, markup), true);
|
||||
}
|
||||
|
||||
bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method) {
|
||||
_overview[type].insert(msgId);
|
||||
if (method == AddToOverviewNew) {
|
||||
if (_overviewCountData[type] > 0) {
|
||||
++_overviewCountData[type];
|
||||
}
|
||||
Notify::mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
|
||||
auto i = _overview[type].find(msgId);
|
||||
if (i == _overview[type].cend()) return;
|
||||
|
||||
_overview[type].erase(i);
|
||||
if (_overviewCountData[type] > 0) {
|
||||
--_overviewCountData[type];
|
||||
}
|
||||
Notify::mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
|
||||
void History::setUnreadMentionsCount(int count) {
|
||||
if (_unreadMentions.size() > count) {
|
||||
LOG(("API Warning: real mentions count is greater than received mentions count"));
|
||||
|
@ -1203,15 +1170,17 @@ void History::setUnreadMentionsCount(int count) {
|
|||
_unreadMentionsCount = count;
|
||||
}
|
||||
|
||||
bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
|
||||
bool History::addToUnreadMentions(
|
||||
MsgId msgId,
|
||||
AddToUnreadMentionsMethod method) {
|
||||
auto allLoaded = _unreadMentionsCount ? (_unreadMentions.size() >= *_unreadMentionsCount) : false;
|
||||
if (allLoaded) {
|
||||
if (method == AddToOverviewNew) {
|
||||
if (method == AddToUnreadMentionsMethod::New) {
|
||||
++*_unreadMentionsCount;
|
||||
_unreadMentions.insert(msgId);
|
||||
return true;
|
||||
}
|
||||
} else if (!_unreadMentions.empty() && method != AddToOverviewNew) {
|
||||
} else if (!_unreadMentions.empty() && method != AddToUnreadMentionsMethod::New) {
|
||||
_unreadMentions.insert(msgId);
|
||||
return true;
|
||||
}
|
||||
|
@ -1290,7 +1259,7 @@ HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
|||
newItemAdded(adding);
|
||||
}
|
||||
|
||||
adding->addToOverview(AddToOverviewNew);
|
||||
adding->addToUnreadMentions(AddToUnreadMentionsMethod::New);
|
||||
if (IsServerMsgId(adding->id)) {
|
||||
if (auto sharedMediaTypes = adding->sharedMediaTypes()) {
|
||||
if (newMsg) {
|
||||
|
@ -1588,7 +1557,6 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice) {
|
|||
oldLoaded = true;
|
||||
} else if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors
|
||||
bool channel = isChannel();
|
||||
int32 mask = 0;
|
||||
std::deque<not_null<UserData*>> *lastAuthors = nullptr;
|
||||
base::flat_set<not_null<PeerData*>> *markupSenders = nullptr;
|
||||
if (peer->isChat()) {
|
||||
|
@ -1605,7 +1573,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice) {
|
|||
}
|
||||
for (auto i = block->items.size(); i > 0; --i) {
|
||||
auto item = block->items[i - 1];
|
||||
mask |= item->addToOverview(AddToOverviewFront);
|
||||
item->addToUnreadMentions(AddToUnreadMentionsMethod::Front);
|
||||
if (item->from()->id) {
|
||||
if (lastAuthors) { // chats
|
||||
if (auto user = item->from()->asUser()) {
|
||||
|
@ -1659,12 +1627,6 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (mask) {
|
||||
Notify::PeerUpdate update(peer);
|
||||
update.flags |= Notify::PeerUpdate::Flag::SharedMediaChanged;
|
||||
update.mediaTypesMask |= mask;
|
||||
Notify::peerUpdatedDelayed(update);
|
||||
}
|
||||
}
|
||||
|
||||
logged.push_back(QString::number(minAdded));
|
||||
|
@ -1743,7 +1705,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice) {
|
|||
}
|
||||
|
||||
if (!wasLoadedAtBottom) {
|
||||
checkAddAllToOverview();
|
||||
checkAddAllToUnreadMentions();
|
||||
}
|
||||
|
||||
if (isChannel()) asChannelHistory()->checkJoinedMessage();
|
||||
|
@ -1754,30 +1716,23 @@ void History::checkLastMsg() {
|
|||
if (lastMsg) {
|
||||
if (!newLoaded && !lastMsg->detached()) {
|
||||
newLoaded = true;
|
||||
checkAddAllToOverview();
|
||||
checkAddAllToUnreadMentions();
|
||||
}
|
||||
} else if (newLoaded) {
|
||||
setLastMessage(lastAvailableMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void History::checkAddAllToOverview() {
|
||||
void History::checkAddAllToUnreadMentions() {
|
||||
if (!loadedAtBottom()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32 mask = 0;
|
||||
for_const (auto block, blocks) {
|
||||
for_const (auto item, block->items) {
|
||||
mask |= item->addToOverview(AddToOverviewBack);
|
||||
item->addToUnreadMentions(AddToUnreadMentionsMethod::Back);
|
||||
}
|
||||
}
|
||||
if (mask) {
|
||||
Notify::PeerUpdate update(peer);
|
||||
update.flags |= Notify::PeerUpdate::Flag::SharedMediaChanged;
|
||||
update.mediaTypesMask |= mask;
|
||||
Notify::peerUpdatedDelayed(update);
|
||||
}
|
||||
}
|
||||
|
||||
void History::addBlockToSharedMedia(HistoryBlock *block) {
|
||||
|
@ -2348,15 +2303,6 @@ void History::clear(bool leaveItems) {
|
|||
++i;
|
||||
}
|
||||
}
|
||||
for (auto i = 0; i != OverviewCount; ++i) {
|
||||
if (!_overview[i].isEmpty()) {
|
||||
_overviewCountData[i] = -1; // not loaded yet
|
||||
_overview[i].clear();
|
||||
if (!App::quitting()) {
|
||||
Notify::mediaOverviewUpdated(peer, MediaOverviewType(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
Auth().storage().remove(Storage::SharedMediaRemoveAll(peer->id));
|
||||
Auth().data().markHistoryCleared(this);
|
||||
}
|
||||
|
@ -2521,91 +2467,7 @@ void History::setPinnedIndex(int pinnedIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
void History::overviewSliceDone(
|
||||
int32 overviewIndex,
|
||||
MsgId startMessageId,
|
||||
const MTPmessages_Messages &result,
|
||||
bool onlyCounts) {
|
||||
auto fullCount = 0;
|
||||
auto v = (const QVector<MTPMessage>*)nullptr;
|
||||
|
||||
switch (result.type()) {
|
||||
case mtpc_messages_messages: {
|
||||
auto &d = result.c_messages_messages();
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
v = &d.vmessages.v;
|
||||
fullCount = v->size();
|
||||
_overviewCountData[overviewIndex] = 0;
|
||||
} break;
|
||||
|
||||
case mtpc_messages_messagesSlice: {
|
||||
auto &d = result.c_messages_messagesSlice();
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
fullCount = _overviewCountData[overviewIndex] = d.vcount.v;
|
||||
v = &d.vmessages.v;
|
||||
} break;
|
||||
|
||||
case mtpc_messages_channelMessages: {
|
||||
auto &d = result.c_messages_channelMessages();
|
||||
if (peer->isChannel()) {
|
||||
peer->asChannel()->ptsReceived(d.vpts.v);
|
||||
} else {
|
||||
LOG(("API Error: received messages.channelMessages when no channel was passed! (History::overviewSliceDone, onlyCounts %1)").arg(Logs::b(onlyCounts)));
|
||||
}
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
fullCount = _overviewCountData[overviewIndex] = d.vcount.v;
|
||||
v = &d.vmessages.v;
|
||||
} break;
|
||||
|
||||
case mtpc_messages_messagesNotModified: {
|
||||
LOG(("API Error: received messages.messagesNotModified! (History::overviewSliceDone, onlyCounts %1)").arg(Logs::b(onlyCounts)));
|
||||
} break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (!onlyCounts && (!v || v->isEmpty())) {
|
||||
_overviewCountData[overviewIndex] = 0;
|
||||
}
|
||||
|
||||
auto noSkipRange = MsgRange { startMessageId, startMessageId };
|
||||
auto sharedMediaType = ConvertSharedMediaType(
|
||||
static_cast<MediaOverviewType>(overviewIndex));
|
||||
auto slice = std::vector<MsgId>();
|
||||
if (v) {
|
||||
slice.reserve(v->size());
|
||||
for (auto &message : *v) {
|
||||
if (auto item = App::histories().addNewMessage(message, NewMessageExisting)) {
|
||||
auto itemId = item->id;
|
||||
_overview[overviewIndex].insert(itemId);
|
||||
if (item->sharedMediaTypes().test(sharedMediaType)) {
|
||||
slice.push_back(itemId);
|
||||
accumulate_min(noSkipRange.from, itemId);
|
||||
accumulate_max(noSkipRange.till, itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Auth().storage().add(Storage::SharedMediaAddSlice(
|
||||
peer->id,
|
||||
sharedMediaType,
|
||||
std::move(slice),
|
||||
noSkipRange,
|
||||
fullCount
|
||||
));
|
||||
}
|
||||
|
||||
void History::changeMsgId(MsgId oldId, MsgId newId) {
|
||||
for (auto i = 0; i != OverviewCount; ++i) {
|
||||
auto j = _overview[i].find(oldId);
|
||||
if (j != _overview[i].cend()) {
|
||||
_overview[i].erase(j);
|
||||
_overview[i].insert(newId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void History::removeBlock(HistoryBlock *block) {
|
||||
|
|
|
@ -140,20 +140,6 @@ enum HistoryMediaType {
|
|||
MediaTypeCount
|
||||
};
|
||||
|
||||
enum MediaOverviewType {
|
||||
OverviewPhotos = 0,
|
||||
OverviewVideos = 1,
|
||||
OverviewMusicFiles = 2,
|
||||
OverviewFiles = 3,
|
||||
OverviewVoiceFiles = 4,
|
||||
OverviewLinks = 5,
|
||||
OverviewChatPhotos = 6,
|
||||
OverviewRoundVoiceFiles = 7,
|
||||
OverviewGIFs = 8,
|
||||
|
||||
OverviewCount
|
||||
};
|
||||
|
||||
struct TextWithTags {
|
||||
struct Tag {
|
||||
int offset, length;
|
||||
|
@ -186,10 +172,10 @@ struct Draft;
|
|||
class HistoryMedia;
|
||||
class HistoryMessage;
|
||||
|
||||
enum AddToOverviewMethod {
|
||||
AddToOverviewNew, // when new message is added to history
|
||||
AddToOverviewFront, // when old messages slice was received
|
||||
AddToOverviewBack, // when new messages slice was received and it is the last one, we index all media
|
||||
enum class AddToUnreadMentionsMethod {
|
||||
New, // when new message is added to history
|
||||
Front, // when old messages slice was received
|
||||
Back, // when new messages slice was received and it is the last one, we index all media
|
||||
};
|
||||
|
||||
namespace Dialogs {
|
||||
|
@ -244,8 +230,6 @@ public:
|
|||
|
||||
void addOlderSlice(const QVector<MTPMessage> &slice);
|
||||
void addNewerSlice(const QVector<MTPMessage> &slice);
|
||||
bool addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method);
|
||||
void eraseFromOverview(MediaOverviewType type, MsgId msgId);
|
||||
|
||||
void newItemAdded(HistoryItem *item);
|
||||
|
||||
|
@ -382,7 +366,7 @@ public:
|
|||
return (getUnreadMentionsCount() > 0);
|
||||
}
|
||||
void setUnreadMentionsCount(int count);
|
||||
bool addToUnreadMentions(MsgId msgId, AddToOverviewMethod method);
|
||||
bool addToUnreadMentions(MsgId msgId, AddToUnreadMentionsMethod method);
|
||||
void eraseFromUnreadMentions(MsgId msgId);
|
||||
void addUnreadMentionsSlice(const MTPmessages_Messages &result);
|
||||
|
||||
|
@ -478,39 +462,6 @@ public:
|
|||
mutable const HistoryItem *textCachedFor = nullptr; // cache
|
||||
mutable Text lastItemTextCache;
|
||||
|
||||
bool overviewCountLoaded(int32 overviewIndex) const {
|
||||
return _overviewCountData[overviewIndex] >= 0;
|
||||
}
|
||||
bool overviewLoaded(int32 overviewIndex) const {
|
||||
return overviewCount(overviewIndex) == _overview[overviewIndex].size();
|
||||
}
|
||||
int overviewCount(int32 overviewIndex, int32 defaultValue = -1) const {
|
||||
auto result = _overviewCountData[overviewIndex];
|
||||
auto loaded = _overview[overviewIndex].size();
|
||||
if (result < 0) return defaultValue;
|
||||
if (result < loaded) {
|
||||
if (result > 0) {
|
||||
const_cast<History*>(this)->_overviewCountData[overviewIndex] = 0;
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const OrderedSet<MsgId> &overview(int32 overviewIndex) const {
|
||||
return _overview[overviewIndex];
|
||||
}
|
||||
MsgId overviewMinId(int32 overviewIndex) const {
|
||||
return _overview[overviewIndex].empty() ? 0 : *_overview[overviewIndex].begin();
|
||||
}
|
||||
void overviewSliceDone(
|
||||
int32 overviewIndex,
|
||||
MsgId startMessageId,
|
||||
const MTPmessages_Messages &result,
|
||||
bool onlyCounts = false);
|
||||
bool overviewHasMsgId(int32 overviewIndex, MsgId msgId) const {
|
||||
return _overview[overviewIndex].contains(msgId);
|
||||
}
|
||||
|
||||
void changeMsgId(MsgId oldId, MsgId newId);
|
||||
|
||||
Text cloudDraftTextCache;
|
||||
|
@ -557,8 +508,8 @@ private:
|
|||
// After adding a new history slice check the lastMsg and newLoaded.
|
||||
void checkLastMsg();
|
||||
|
||||
// Add all items to the media overview if we were not loaded at bottom and now are.
|
||||
void checkAddAllToOverview();
|
||||
// Add all items to the unread mentions if we were not loaded at bottom and now are.
|
||||
void checkAddAllToUnreadMentions();
|
||||
|
||||
template <int kSharedMediaTypeCount>
|
||||
void addToSharedMedia(std::vector<MsgId> (&medias)[kSharedMediaTypeCount], bool force);
|
||||
|
@ -594,9 +545,6 @@ private:
|
|||
}
|
||||
uint64 _sortKeyInChatList = 0; // like ((unixtime) << 32) | (incremented counter)
|
||||
|
||||
OrderedSet<MsgId> _overview[OverviewCount];
|
||||
int32 _overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded
|
||||
|
||||
// A pointer to the block that is currently being built.
|
||||
// We hold this pointer so we can destroy it while building
|
||||
// and then create a new one if it is necessary.
|
||||
|
|
|
@ -721,7 +721,7 @@ void HistoryItem::destroy() {
|
|||
Assert(detached());
|
||||
} else {
|
||||
// All this must be done for all items manually in History::clear(false)!
|
||||
eraseFromOverview();
|
||||
eraseFromUnreadMentions();
|
||||
if (IsServerMsgId(id)) {
|
||||
if (auto types = sharedMediaTypes()) {
|
||||
Auth().storage().remove(Storage::SharedMediaRemoveOne(
|
||||
|
|
|
@ -642,7 +642,7 @@ public:
|
|||
bool isPost() const {
|
||||
return _flags & MTPDmessage::Flag::f_post;
|
||||
}
|
||||
bool indexInOverview() const {
|
||||
bool indexInUnreadMentions() const {
|
||||
return (id > 0);
|
||||
}
|
||||
bool isSilent() const {
|
||||
|
@ -688,10 +688,9 @@ public:
|
|||
virtual void updateReplyMarkup(const MTPReplyMarkup *markup) {
|
||||
}
|
||||
|
||||
virtual int32 addToOverview(AddToOverviewMethod method) {
|
||||
return 0;
|
||||
virtual void addToUnreadMentions(AddToUnreadMentionsMethod method) {
|
||||
}
|
||||
virtual void eraseFromOverview() {
|
||||
virtual void eraseFromUnreadMentions() {
|
||||
}
|
||||
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
||||
|
||||
|
|
|
@ -84,11 +84,6 @@ public:
|
|||
virtual void updatePressed(QPoint point) {
|
||||
}
|
||||
|
||||
virtual int32 addToOverview(AddToOverviewMethod method) {
|
||||
return 0;
|
||||
}
|
||||
virtual void eraseFromOverview() {
|
||||
}
|
||||
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
||||
|
||||
// if we are in selecting items mode perhaps we want to
|
||||
|
@ -236,16 +231,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
int32 addToOneOverview(MediaOverviewType type, AddToOverviewMethod method) {
|
||||
if (_parent->history()->addToOverview(type, _parent->id, method)) {
|
||||
return (1 << type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void eraseFromOneOverview(MediaOverviewType type) {
|
||||
_parent->history()->eraseFromOverview(type, _parent->id);
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> _parent;
|
||||
int _width = 0;
|
||||
MediaInBubbleState _inBubbleState = MediaInBubbleState::None;
|
||||
|
|
|
@ -638,24 +638,6 @@ bool HistoryPhoto::needsBubble() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
int32 HistoryPhoto::addToOverview(AddToOverviewMethod method) {
|
||||
auto result = int32(0);
|
||||
if (_parent->toHistoryMessage()) {
|
||||
result |= addToOneOverview(OverviewPhotos, method);
|
||||
} else {
|
||||
result |= addToOneOverview(OverviewChatPhotos, method);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void HistoryPhoto::eraseFromOverview() {
|
||||
if (_parent->toHistoryMessage()) {
|
||||
eraseFromOneOverview(OverviewPhotos);
|
||||
} else {
|
||||
eraseFromOneOverview(OverviewChatPhotos);
|
||||
}
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryPhoto::sharedMediaTypes() const {
|
||||
if (_parent->toHistoryMessage()) {
|
||||
return Storage::SharedMediaType::Photo;
|
||||
|
@ -961,14 +943,6 @@ bool HistoryVideo::needsBubble() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
int32 HistoryVideo::addToOverview(AddToOverviewMethod method) {
|
||||
return addToOneOverview(OverviewVideos, method);
|
||||
}
|
||||
|
||||
void HistoryVideo::eraseFromOverview() {
|
||||
eraseFromOneOverview(OverviewVideos);
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryVideo::sharedMediaTypes() const {
|
||||
return Storage::SharedMediaType::Video;
|
||||
}
|
||||
|
@ -1585,30 +1559,6 @@ TextWithEntities HistoryDocument::selectedText(TextSelection selection) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
int32 HistoryDocument::addToOverview(AddToOverviewMethod method) {
|
||||
auto result = int32(0);
|
||||
if (_data->voice()) {
|
||||
result |= addToOneOverview(OverviewVoiceFiles, method);
|
||||
result |= addToOneOverview(OverviewRoundVoiceFiles, method);
|
||||
} else if (_data->isMusic()) {
|
||||
result |= addToOneOverview(OverviewMusicFiles, method);
|
||||
} else {
|
||||
result |= addToOneOverview(OverviewFiles, method);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void HistoryDocument::eraseFromOverview() {
|
||||
if (_data->voice()) {
|
||||
eraseFromOneOverview(OverviewVoiceFiles);
|
||||
eraseFromOneOverview(OverviewRoundVoiceFiles);
|
||||
} else if (_data->isMusic()) {
|
||||
eraseFromOneOverview(OverviewMusicFiles);
|
||||
} else {
|
||||
eraseFromOneOverview(OverviewFiles);
|
||||
}
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryDocument::sharedMediaTypes() const {
|
||||
using Type = Storage::SharedMediaType;
|
||||
if (_data->voice()) {
|
||||
|
@ -2433,18 +2383,6 @@ bool HistoryGif::needsBubble() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
int32 HistoryGif::addToOverview(AddToOverviewMethod method) {
|
||||
auto result = int32(0);
|
||||
if (_data->isRoundVideo()) {
|
||||
result |= addToOneOverview(OverviewRoundVoiceFiles, method);
|
||||
} else if (_data->isGifv()) {
|
||||
result |= addToOneOverview(OverviewGIFs, method);
|
||||
} else {
|
||||
result |= addToOneOverview(OverviewFiles, method);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryGif::sharedMediaTypes() const {
|
||||
using Type = Storage::SharedMediaType;
|
||||
if (_data->isRoundVideo()) {
|
||||
|
@ -2457,16 +2395,6 @@ Storage::SharedMediaTypesMask HistoryGif::sharedMediaTypes() const {
|
|||
return Type::File;
|
||||
}
|
||||
|
||||
void HistoryGif::eraseFromOverview() {
|
||||
if (_data->isRoundVideo()) {
|
||||
eraseFromOneOverview(OverviewRoundVoiceFiles);
|
||||
} else if (_data->isGifv()) {
|
||||
eraseFromOneOverview(OverviewGIFs);
|
||||
} else {
|
||||
eraseFromOneOverview(OverviewFiles);
|
||||
}
|
||||
}
|
||||
|
||||
QString HistoryGif::mediaTypeString() const {
|
||||
return _data->isRoundVideo() ? lang(lng_in_dlg_video_message) : qsl("GIF");
|
||||
}
|
||||
|
|
|
@ -164,8 +164,6 @@ public:
|
|||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
PhotoData *photo() const {
|
||||
|
@ -252,8 +250,6 @@ public:
|
|||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
DocumentData *getDocument() override {
|
||||
|
@ -412,8 +408,6 @@ public:
|
|||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
bool uploading() const override {
|
||||
|
@ -521,8 +515,6 @@ public:
|
|||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
bool uploading() const override {
|
||||
|
|
|
@ -1416,33 +1416,17 @@ void HistoryMessage::updateMedia(const MTPMessageMedia *media) {
|
|||
setPendingInitDimensions();
|
||||
}
|
||||
|
||||
int32 HistoryMessage::addToOverview(AddToOverviewMethod method) {
|
||||
if (!indexInOverview()) return 0;
|
||||
|
||||
int32 result = 0;
|
||||
if (auto media = getMedia()) {
|
||||
result |= media->addToOverview(method);
|
||||
}
|
||||
if (hasTextLinks()) {
|
||||
if (history()->addToOverview(OverviewLinks, id, method)) {
|
||||
result |= (1 << OverviewLinks);
|
||||
}
|
||||
}
|
||||
if (mentionsMe() && isMediaUnread()) {
|
||||
void HistoryMessage::addToUnreadMentions(AddToUnreadMentionsMethod method) {
|
||||
if (indexInUnreadMentions() && mentionsMe() && isMediaUnread()) {
|
||||
if (history()->addToUnreadMentions(id, method)) {
|
||||
Notify::peerUpdatedDelayed(history()->peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged);
|
||||
Notify::peerUpdatedDelayed(
|
||||
history()->peer,
|
||||
Notify::PeerUpdate::Flag::UnreadMentionsChanged);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void HistoryMessage::eraseFromOverview() {
|
||||
if (auto media = getMedia()) {
|
||||
media->eraseFromOverview();
|
||||
}
|
||||
if (hasTextLinks()) {
|
||||
history()->eraseFromOverview(OverviewLinks, id);
|
||||
}
|
||||
void HistoryMessage::eraseFromUnreadMentions() {
|
||||
if (mentionsMe() && isMediaUnread()) {
|
||||
history()->eraseFromUnreadMentions(id);
|
||||
}
|
||||
|
|
|
@ -107,8 +107,8 @@ public:
|
|||
setReplyMarkup(markup);
|
||||
}
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
void addToUnreadMentions(AddToUnreadMentionsMethod method) override;
|
||||
void eraseFromUnreadMentions() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
|
|
@ -738,16 +738,6 @@ void HistoryService::removeMedia() {
|
|||
}
|
||||
}
|
||||
|
||||
int32 HistoryService::addToOverview(AddToOverviewMethod method) {
|
||||
if (!indexInOverview()) return 0;
|
||||
|
||||
int32 result = 0;
|
||||
if (auto media = getMedia()) {
|
||||
result |= media->addToOverview(method);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryService::sharedMediaTypes() const {
|
||||
if (auto media = getMedia()) {
|
||||
return media->sharedMediaTypes();
|
||||
|
@ -755,12 +745,6 @@ Storage::SharedMediaTypesMask HistoryService::sharedMediaTypes() const {
|
|||
return {};
|
||||
}
|
||||
|
||||
void HistoryService::eraseFromOverview() {
|
||||
if (auto media = getMedia()) {
|
||||
media->eraseFromOverview();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryService::updateDependentText() {
|
||||
auto text = PreparedText {};
|
||||
if (Has<HistoryServicePinned>()) {
|
||||
|
|
|
@ -100,8 +100,6 @@ public:
|
|||
void applyEdition(const MTPDmessageService &message) override;
|
||||
TimeMs getSelfDestructIn(TimeMs now) override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
void eraseFromOverview() override;
|
||||
Storage::SharedMediaTypesMask sharedMediaTypes() const override;
|
||||
|
||||
bool needCheck() const override {
|
||||
|
|
|
@ -91,25 +91,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "storage/storage_shared_media.h"
|
||||
#include "storage/storage_user_photos.h"
|
||||
|
||||
namespace {
|
||||
|
||||
MTPMessagesFilter TypeToMediaFilter(MediaOverviewType &type) {
|
||||
switch (type) {
|
||||
case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
|
||||
case OverviewVideos: return MTP_inputMessagesFilterVideo();
|
||||
case OverviewMusicFiles: return MTP_inputMessagesFilterMusic();
|
||||
case OverviewFiles: return MTP_inputMessagesFilterDocument();
|
||||
case OverviewVoiceFiles: return MTP_inputMessagesFilterVoice();
|
||||
case OverviewRoundVoiceFiles: return MTP_inputMessagesFilterRoundVoice();
|
||||
case OverviewGIFs: return MTP_inputMessagesFilterGif();
|
||||
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
||||
case OverviewChatPhotos: return MTP_inputMessagesFilterChatPhotos();
|
||||
default: return MTP_inputMessagesFilterEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
enum StackItemType {
|
||||
HistoryStackItem,
|
||||
SectionStackItem,
|
||||
|
@ -1631,99 +1612,12 @@ void MainWidget::searchMessages(const QString &query, PeerData *inPeer) {
|
|||
}
|
||||
}
|
||||
|
||||
bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
|
||||
auto filter = TypeToMediaFilter(type);
|
||||
if (filter.type() == mtpc_inputMessagesFilterEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto history = App::history(peer->id);
|
||||
if (history->overviewCountLoaded(type) || _overviewPreload[type].contains(peer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto request = MTPmessages_Search(
|
||||
MTP_flags(0),
|
||||
peer->input,
|
||||
MTP_string(""),
|
||||
MTP_inputUserEmpty(),
|
||||
filter,
|
||||
MTP_int(0),
|
||||
MTP_int(0),
|
||||
MTP_int(0),
|
||||
MTP_int(0),
|
||||
MTP_int(0),
|
||||
MTP_int(0),
|
||||
MTP_int(0));
|
||||
_overviewPreload[type].insert(peer, MTP::send(
|
||||
request,
|
||||
rpcDone(&MainWidget::overviewPreloaded, peer),
|
||||
rpcFail(&MainWidget::overviewFailed, peer),
|
||||
0,
|
||||
10));
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWidget::overviewPreloaded(
|
||||
PeerData *peer,
|
||||
const MTPmessages_Messages &result,
|
||||
mtpRequestId req) {
|
||||
MediaOverviewType type = OverviewCount;
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
OverviewsPreload::iterator j = _overviewPreload[i].find(peer);
|
||||
if (j != _overviewPreload[i].end() && j.value() == req) {
|
||||
type = MediaOverviewType(i);
|
||||
_overviewPreload[i].erase(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == OverviewCount) return;
|
||||
|
||||
auto startMessageId = MsgId(0);
|
||||
App::history(peer->id)->overviewSliceDone(type, startMessageId, result, true);
|
||||
|
||||
Notify::mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
|
||||
void MainWidget::itemEdited(HistoryItem *item) {
|
||||
if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
|
||||
_history->itemEdited(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWidget::overviewFailed(PeerData *peer, const RPCError &error, mtpRequestId req) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
MediaOverviewType type = OverviewCount;
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
OverviewsPreload::iterator j = _overviewPreload[i].find(peer);
|
||||
if (j != _overviewPreload[i].end() && j.value() == req) {
|
||||
_overviewPreload[i].erase(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWidget::loadMediaBack(PeerData *peer, MediaOverviewType type, bool many) {
|
||||
if (_overviewLoad[type].constFind(peer) != _overviewLoad[type].cend()) return;
|
||||
|
||||
auto history = App::history(peer->id);
|
||||
if (history->overviewLoaded(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto minId = history->overviewMinId(type);
|
||||
auto limit = (many || history->overview(type).size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage;
|
||||
auto filter = TypeToMediaFilter(type);
|
||||
if (filter.type() == mtpc_inputMessagesFilterEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
_overviewLoad[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(0), peer->input, MTPstring(), MTP_inputUserEmpty(), filter, MTP_int(0), MTP_int(0), MTP_int(minId), MTP_int(0), MTP_int(limit), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewLoaded, { history, minId })));
|
||||
}
|
||||
|
||||
void MainWidget::checkLastUpdate(bool afterSleep) {
|
||||
auto n = getms(true);
|
||||
if (_lastUpdateTime && n > _lastUpdateTime + (afterSleep ? NoUpdatesAfterSleepTimeout : NoUpdatesTimeout)) {
|
||||
|
@ -1732,28 +1626,6 @@ void MainWidget::checkLastUpdate(bool afterSleep) {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWidget::overviewLoaded(
|
||||
std::pair<not_null<History*>,MsgId> historyAndStartMsgId,
|
||||
const MTPmessages_Messages &result,
|
||||
mtpRequestId req) {
|
||||
auto history = historyAndStartMsgId.first;
|
||||
OverviewsPreload::iterator it;
|
||||
MediaOverviewType type = OverviewCount;
|
||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
||||
it = _overviewLoad[i].find(history->peer);
|
||||
if (it != _overviewLoad[i].cend()) {
|
||||
type = MediaOverviewType(i);
|
||||
_overviewLoad[i].erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type == OverviewCount) return;
|
||||
|
||||
history->overviewSliceDone(type, historyAndStartMsgId.second, result);
|
||||
|
||||
Notify::mediaOverviewUpdated(history->peer, type);
|
||||
}
|
||||
|
||||
void MainWidget::messagesAffected(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedMessages &result) {
|
||||
|
@ -4948,7 +4820,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
|||
auto entities = d.has_entities() ? TextUtilities::EntitiesFromMTP(d.ventities.v) : EntitiesInText();
|
||||
item->setText({ text, entities });
|
||||
item->updateMedia(d.has_media() ? (&d.vmedia) : nullptr);
|
||||
item->addToOverview(AddToOverviewNew);
|
||||
item->addToUnreadMentions(AddToUnreadMentionsMethod::New);
|
||||
if (!wasAlready) {
|
||||
if (auto sharedMediaTypes = item->sharedMediaTypes()) {
|
||||
Auth().storage().add(Storage::SharedMediaAddNew(
|
||||
|
|
|
@ -272,11 +272,8 @@ public:
|
|||
|
||||
void jumpToDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void searchMessages(const QString &query, PeerData *inPeer);
|
||||
bool preloadOverview(PeerData *peer, MediaOverviewType type);
|
||||
void itemEdited(HistoryItem *item);
|
||||
|
||||
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
||||
|
||||
void checkLastUpdate(bool afterSleep);
|
||||
|
||||
void insertCheckedServiceNotification(const TextWithEntities &message, const MTPMessageMedia &media, int32 date);
|
||||
|
@ -470,10 +467,6 @@ private:
|
|||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedMessages &result);
|
||||
void messagesContentsRead(const MTPmessages_AffectedMessages &result);
|
||||
void overviewLoaded(
|
||||
std::pair<not_null<History*>, MsgId> historyAndStartMsgId,
|
||||
const MTPmessages_Messages &result,
|
||||
mtpRequestId req);
|
||||
|
||||
Window::SectionSlideParams prepareShowAnimation(
|
||||
bool willHaveTopBarShadow);
|
||||
|
@ -526,9 +519,6 @@ private:
|
|||
void hideAll();
|
||||
void showAll();
|
||||
|
||||
void overviewPreloaded(PeerData *data, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
bool overviewFailed(PeerData *data, const RPCError &error, mtpRequestId req);
|
||||
|
||||
void clearCachedBackground();
|
||||
void checkCurrentFloatPlayer();
|
||||
void toggleFloatPlayer(not_null<Float*> instance);
|
||||
|
@ -645,9 +635,6 @@ private:
|
|||
base::flat_set<not_null<PeerData*>> updateNotifySettingPeers;
|
||||
SingleTimer updateNotifySettingTimer;
|
||||
|
||||
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
||||
OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
|
||||
|
||||
int32 _failDifferenceTimeout = 1; // growing timeout for getDifference calls, if it fails
|
||||
typedef QMap<ChannelData*, int32> ChannelFailDifferenceTimeout;
|
||||
ChannelFailDifferenceTimeout _channelFailDifferenceTimeout; // growing timeout for getChannelDifference calls, if it fails
|
||||
|
|
|
@ -69,7 +69,7 @@ void CoverWidget::PlayButton::paintEvent(QPaintEvent *e) {
|
|||
_layout.paint(p, st::mediaPlayerActiveFg);
|
||||
}
|
||||
|
||||
CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
||||
CoverWidget::CoverWidget(QWidget *parent) : RpWidget(parent)
|
||||
, _nameLabel(this, st::mediaPlayerName)
|
||||
, _timeLabel(this, st::mediaPlayerTime)
|
||||
, _close(this, st::mediaPlayerPanelClose)
|
||||
|
@ -123,11 +123,6 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
|||
updateRepeatTrackIcon();
|
||||
}
|
||||
});
|
||||
subscribe(instance()->playlistChangedNotifier(), [this](AudioMsgId::Type type) {
|
||||
if (type == AudioMsgId::Type::Song) {
|
||||
handlePlaylistUpdate();
|
||||
}
|
||||
});
|
||||
subscribe(instance()->updatedNotifier(), [this](const TrackState &state) {
|
||||
if (state.id.type() == AudioMsgId::Type::Song) {
|
||||
handleSongUpdate(state);
|
||||
|
@ -138,6 +133,13 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
|||
handleSongChange();
|
||||
}
|
||||
});
|
||||
|
||||
instance()->playlistChanges(
|
||||
AudioMsgId::Type::Song
|
||||
) | rpl::start_with_next([=] {
|
||||
handlePlaylistUpdate();
|
||||
}, lifetime());
|
||||
|
||||
handleSongChange();
|
||||
|
||||
handleSongUpdate(mixer()->currentState(AudioMsgId::Type::Song));
|
||||
|
@ -340,15 +342,13 @@ void CoverWidget::handleSongChange() {
|
|||
}
|
||||
|
||||
void CoverWidget::handlePlaylistUpdate() {
|
||||
auto current = instance()->current(AudioMsgId::Type::Song);
|
||||
auto playlist = instance()->playlist(AudioMsgId::Type::Song);
|
||||
auto index = playlist.indexOf(current.contextId());
|
||||
if (!current || index < 0) {
|
||||
const auto type = AudioMsgId::Type::Song;
|
||||
const auto previousEnabled = instance()->previousAvailable(type);
|
||||
const auto nextEnabled = instance()->nextAvailable(type);
|
||||
if (!previousEnabled && !nextEnabled) {
|
||||
destroyPrevNextButtons();
|
||||
} else {
|
||||
createPrevNextButtons();
|
||||
auto previousEnabled = (index > 0);
|
||||
auto nextEnabled = (index + 1 < playlist.size());
|
||||
_previousTrack->setIconOverride(previousEnabled ? nullptr : &st::mediaPlayerPanelPreviousDisabledIcon);
|
||||
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
||||
_nextTrack->setIconOverride(nextEnabled ? nullptr : &st::mediaPlayerPanelNextDisabledIcon);
|
||||
|
|
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class AudioMsgId;
|
||||
|
||||
namespace Ui {
|
||||
|
@ -39,7 +41,7 @@ namespace Player {
|
|||
class VolumeController;
|
||||
struct TrackState;
|
||||
|
||||
class CoverWidget : public TWidget, private base::Subscriber {
|
||||
class CoverWidget : public Ui::RpWidget, private base::Subscriber {
|
||||
public:
|
||||
CoverWidget(QWidget *parent);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "data/data_document.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "media/media_audio_capture.h"
|
||||
#include "observer_peer.h"
|
||||
#include "messenger.h"
|
||||
#include "auth_session.h"
|
||||
#include "calls/calls_instance.h"
|
||||
|
@ -52,15 +51,11 @@ void finish() {
|
|||
}
|
||||
|
||||
Instance::Instance()
|
||||
: _songData(AudioMsgId::Type::Song, OverviewMusicFiles)
|
||||
, _voiceData(AudioMsgId::Type::Voice, OverviewRoundVoiceFiles) {
|
||||
: _songData(AudioMsgId::Type::Song, SharedMediaType::MusicFile)
|
||||
, _voiceData(AudioMsgId::Type::Voice, SharedMediaType::RoundVoiceFile) {
|
||||
subscribe(Media::Player::Updated(), [this](const AudioMsgId &audioId) {
|
||||
handleSongUpdate(audioId);
|
||||
});
|
||||
auto observeEvents = Notify::PeerUpdate::Flag::SharedMediaChanged;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
|
||||
notifyPeerUpdated(update);
|
||||
}));
|
||||
subscribe(Global::RefSelfChanged(), [this] {
|
||||
if (!App::self()) {
|
||||
handleLogout();
|
||||
|
@ -95,27 +90,6 @@ AudioMsgId::Type Instance::getActiveType() const {
|
|||
return AudioMsgId::Type::Song;
|
||||
}
|
||||
|
||||
void Instance::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||
checkPeerUpdate(AudioMsgId::Type::Song, update);
|
||||
checkPeerUpdate(AudioMsgId::Type::Voice, update);
|
||||
}
|
||||
|
||||
void Instance::checkPeerUpdate(AudioMsgId::Type type, const Notify::PeerUpdate &update) {
|
||||
if (auto data = getData(type)) {
|
||||
if (!data->history) {
|
||||
return;
|
||||
}
|
||||
if (!(update.mediaTypesMask & (1 << data->overview))) {
|
||||
return;
|
||||
}
|
||||
if (update.peer != data->history->peer && (!data->migrated || update.peer != data->migrated->peer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
rebuildPlaylist(data);
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::handleSongUpdate(const AudioMsgId &audioId) {
|
||||
emitUpdate(audioId.type(), [&audioId](const AudioMsgId &playing) {
|
||||
return (audioId == playing);
|
||||
|
@ -146,53 +120,50 @@ void Instance::setCurrent(const AudioMsgId &audioId) {
|
|||
}
|
||||
}
|
||||
|
||||
void Instance::rebuildPlaylist(Data *data) {
|
||||
Expects(data != nullptr);
|
||||
|
||||
data->playlist.clear();
|
||||
if (data->history && data->history->loadedAtBottom()) {
|
||||
auto &historyOverview = data->history->overview(data->overview);
|
||||
if (data->migrated && data->migrated->loadedAtBottom() && data->history->loadedAtTop()) {
|
||||
auto &migratedOverview = data->migrated->overview(data->overview);
|
||||
data->playlist.reserve(migratedOverview.size() + historyOverview.size());
|
||||
for_const (auto msgId, migratedOverview) {
|
||||
data->playlist.push_back(FullMsgId(data->migrated->channelId(), msgId));
|
||||
}
|
||||
} else {
|
||||
data->playlist.reserve(historyOverview.size());
|
||||
}
|
||||
for_const (auto msgId, historyOverview) {
|
||||
data->playlist.push_back(FullMsgId(data->history->channelId(), msgId));
|
||||
}
|
||||
}
|
||||
_playlistChangedNotifier.notify(data->type, true);
|
||||
void Instance::rebuildPlaylist(not_null<Data*> data) {
|
||||
// #TODO playlist
|
||||
}
|
||||
|
||||
bool Instance::moveInPlaylist(Data *data, int delta, bool autonext) {
|
||||
Expects(data != nullptr);
|
||||
bool Instance::moveInPlaylist(
|
||||
not_null<Data*> data,
|
||||
int delta,
|
||||
bool autonext) {
|
||||
//auto index = data->playlist.indexOf(data->current.contextId());
|
||||
//auto newIndex = index + delta;
|
||||
//if (!data->current || index < 0 || newIndex < 0 || newIndex >= data->playlist.size()) {
|
||||
// rebuildPlaylist(data);
|
||||
// return false;
|
||||
//}
|
||||
|
||||
auto index = data->playlist.indexOf(data->current.contextId());
|
||||
auto newIndex = index + delta;
|
||||
if (!data->current || index < 0 || newIndex < 0 || newIndex >= data->playlist.size()) {
|
||||
rebuildPlaylist(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto msgId = data->playlist[newIndex];
|
||||
if (auto item = App::histItemById(msgId)) {
|
||||
if (auto media = item->getMedia()) {
|
||||
if (auto document = media->getDocument()) {
|
||||
if (autonext) {
|
||||
_switchToNextNotifier.notify({ data->current, msgId });
|
||||
}
|
||||
DocumentOpenClickHandler::doOpen(media->getDocument(), item, ActionOnLoadPlayInline);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//auto msgId = data->playlist[newIndex];
|
||||
//if (auto item = App::histItemById(msgId)) {
|
||||
// if (auto media = item->getMedia()) {
|
||||
// if (auto document = media->getDocument()) {
|
||||
// if (autonext) {
|
||||
// _switchToNextNotifier.notify({ data->current, msgId });
|
||||
// }
|
||||
// DocumentOpenClickHandler::doOpen(media->getDocument(), item, ActionOnLoadPlayInline);
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Instance::previousAvailable(AudioMsgId::Type type) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Instance::nextAvailable(AudioMsgId::Type type) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
rpl::producer<> Media::Player::Instance::playlistChanges(
|
||||
AudioMsgId::Type type) const {
|
||||
return rpl::never<>();
|
||||
}
|
||||
|
||||
Instance *instance() {
|
||||
Expects(SingleInstance != nullptr);
|
||||
return SingleInstance;
|
||||
|
@ -344,34 +315,36 @@ void Instance::emitUpdate(AudioMsgId::Type type, CheckCallback check) {
|
|||
}
|
||||
}
|
||||
|
||||
void Instance::preloadNext(Data *data) {
|
||||
Expects(data != nullptr);
|
||||
|
||||
void Instance::preloadNext(not_null<Data*> data) {
|
||||
if (!data->current) {
|
||||
return;
|
||||
}
|
||||
auto index = data->playlist.indexOf(data->current.contextId());
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
auto nextIndex = index + 1;
|
||||
if (nextIndex >= data->playlist.size()) {
|
||||
return;
|
||||
}
|
||||
if (auto item = App::histItemById(data->playlist[nextIndex])) {
|
||||
if (auto media = item->getMedia()) {
|
||||
if (auto document = media->getDocument()) {
|
||||
if (!document->loaded(DocumentData::FilePathResolveSaveFromDataSilent)) {
|
||||
DocumentOpenClickHandler::doOpen(document, nullptr, ActionOnLoadNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//auto index = data->playlist.indexOf(data->current.contextId());
|
||||
//if (index < 0) {
|
||||
// return;
|
||||
//}
|
||||
//auto nextIndex = index + 1;
|
||||
//if (nextIndex >= data->playlist.size()) {
|
||||
// return;
|
||||
//}
|
||||
//if (auto item = App::histItemById(data->playlist[nextIndex])) {
|
||||
// if (auto media = item->getMedia()) {
|
||||
// if (auto document = media->getDocument()) {
|
||||
// if (!document->loaded(DocumentData::FilePathResolveSaveFromDataSilent)) {
|
||||
// DocumentOpenClickHandler::doOpen(document, nullptr, ActionOnLoadNone);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void Instance::handleLogout() {
|
||||
*getData(AudioMsgId::Type::Voice) = Data(AudioMsgId::Type::Voice, OverviewRoundVoiceFiles);
|
||||
*getData(AudioMsgId::Type::Song) = Data(AudioMsgId::Type::Song, OverviewMusicFiles);
|
||||
const auto reset = [&](AudioMsgId::Type type) {
|
||||
const auto data = getData(type);
|
||||
*data = Data(type, data->overview);
|
||||
};
|
||||
reset(AudioMsgId::Type::Voice);
|
||||
reset(AudioMsgId::Type::Song);
|
||||
_usePanelPlayer.notify(false, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
} // namespace Notify
|
||||
#include "data/data_shared_media.h"
|
||||
|
||||
class AudioMsgId;
|
||||
|
||||
namespace Media {
|
||||
|
@ -98,12 +97,8 @@ public:
|
|||
void startSeeking(AudioMsgId::Type type);
|
||||
void stopSeeking(AudioMsgId::Type type);
|
||||
|
||||
QList<FullMsgId> playlist(AudioMsgId::Type type) const {
|
||||
if (auto data = getData(type)) {
|
||||
return data->playlist;
|
||||
}
|
||||
return QList<FullMsgId>();
|
||||
}
|
||||
bool nextAvailable(AudioMsgId::Type type) const;
|
||||
bool previousAvailable(AudioMsgId::Type type) const;
|
||||
|
||||
struct Switch {
|
||||
AudioMsgId from;
|
||||
|
@ -128,9 +123,6 @@ public:
|
|||
base::Observable<AudioMsgId::Type> &tracksFinishedNotifier() {
|
||||
return _tracksFinishedNotifier;
|
||||
}
|
||||
base::Observable<AudioMsgId::Type> &playlistChangedNotifier() {
|
||||
return _playlistChangedNotifier;
|
||||
}
|
||||
base::Observable<AudioMsgId::Type> &trackChangedNotifier() {
|
||||
return _trackChangedNotifier;
|
||||
}
|
||||
|
@ -138,6 +130,8 @@ public:
|
|||
return _repeatChangedNotifier;
|
||||
}
|
||||
|
||||
rpl::producer<> playlistChanges(AudioMsgId::Type type) const;
|
||||
|
||||
void documentLoadProgress(DocumentData *document);
|
||||
|
||||
void clear();
|
||||
|
@ -146,30 +140,31 @@ private:
|
|||
Instance();
|
||||
friend void start();
|
||||
|
||||
using SharedMediaType = Storage::SharedMediaType;
|
||||
struct Data {
|
||||
Data(AudioMsgId::Type type, MediaOverviewType overview) : type(type), overview(overview) {
|
||||
Data(AudioMsgId::Type type, SharedMediaType overview)
|
||||
: type(type)
|
||||
, overview(overview) {
|
||||
}
|
||||
|
||||
AudioMsgId::Type type;
|
||||
MediaOverviewType overview;
|
||||
Storage::SharedMediaType overview;
|
||||
AudioMsgId current;
|
||||
AudioMsgId seeking;
|
||||
base::optional<SparseIdsMergedSlice> playlistSlice;
|
||||
History *history = nullptr;
|
||||
History *migrated = nullptr;
|
||||
bool repeatEnabled = false;
|
||||
QList<FullMsgId> playlist;
|
||||
bool isPlaying = false;
|
||||
};
|
||||
|
||||
// Observed notifications.
|
||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||
void handleSongUpdate(const AudioMsgId &audioId);
|
||||
|
||||
void checkPeerUpdate(AudioMsgId::Type type, const Notify::PeerUpdate &update);
|
||||
void setCurrent(const AudioMsgId &audioId);
|
||||
void rebuildPlaylist(Data *data);
|
||||
bool moveInPlaylist(Data *data, int delta, bool autonext);
|
||||
void preloadNext(Data *data);
|
||||
void rebuildPlaylist(not_null<Data*> data);
|
||||
bool moveInPlaylist(not_null<Data*> data, int delta, bool autonext);
|
||||
void preloadNext(not_null<Data*> data);
|
||||
void handleLogout();
|
||||
|
||||
template <typename CheckCallback>
|
||||
|
@ -202,7 +197,6 @@ private:
|
|||
base::Observable<bool> _playerWidgetOver;
|
||||
base::Observable<TrackState> _updatedNotifier;
|
||||
base::Observable<AudioMsgId::Type> _tracksFinishedNotifier;
|
||||
base::Observable<AudioMsgId::Type> _playlistChangedNotifier;
|
||||
base::Observable<AudioMsgId::Type> _trackChangedNotifier;
|
||||
base::Observable<AudioMsgId::Type> _repeatChangedNotifier;
|
||||
|
||||
|
|
|
@ -1,246 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "media/player/media_player_list.h"
|
||||
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "overview/overview_layout.h"
|
||||
#include "styles/style_media_player.h"
|
||||
#include "history/history_media.h"
|
||||
#include "auth_session.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
ListWidget::ListWidget(QWidget *parent) : RpWidget(parent) {
|
||||
setMouseTracking(true);
|
||||
playlistUpdated();
|
||||
subscribe(
|
||||
instance()->playlistChangedNotifier(),
|
||||
[this](AudioMsgId::Type type) { playlistUpdated(); });
|
||||
Auth().data().itemRemoved()
|
||||
| rpl::start_with_next(
|
||||
[this](auto item) { itemRemoved(item); },
|
||||
lifetime());
|
||||
Auth().data().itemRepaintRequest()
|
||||
| rpl::start_with_next(
|
||||
[this](auto item) { repaintItem(item); },
|
||||
lifetime());
|
||||
}
|
||||
|
||||
ListWidget::~ListWidget() {
|
||||
auto layouts = base::take(_layouts);
|
||||
for_const (auto layout, layouts) {
|
||||
delete layout;
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto clip = e->rect();
|
||||
Overview::Layout::PaintContext context(getms(), false);
|
||||
int y = marginTop();
|
||||
for_const (auto layout, _list) {
|
||||
auto layoutHeight = layout->height();
|
||||
if (y + layoutHeight > clip.y()) {
|
||||
if (y >= clip.y() + clip.height()) break;
|
||||
|
||||
p.translate(0, y);
|
||||
layout->paint(p, clip.translated(0, -y), TextSelection(), &context);
|
||||
p.translate(0, -y);
|
||||
}
|
||||
y += layoutHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::mousePressEvent(QMouseEvent *e) {
|
||||
if (e->button() != Qt::LeftButton) return;
|
||||
|
||||
ClickHandler::pressed();
|
||||
}
|
||||
|
||||
void ListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
ClickHandlerPtr activated = ClickHandler::unpressed();
|
||||
if (!ClickHandler::getActive() && _cursor != style::cur_default) {
|
||||
_cursor = style::cur_default;
|
||||
setCursor(_cursor);
|
||||
}
|
||||
if (activated) {
|
||||
App::activateClickHandler(activated, e->button());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||
auto m = e->pos();
|
||||
|
||||
ClickHandlerPtr lnk;
|
||||
ClickHandlerHost *lnkhost = nullptr;
|
||||
HistoryItem *item = nullptr;
|
||||
HistoryCursorState cursorState = HistoryDefaultCursorState;
|
||||
|
||||
int y = marginTop();
|
||||
for_const (auto layout, _list) {
|
||||
auto layoutHeight = layout->height();
|
||||
if (y + layoutHeight > m.y()) {
|
||||
if (y <= m.y()) {
|
||||
if (auto media = layout->toMediaItem()) {
|
||||
item = media->getItem();
|
||||
auto result = media->getState(m - QPoint(0, y), HistoryStateRequest());
|
||||
lnk = result.link;
|
||||
cursorState = result.cursor;
|
||||
lnkhost = media;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
y += layoutHeight;
|
||||
}
|
||||
|
||||
auto cur = lnk ? style::cur_pointer : style::cur_default;
|
||||
if (cur != _cursor) {
|
||||
setCursor(_cursor = cur);
|
||||
}
|
||||
|
||||
auto lnkChanged = ClickHandler::setActive(lnk, lnkhost);
|
||||
if (item != App::mousedItem()) {
|
||||
repaintItem(App::mousedItem());
|
||||
App::mousedItem(item);
|
||||
repaintItem(App::mousedItem());
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::repaintItem(const HistoryItem *item) {
|
||||
if (!item) return;
|
||||
|
||||
auto layoutIt = _layouts.constFind(item->fullId());
|
||||
if (layoutIt != _layouts.cend()) {
|
||||
int y = 0;
|
||||
for_const (auto layout, _list) {
|
||||
auto layoutHeight = layout->height();
|
||||
if (layout->getItem() == item) {
|
||||
update(0, y, width(), layoutHeight);
|
||||
break;
|
||||
}
|
||||
y += layoutHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::itemRemoved(not_null<const HistoryItem *> item) {
|
||||
auto layoutIt = _layouts.find(item->fullId());
|
||||
if (layoutIt != _layouts.cend()) {
|
||||
auto layout = layoutIt.value();
|
||||
_layouts.erase(layoutIt);
|
||||
|
||||
for (int i = 0, count = _list.size(); i != count; ++i) {
|
||||
if (_list[i] == layout) {
|
||||
_list.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete layout;
|
||||
}
|
||||
}
|
||||
|
||||
QRect ListWidget::getCurrentTrackGeometry() const {
|
||||
auto top = marginTop();
|
||||
auto current = instance()->current(AudioMsgId::Type::Song);
|
||||
auto fullMsgId = current.contextId();
|
||||
for_const (auto layout, _list) {
|
||||
auto layoutHeight = layout->height();
|
||||
if (layout->getItem()->fullId() == fullMsgId) {
|
||||
return QRect(0, top, width(), layoutHeight);
|
||||
}
|
||||
top += layoutHeight;
|
||||
}
|
||||
return QRect(0, height(), width(), 0);
|
||||
}
|
||||
|
||||
int ListWidget::resizeGetHeight(int newWidth) {
|
||||
auto result = 0;
|
||||
for_const (auto layout, _list) {
|
||||
result += layout->resizeGetHeight(newWidth);
|
||||
}
|
||||
return (result > 0) ? (marginTop() + result) : 0;
|
||||
}
|
||||
|
||||
int ListWidget::marginTop() const {
|
||||
return st::mediaPlayerListMarginTop;
|
||||
}
|
||||
|
||||
void ListWidget::playlistUpdated() {
|
||||
auto newHeight = 0;
|
||||
|
||||
auto playlist = instance()->playlist(AudioMsgId::Type::Song);
|
||||
auto playlistSize = playlist.size();
|
||||
auto existingSize = _list.size();
|
||||
if (playlistSize > existingSize) {
|
||||
_list.reserve(playlistSize);
|
||||
}
|
||||
|
||||
int existingIndex = 0;
|
||||
for (int i = 0; i != playlistSize; ++i) {
|
||||
auto &msgId = playlist[i];
|
||||
if (existingIndex < existingSize && _list[existingIndex]->getItem()->fullId() == msgId) {
|
||||
newHeight += _list[existingIndex]->height();
|
||||
++existingIndex;
|
||||
continue;
|
||||
}
|
||||
auto layoutIt = _layouts.constFind(msgId);
|
||||
if (layoutIt == _layouts.cend()) {
|
||||
if (auto item = App::histItemById(msgId)) {
|
||||
if (auto media = item->getMedia()) {
|
||||
if (media->type() == MediaTypeMusicFile) {
|
||||
layoutIt = _layouts.insert(msgId, new Overview::Layout::Document(item, media->getDocument(), st::mediaPlayerFileLayout));
|
||||
layoutIt.value()->initDimensions();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layoutIt != _layouts.cend()) {
|
||||
auto layout = layoutIt.value();
|
||||
if (existingIndex < existingSize) {
|
||||
_list[existingIndex] = layout;
|
||||
} else {
|
||||
_list.push_back(layout);
|
||||
++existingSize;
|
||||
}
|
||||
++existingIndex;
|
||||
newHeight += layout->resizeGetHeight(width());
|
||||
}
|
||||
}
|
||||
while (existingIndex < existingSize) {
|
||||
_list.pop_back();
|
||||
--existingSize;
|
||||
}
|
||||
|
||||
if (newHeight > 0) {
|
||||
newHeight += marginTop();
|
||||
}
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
emit heightUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Player
|
||||
} // namespace Media
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Overview {
|
||||
namespace Layout {
|
||||
class Document;
|
||||
} // namespace Layout
|
||||
} // namespace Overview
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
class ListWidget : public Ui::RpWidget, private base::Subscriber {
|
||||
public:
|
||||
ListWidget(QWidget *parent);
|
||||
|
||||
QRect getCurrentTrackGeometry() const;
|
||||
|
||||
~ListWidget();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
int marginTop() const;
|
||||
void repaintItem(const HistoryItem *item);
|
||||
void playlistUpdated();
|
||||
|
||||
using Layout = Overview::Layout::Document;
|
||||
using Layouts = QMap<FullMsgId, Layout*>;
|
||||
Layouts _layouts;
|
||||
|
||||
using List = QList<Layout*>;
|
||||
List _list;
|
||||
|
||||
style::cursor _cursor = style::cur_default;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Clip
|
||||
} // namespace Media
|
|
@ -21,7 +21,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "media/player/media_player_panel.h"
|
||||
|
||||
#include "media/player/media_player_cover.h"
|
||||
#include "media/player/media_player_list.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
@ -104,11 +103,12 @@ int Panel::bestPositionFor(int left) const {
|
|||
}
|
||||
|
||||
void Panel::scrollPlaylistToCurrentTrack() {
|
||||
if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||
auto rect = list->getCurrentTrackGeometry();
|
||||
auto top = _scroll->scrollTop(), bottom = top + _scroll->height();
|
||||
_scroll->scrollToY(rect.y());
|
||||
}
|
||||
// #TODO playlist
|
||||
//if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||
// auto rect = list->getCurrentTrackGeometry();
|
||||
// auto top = _scroll->scrollTop(), bottom = top + _scroll->height();
|
||||
// _scroll->scrollToY(rect.y());
|
||||
//}
|
||||
}
|
||||
|
||||
void Panel::onScroll() {
|
||||
|
@ -219,9 +219,10 @@ void Panel::ensureCreated() {
|
|||
|
||||
_scrollShadow.create(this, st::mediaPlayerScrollShadow, RectPart::Bottom);
|
||||
}
|
||||
auto list = object_ptr<ListWidget>(this);
|
||||
connect(list, SIGNAL(heightUpdated()), this, SLOT(onListHeightUpdated()));
|
||||
_scroll->setOwnedWidget(std::move(list));
|
||||
// #TODO playlist
|
||||
//auto list = object_ptr<ListWidget>(this);
|
||||
//connect(list, SIGNAL(heightUpdated()), this, SLOT(onListHeightUpdated()));
|
||||
//_scroll->setOwnedWidget(std::move(list));
|
||||
|
||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||
if (auto window = App::wnd()) {
|
||||
|
@ -238,7 +239,8 @@ void Panel::performDestroy() {
|
|||
if (!_scroll->widget()) return;
|
||||
|
||||
_cover.destroy();
|
||||
_scroll->takeWidget<ListWidget>().destroyDelayed();
|
||||
// #TODO playlist
|
||||
//_scroll->takeWidget<ListWidget>().destroyDelayed();
|
||||
|
||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||
if (auto window = App::wnd()) {
|
||||
|
|
|
@ -29,7 +29,6 @@ namespace Media {
|
|||
namespace Player {
|
||||
|
||||
class CoverWidget;
|
||||
class ListWidget;
|
||||
|
||||
class Panel : public TWidget {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -144,11 +144,6 @@ Widget::Widget(QWidget *parent) : RpWidget(parent)
|
|||
updateRepeatTrackIcon();
|
||||
}
|
||||
});
|
||||
subscribe(instance()->playlistChangedNotifier(), [this](AudioMsgId::Type type) {
|
||||
if (type == _type) {
|
||||
handlePlaylistUpdate();
|
||||
}
|
||||
});
|
||||
subscribe(instance()->updatedNotifier(), [this](const TrackState &state) {
|
||||
handleSongUpdate(state);
|
||||
});
|
||||
|
@ -395,6 +390,11 @@ void Widget::setType(AudioMsgId::Type type) {
|
|||
handleSongChange();
|
||||
handleSongUpdate(mixer()->currentState(_type));
|
||||
updateOverLabelsState(_labelsOver);
|
||||
_playlistChangesLifetime = instance()->playlistChanges(
|
||||
_type
|
||||
) | rpl::start_with_next([=] {
|
||||
handlePlaylistUpdate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,15 +519,12 @@ void Widget::handleSongChange() {
|
|||
}
|
||||
|
||||
void Widget::handlePlaylistUpdate() {
|
||||
auto current = instance()->current(_type);
|
||||
auto playlist = instance()->playlist(_type);
|
||||
auto index = playlist.indexOf(current.contextId());
|
||||
if (!current || index < 0) {
|
||||
const auto previousEnabled = instance()->previousAvailable(_type);
|
||||
const auto nextEnabled = instance()->nextAvailable(_type);
|
||||
if (!previousEnabled && !nextEnabled) {
|
||||
destroyPrevNextButtons();
|
||||
} else {
|
||||
createPrevNextButtons();
|
||||
auto previousEnabled = (index > 0);
|
||||
auto nextEnabled = (index + 1 < playlist.size());
|
||||
_previousTrack->setIconOverride(previousEnabled ? nullptr : &st::mediaPlayerPreviousDisabledIcon);
|
||||
_previousTrack->setRippleColorOverride(previousEnabled ? nullptr : &st::mediaPlayerBg);
|
||||
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
||||
|
|
|
@ -121,6 +121,8 @@ private:
|
|||
object_ptr<Ui::FilledSlider> _playbackSlider;
|
||||
std::unique_ptr<Clip::Playback> _playback;
|
||||
|
||||
rpl::lifetime _playlistChangesLifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Clip
|
||||
|
|
|
@ -49,9 +49,6 @@ void mergePeerUpdate(PeerUpdate &mergeTo, const PeerUpdate &mergeFrom) {
|
|||
mergeTo.oldNameFirstChars = mergeFrom.oldNameFirstChars;
|
||||
}
|
||||
}
|
||||
if (mergeFrom.flags & PeerUpdate::Flag::SharedMediaChanged) {
|
||||
mergeTo.mediaTypesMask |= mergeFrom.mediaTypesMask;
|
||||
}
|
||||
mergeTo.flags |= mergeFrom.flags;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ struct PeerUpdate {
|
|||
PhotoChanged = (1 << 2),
|
||||
AboutChanged = (1 << 3),
|
||||
NotificationsEnabled = (1 << 4),
|
||||
SharedMediaChanged = (1 << 5),
|
||||
MigrationChanged = (1 << 6),
|
||||
PinnedChanged = (1 << 7),
|
||||
RestrictionReasonChanged = (1 << 8),
|
||||
|
@ -87,9 +86,6 @@ struct PeerUpdate {
|
|||
// NameChanged data
|
||||
PeerData::NameFirstChars oldNameFirstChars;
|
||||
|
||||
// SharedMediaChanged data
|
||||
int32 mediaTypesMask = 0;
|
||||
|
||||
};
|
||||
|
||||
void peerUpdatedDelayed(const PeerUpdate &update);
|
||||
|
@ -100,13 +96,6 @@ inline void peerUpdatedDelayed(PeerData *peer, PeerUpdate::Flags events) {
|
|||
}
|
||||
void peerUpdatedSendDelayed();
|
||||
|
||||
inline void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
PeerUpdate update(peer);
|
||||
update.flags |= PeerUpdate::Flag::SharedMediaChanged;
|
||||
update.mediaTypesMask |= (1 << type);
|
||||
peerUpdatedDelayed(update);
|
||||
}
|
||||
|
||||
class PeerUpdatedHandler {
|
||||
public:
|
||||
template <typename Lambda>
|
||||
|
|
|
@ -317,8 +317,6 @@
|
|||
<(src_loc)/media/player/media_player_float.h
|
||||
<(src_loc)/media/player/media_player_instance.cpp
|
||||
<(src_loc)/media/player/media_player_instance.h
|
||||
<(src_loc)/media/player/media_player_list.cpp
|
||||
<(src_loc)/media/player/media_player_list.h
|
||||
<(src_loc)/media/player/media_player_panel.cpp
|
||||
<(src_loc)/media/player/media_player_panel.h
|
||||
<(src_loc)/media/player/media_player_volume_controller.cpp
|
||||
|
|
Loading…
Reference in New Issue