/* 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 */ #include "data/data_changes.h" #include "main/main_session.h" namespace Data { template void Changes::Manager::updated( not_null data, Flags flags, bool dropScheduled) { sendRealtimeNotifications(data, flags); if (dropScheduled) { const auto i = _updates.find(data); if (i != _updates.end()) { flags |= i->second; _updates.erase(i); } _stream.fire({ data, flags }); } else { _updates[data] |= flags; } } template void Changes::Manager::sendRealtimeNotifications( not_null data, Flags flags) { auto clearRealtime = false; for (auto i = 0; i != kCount; ++i) { const auto flag = static_cast(1U << i); if (flags & flag) { _realtimeStreams[i].fire({ data, flags }); } } } template rpl::producer Changes::Manager::updates( Flags flags) const { return _stream.events( ) | rpl::filter([=](const UpdateType &update) { return (update.flags & flags); }); } template rpl::producer Changes::Manager::updates( not_null data, Flags flags) const { return _stream.events( ) | rpl::filter([=](const UpdateType &update) { const auto [updateData, updateFlags] = update; return (updateData == data) && (updateFlags & flags); }); } template auto Changes::Manager::realtimeUpdates(Flag flag) const -> rpl::producer { return _realtimeStreams[details::CountBit(flag)].events(); } template rpl::producer Changes::Manager::flagsValue( not_null data, Flags flags) const { return rpl::single( UpdateType{ data, flags } ) | rpl::then(updates(data, flags)); } template void Changes::Manager::sendNotifications() { for (const auto [data, flags] : base::take(_updates)) { _stream.fire({ data, flags }); } } Changes::Changes(not_null session) : _session(session) { } Main::Session &Changes::session() const { return *_session; } void Changes::nameUpdated( not_null peer, base::flat_set oldFirstLetters) { _nameStream.fire({ peer, std::move(oldFirstLetters) }); } rpl::producer Changes::realtimeNameUpdates() const { return _nameStream.events(); } rpl::producer Changes::realtimeNameUpdates( not_null peer) const { return _nameStream.events() | rpl::filter([=](const NameUpdate &update) { return (update.peer == peer); }); } void Changes::peerUpdated(not_null peer, PeerUpdate::Flags flags) { _peerChanges.updated(peer, flags); scheduleNotifications(); } rpl::producer Changes::peerUpdates( PeerUpdate::Flags flags) const { return _peerChanges.updates(flags); } rpl::producer Changes::peerUpdates( not_null peer, PeerUpdate::Flags flags) const { return _peerChanges.updates(peer, flags); } rpl::producer Changes::peerFlagsValue( not_null peer, PeerUpdate::Flags flags) const { return _peerChanges.flagsValue(peer, flags); } rpl::producer Changes::realtimePeerUpdates( PeerUpdate::Flag flag) const { return _peerChanges.realtimeUpdates(flag); } void Changes::historyUpdated( not_null history, HistoryUpdate::Flags flags) { _historyChanges.updated(history, flags); scheduleNotifications(); } rpl::producer Changes::historyUpdates( HistoryUpdate::Flags flags) const { return _historyChanges.updates(flags); } rpl::producer Changes::historyUpdates( not_null history, HistoryUpdate::Flags flags) const { return _historyChanges.updates(history, flags); } rpl::producer Changes::historyFlagsValue( not_null history, HistoryUpdate::Flags flags) const { return _historyChanges.flagsValue(history, flags); } rpl::producer Changes::realtimeHistoryUpdates( HistoryUpdate::Flag flag) const { return _historyChanges.realtimeUpdates(flag); } void Changes::messageUpdated( not_null item, MessageUpdate::Flags flags) { const auto drop = (flags & MessageUpdate::Flag::Destroyed); _messageChanges.updated(item, flags, drop); if (!drop) { scheduleNotifications(); } } rpl::producer Changes::messageUpdates( MessageUpdate::Flags flags) const { return _messageChanges.updates(flags); } rpl::producer Changes::messageUpdates( not_null item, MessageUpdate::Flags flags) const { return _messageChanges.updates(item, flags); } rpl::producer Changes::messageFlagsValue( not_null item, MessageUpdate::Flags flags) const { return _messageChanges.flagsValue(item, flags); } rpl::producer Changes::realtimeMessageUpdates( MessageUpdate::Flag flag) const { return _messageChanges.realtimeUpdates(flag); } void Changes::entryUpdated( not_null entry, EntryUpdate::Flags flags) { _entryChanges.updated(entry, flags); scheduleNotifications(); } rpl::producer Changes::entryUpdates( EntryUpdate::Flags flags) const { return _entryChanges.updates(flags); } rpl::producer Changes::entryUpdates( not_null entry, EntryUpdate::Flags flags) const { return _entryChanges.updates(entry, flags); } rpl::producer Changes::entryFlagsValue( not_null entry, EntryUpdate::Flags flags) const { return _entryChanges.flagsValue(entry, flags); } rpl::producer Changes::realtimeEntryUpdates( EntryUpdate::Flag flag) const { return _entryChanges.realtimeUpdates(flag); } void Changes::scheduleNotifications() { if (!_notify) { _notify = true; crl::on_main(&session(), [=] { sendNotifications(); }); } } void Changes::sendNotifications() { if (!_notify) { return; } _notify = false; _peerChanges.sendNotifications(); _historyChanges.sendNotifications(); _messageChanges.sendNotifications(); _entryChanges.sendNotifications(); } } // namespace Data