mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Update API scheme to layer 148, start forums.
This commit is contained in:
parent
87b228b256
commit
c88140e256
25 changed files with 349 additions and 40 deletions
Telegram
CMakeLists.txt
Resources/tl
SourceFiles
boxes
data
data_channel.cppdata_channel.hdata_chat.hdata_forum.cppdata_forum.hdata_peer.cppdata_peer.hdata_session.cppdata_user.h
dialogs
export
history
window
|
@ -467,6 +467,8 @@ PRIVATE
|
|||
data/data_emoji_statuses.h
|
||||
data/data_folder.cpp
|
||||
data/data_folder.h
|
||||
data/data_forum.cpp
|
||||
data/data_forum.h
|
||||
data/data_file_click_handler.cpp
|
||||
data/data_file_click_handler.h
|
||||
data/data_file_origin.cpp
|
||||
|
|
|
@ -125,7 +125,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
|||
chatEmpty#29562865 id:long = Chat;
|
||||
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||
channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
|
@ -142,7 +142,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
|||
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
|
||||
message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true topic_start:flags.27?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
|
@ -192,6 +192,7 @@ messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
|||
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
||||
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
||||
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
|
||||
messageActionTopicCreate#4619708d title:string = MessageAction;
|
||||
|
||||
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
|
@ -591,7 +592,7 @@ inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
|||
|
||||
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
|
||||
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
||||
|
||||
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
||||
|
@ -770,7 +771,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
|
|||
|
||||
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
|
||||
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
|
||||
stickerSetFullCovered#1aed5ee5 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = StickerSetCovered;
|
||||
stickerSetFullCovered#40d13c0e set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = StickerSetCovered;
|
||||
|
||||
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
|
||||
|
||||
|
@ -1248,7 +1249,7 @@ messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> use
|
|||
|
||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||
|
||||
messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
||||
messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
||||
|
||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||
|
||||
|
@ -1448,6 +1449,12 @@ sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer
|
|||
messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
|
||||
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;
|
||||
|
||||
stickerKeyword#fcfeb29c document_id:long keyword:Vector<string> = StickerKeyword;
|
||||
|
||||
forumTopic#4a0005d9 flags:# pinned:flags.2?true id:int date:int title:string top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int = ForumTopic;
|
||||
|
||||
messages.forumTopics#ed93d3e flags:# count:int topics:Vector<ForumTopic> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int next_date:flags.0?int = messages.ForumTopics;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
|
@ -1846,6 +1853,9 @@ channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers;
|
|||
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
|
||||
channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.createForumTopic#22cf4868 flags:# no_webpage:flags.3?true channel:InputChannel title:string media:flags.0?InputMedia message:string random_id:long entities:flags.1?Vector<MessageEntity> send_as:flags.2?InputPeer = Updates;
|
||||
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
|
@ -1924,4 +1934,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
|||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||
|
||||
// LAYER 146
|
||||
// LAYER 148
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
Group,
|
||||
Channel,
|
||||
Megagroup,
|
||||
Forum,
|
||||
};
|
||||
GroupInfoBox(
|
||||
QWidget*,
|
||||
|
|
|
@ -266,6 +266,7 @@ private:
|
|||
std::optional<QString> title;
|
||||
std::optional<QString> description;
|
||||
std::optional<bool> hiddenPreHistory;
|
||||
std::optional<bool> forum;
|
||||
std::optional<bool> signatures;
|
||||
std::optional<bool> noForwards;
|
||||
std::optional<bool> joinToWrite;
|
||||
|
@ -289,6 +290,7 @@ private:
|
|||
void fillPrivacyTypeButton();
|
||||
void fillLinkedChatButton();
|
||||
//void fillInviteLinkButton();
|
||||
void fillForumButton();
|
||||
void fillSignaturesButton();
|
||||
void fillHistoryVisibilityButton();
|
||||
void fillManageSection();
|
||||
|
@ -305,6 +307,7 @@ private:
|
|||
[[nodiscard]] bool validateTitle(Saving &to) const;
|
||||
[[nodiscard]] bool validateDescription(Saving &to) const;
|
||||
[[nodiscard]] bool validateHistoryVisibility(Saving &to) const;
|
||||
[[nodiscard]] bool validateForum(Saving &to) const;
|
||||
[[nodiscard]] bool validateSignatures(Saving &to) const;
|
||||
[[nodiscard]] bool validateForwards(Saving &to) const;
|
||||
[[nodiscard]] bool validateJoinToWrite(Saving &to) const;
|
||||
|
@ -316,6 +319,7 @@ private:
|
|||
void saveTitle();
|
||||
void saveDescription();
|
||||
void saveHistoryVisibility();
|
||||
void saveForum();
|
||||
void saveSignatures();
|
||||
void saveForwards();
|
||||
void saveJoinToWrite();
|
||||
|
@ -339,6 +343,7 @@ private:
|
|||
bool _channelHasLocationOriginalValue = false;
|
||||
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
|
||||
std::optional<EditPeerTypeData> _typeDataSavedValue;
|
||||
std::optional<bool> _forumSavedValue;
|
||||
std::optional<bool> _signaturesSavedValue;
|
||||
|
||||
const not_null<Window::SessionNavigation*> _navigation;
|
||||
|
@ -800,6 +805,27 @@ void Controller::fillLinkedChatButton() {
|
|||
// buttonCallback);
|
||||
//}
|
||||
|
||||
void Controller::fillForumButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddButtonWithText(
|
||||
_controls.buttonsLayout,
|
||||
rpl::single(u"Forum"_q), // #TODO forum
|
||||
rpl::single(QString()),
|
||||
[] {},
|
||||
{ &st::settingsIconGroup, Settings::kIconPurple }
|
||||
)->toggleOn(rpl::single(channel->isForum())
|
||||
)->toggledValue(
|
||||
) | rpl::start_with_next([=](bool toggled) {
|
||||
_forumSavedValue = toggled;
|
||||
}, _controls.buttonsLayout->lifetime());
|
||||
}
|
||||
|
||||
void Controller::fillSignaturesButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
|
@ -907,6 +933,9 @@ void Controller::fillManageSection() {
|
|||
? channel->canEditPreHistoryHidden()
|
||||
: chat->canEditPreHistoryHidden();
|
||||
}();
|
||||
const auto canEditForum = isChannel
|
||||
&& channel->isMegagroup()
|
||||
&& channel->canEditInformation();
|
||||
|
||||
const auto canEditPermissions = [&] {
|
||||
return isChannel
|
||||
|
@ -972,10 +1001,14 @@ void Controller::fillManageSection() {
|
|||
if (canEditPreHistoryHidden) {
|
||||
fillHistoryVisibilityButton();
|
||||
}
|
||||
if (canEditForum) {
|
||||
fillForumButton();
|
||||
}
|
||||
if (canEditSignatures) {
|
||||
fillSignaturesButton();
|
||||
}
|
||||
if (canEditPreHistoryHidden
|
||||
|| canEditForum
|
||||
|| canEditSignatures
|
||||
//|| canEditInviteLinks
|
||||
|| canViewOrEditLinkedChat
|
||||
|
@ -1235,6 +1268,7 @@ std::optional<Controller::Saving> Controller::validate() const {
|
|||
&& validateTitle(result)
|
||||
&& validateDescription(result)
|
||||
&& validateHistoryVisibility(result)
|
||||
&& validateForum(result)
|
||||
&& validateSignatures(result)
|
||||
&& validateForwards(result)
|
||||
&& validateJoinToWrite(result)
|
||||
|
@ -1302,6 +1336,14 @@ bool Controller::validateHistoryVisibility(Saving &to) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Controller::validateForum(Saving &to) const {
|
||||
if (!_forumSavedValue.has_value()) {
|
||||
return true;
|
||||
}
|
||||
to.forum = _forumSavedValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::validateSignatures(Saving &to) const {
|
||||
if (!_signaturesSavedValue.has_value()) {
|
||||
return true;
|
||||
|
@ -1347,6 +1389,7 @@ void Controller::save() {
|
|||
pushSaveStage([=] { saveTitle(); });
|
||||
pushSaveStage([=] { saveDescription(); });
|
||||
pushSaveStage([=] { saveHistoryVisibility(); });
|
||||
pushSaveStage([=] { saveForum(); });
|
||||
pushSaveStage([=] { saveSignatures(); });
|
||||
pushSaveStage([=] { saveForwards(); });
|
||||
pushSaveStage([=] { saveJoinToWrite(); });
|
||||
|
@ -1585,6 +1628,28 @@ void Controller::togglePreHistoryHidden(
|
|||
}).send();
|
||||
}
|
||||
|
||||
void Controller::saveForum() {
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!_savingData.forum
|
||||
|| !channel
|
||||
|| *_savingData.forum == channel->isForum()) {
|
||||
return continueSave();
|
||||
}
|
||||
_api.request(MTPchannels_ToggleForum(
|
||||
channel->inputChannel,
|
||||
MTP_bool(*_savingData.forum)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
continueSave();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.type() == qstr("CHAT_NOT_MODIFIED")) {
|
||||
continueSave();
|
||||
} else {
|
||||
cancelSave();
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Controller::saveSignatures() {
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!_savingData.signatures
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_chat.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_location.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_group_call.h"
|
||||
|
@ -34,6 +35,10 @@ using UpdateFlag = Data::PeerUpdate::Flag;
|
|||
|
||||
} // namespace
|
||||
|
||||
MegagroupInfo::MegagroupInfo() = default;
|
||||
|
||||
MegagroupInfo::~MegagroupInfo() = default;
|
||||
|
||||
ChatData *MegagroupInfo::getMigrateFromChat() const {
|
||||
return _migratedFrom;
|
||||
}
|
||||
|
@ -55,6 +60,20 @@ Data::ChatBotCommands::Changed MegagroupInfo::setBotCommands(
|
|||
return _botCommands.update(list);
|
||||
}
|
||||
|
||||
void MegagroupInfo::setIsForum(bool is) {
|
||||
if (is == (_forum != nullptr)) {
|
||||
return;
|
||||
} else if (is) {
|
||||
_forum = std::make_unique<Data::Forum>();
|
||||
} else {
|
||||
_forum = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Data::Forum *MegagroupInfo::forum() const {
|
||||
return _forum.get();
|
||||
}
|
||||
|
||||
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
|
||||
: PeerData(owner, id)
|
||||
, inputChannel(
|
||||
|
@ -78,6 +97,10 @@ ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
|
|||
mgInfo = nullptr;
|
||||
}
|
||||
}
|
||||
if (change.diff & Flag::Forum) {
|
||||
Assert(mgInfo != nullptr);
|
||||
mgInfo->setIsForum(change.value & Flag::Forum);
|
||||
}
|
||||
if (change.diff & Flag::CallNotEmpty) {
|
||||
if (const auto history = this->owner().historyLoaded(this)) {
|
||||
history->updateChatListEntry();
|
||||
|
|
|
@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_chat_participant_status.h"
|
||||
#include "data/data_peer_bot_commands.h"
|
||||
|
||||
namespace Data {
|
||||
class Forum;
|
||||
} // namespace Data
|
||||
|
||||
struct ChannelLocation {
|
||||
QString address;
|
||||
Data::LocationPoint point;
|
||||
|
@ -55,12 +59,16 @@ enum class ChannelDataFlag {
|
|||
NoForwards = (1 << 20),
|
||||
JoinToWrite = (1 << 21),
|
||||
RequestToJoin = (1 << 22),
|
||||
Forum = (1 << 23),
|
||||
};
|
||||
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
|
||||
using ChannelDataFlags = base::flags<ChannelDataFlag>;
|
||||
|
||||
class MegagroupInfo {
|
||||
public:
|
||||
MegagroupInfo();
|
||||
~MegagroupInfo();
|
||||
|
||||
struct Admin {
|
||||
explicit Admin(ChatAdminRightsInfo rights)
|
||||
: rights(rights) {
|
||||
|
@ -92,6 +100,9 @@ public:
|
|||
return _botCommands;
|
||||
}
|
||||
|
||||
void setIsForum(bool is);
|
||||
[[nodiscard]] Data::Forum *forum() const;
|
||||
|
||||
std::deque<not_null<UserData*>> lastParticipants;
|
||||
base::flat_map<not_null<UserData*>, Admin> lastAdmins;
|
||||
base::flat_map<not_null<UserData*>, Restricted> lastRestricted;
|
||||
|
@ -119,10 +130,11 @@ private:
|
|||
ChatData *_migratedFrom = nullptr;
|
||||
ChannelLocation _location;
|
||||
Data::ChatBotCommands _botCommands;
|
||||
std::unique_ptr<Data::Forum> _forum;
|
||||
|
||||
};
|
||||
|
||||
class ChannelData : public PeerData {
|
||||
class ChannelData final : public PeerData {
|
||||
public:
|
||||
using Flag = ChannelDataFlag;
|
||||
using Flags = Data::Flags<ChannelDataFlags>;
|
||||
|
@ -243,6 +255,9 @@ public:
|
|||
[[nodiscard]] bool isGigagroup() const {
|
||||
return flags() & Flag::Gigagroup;
|
||||
}
|
||||
[[nodiscard]] bool isForum() const {
|
||||
return flags() & Flag::Forum;
|
||||
}
|
||||
[[nodiscard]] bool hasUsername() const {
|
||||
return flags() & Flag::Username;
|
||||
}
|
||||
|
@ -420,6 +435,10 @@ public:
|
|||
void setAllowedReactions(Data::AllowedReactions value);
|
||||
[[nodiscard]] const Data::AllowedReactions &allowedReactions() const;
|
||||
|
||||
[[nodiscard]] Data::Forum *forum() const {
|
||||
return mgInfo ? mgInfo->forum() : nullptr;
|
||||
}
|
||||
|
||||
// Still public data members.
|
||||
uint64 access = 0;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ enum class ChatDataFlag {
|
|||
inline constexpr bool is_flag_type(ChatDataFlag) { return true; };
|
||||
using ChatDataFlags = base::flags<ChatDataFlag>;
|
||||
|
||||
class ChatData : public PeerData {
|
||||
class ChatData final : public PeerData {
|
||||
public:
|
||||
using Flag = ChatDataFlag;
|
||||
using Flags = Data::Flags<ChatDataFlags>;
|
||||
|
|
16
Telegram/SourceFiles/data/data_forum.cpp
Normal file
16
Telegram/SourceFiles/data/data_forum.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
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_forum.h"
|
||||
|
||||
namespace Data {
|
||||
|
||||
Forum::Forum() = default;
|
||||
|
||||
Forum::~Forum() = default;
|
||||
|
||||
} // namespace Data
|
21
Telegram/SourceFiles/data/data_forum.h
Normal file
21
Telegram/SourceFiles/data/data_forum.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
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
|
||||
|
||||
namespace Data {
|
||||
|
||||
class Forum final {
|
||||
public:
|
||||
Forum();
|
||||
~Forum();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace Data
|
|
@ -844,15 +844,31 @@ bool PeerData::isFake() const {
|
|||
}
|
||||
|
||||
bool PeerData::isMegagroup() const {
|
||||
return isChannel() && asChannel()->isMegagroup();
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isMegagroup();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::isBroadcast() const {
|
||||
return isChannel() && asChannel()->isBroadcast();
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isBroadcast();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::isForum() const {
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isForum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::isGigagroup() const {
|
||||
return isChannel() && asChannel()->isGigagroup();
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isGigagroup();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::isRepliesChat() const {
|
||||
|
|
|
@ -180,6 +180,7 @@ public:
|
|||
[[nodiscard]] bool isFake() const;
|
||||
[[nodiscard]] bool isMegagroup() const;
|
||||
[[nodiscard]] bool isBroadcast() const;
|
||||
[[nodiscard]] bool isForum() const;
|
||||
[[nodiscard]] bool isGigagroup() const;
|
||||
[[nodiscard]] bool isRepliesChat() const;
|
||||
[[nodiscard]] bool sharedMediaInfo() const {
|
||||
|
|
|
@ -777,7 +777,8 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
|
|||
| (!minimal ? (Flag::Left | Flag::Creator) : Flag())
|
||||
| Flag::NoForwards
|
||||
| Flag::JoinToWrite
|
||||
| Flag::RequestToJoin;
|
||||
| Flag::RequestToJoin
|
||||
| Flag::Forum;
|
||||
const auto flagsSet = (data.is_broadcast() ? Flag::Broadcast : Flag())
|
||||
| (data.is_verified() ? Flag::Verified : Flag())
|
||||
| (data.is_scam() ? Flag::Scam : Flag())
|
||||
|
@ -800,7 +801,10 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
|
|||
: Flag())
|
||||
| (data.is_noforwards() ? Flag::NoForwards : Flag())
|
||||
| (data.is_join_to_send() ? Flag::JoinToWrite : Flag())
|
||||
| (data.is_join_request() ? Flag::RequestToJoin : Flag());
|
||||
| (data.is_join_request() ? Flag::RequestToJoin : Flag())
|
||||
| ((data.is_forum() && data.is_megagroup())
|
||||
? Flag::Forum
|
||||
: Flag());
|
||||
channel->setFlags((channel->flags() & ~flagsMask) | flagsSet);
|
||||
|
||||
channel->setName(
|
||||
|
|
|
@ -57,7 +57,7 @@ enum class UserDataFlag {
|
|||
inline constexpr bool is_flag_type(UserDataFlag) { return true; };
|
||||
using UserDataFlags = base::flags<UserDataFlag>;
|
||||
|
||||
class UserData : public PeerData {
|
||||
class UserData final : public PeerData {
|
||||
public:
|
||||
using Flag = UserDataFlag;
|
||||
using Flags = Data::Flags<UserDataFlags>;
|
||||
|
|
|
@ -394,15 +394,22 @@ void InnerWidget::changeOpenedFolder(Data::Folder *folder) {
|
|||
return;
|
||||
}
|
||||
stopReorderPinned();
|
||||
//const auto mouseSelection = _mouseSelection;
|
||||
//const auto lastMousePosition = _lastMousePosition;
|
||||
clearSelection();
|
||||
_openedFolder = folder;
|
||||
refreshWithCollapsedRows(true);
|
||||
// This doesn't work, because we clear selection in leaveEvent on hide.
|
||||
//if (mouseSelection && lastMousePosition) {
|
||||
// selectByMouse(*lastMousePosition);
|
||||
//}
|
||||
if (_loadMoreCallback) {
|
||||
_loadMoreCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::changeOpenedForum(ChannelData *forum) {
|
||||
if (_openedForum == forum) {
|
||||
return;
|
||||
}
|
||||
stopReorderPinned();
|
||||
clearSelection();
|
||||
_openedForum = forum;
|
||||
refreshWithCollapsedRows(true);
|
||||
if (_loadMoreCallback) {
|
||||
_loadMoreCallback();
|
||||
}
|
||||
|
@ -1160,6 +1167,8 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
|
|||
} else if (qAbs(localPosition.y() - _dragStart.y())
|
||||
< style::ConvertScale(kStartReorderThreshold)) {
|
||||
return;
|
||||
} else if (_openedForum) {
|
||||
return; // #TODO forum
|
||||
}
|
||||
_dragging = _pressed;
|
||||
if (updateReorderIndexGetCount() < 2) {
|
||||
|
@ -1311,7 +1320,7 @@ bool InnerWidget::updateReorderPinned(QPoint localPosition) {
|
|||
const auto delta = [&] {
|
||||
if (localPosition.y() < _visibleTop) {
|
||||
return localPosition.y() - _visibleTop;
|
||||
} else if ((_openedFolder || _filterId)
|
||||
} else if ((_openedFolder || _openedForum || _filterId)
|
||||
&& localPosition.y() > _visibleBottom) {
|
||||
return localPosition.y() - _visibleBottom;
|
||||
}
|
||||
|
@ -2273,6 +2282,10 @@ Data::Folder *InnerWidget::shownFolder() const {
|
|||
return _openedFolder;
|
||||
}
|
||||
|
||||
ChannelData *InnerWidget::shownForum() const {
|
||||
return _openedForum;
|
||||
}
|
||||
|
||||
bool InnerWidget::needCollapsedRowsRefresh() const {
|
||||
const auto list = shownDialogs();
|
||||
const auto archive = !list->empty()
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
void clearSelection();
|
||||
|
||||
void changeOpenedFolder(Data::Folder *folder);
|
||||
void changeOpenedForum(ChannelData *forum);
|
||||
void selectSkip(int32 direction);
|
||||
void selectSkipPage(int32 pixels, int32 direction);
|
||||
|
||||
|
@ -109,6 +110,7 @@ public:
|
|||
void scrollToEntry(const RowDescriptor &entry);
|
||||
|
||||
Data::Folder *shownFolder() const;
|
||||
ChannelData *shownForum() const;
|
||||
int32 lastSearchDate() const;
|
||||
PeerData *lastSearchPeer() const;
|
||||
MsgId lastSearchId() const;
|
||||
|
@ -179,6 +181,7 @@ private:
|
|||
Loading,
|
||||
NoContacts,
|
||||
EmptyFolder,
|
||||
EmptyForum,
|
||||
};
|
||||
|
||||
Main::Session &session() const;
|
||||
|
@ -348,6 +351,7 @@ private:
|
|||
Qt::MouseButton _pressButton = Qt::LeftButton;
|
||||
|
||||
Data::Folder *_openedFolder = nullptr;
|
||||
ChannelData *_openedForum = nullptr;
|
||||
|
||||
std::vector<std::unique_ptr<CollapsedRow>> _collapsedRows;
|
||||
int _collapsedSelected = -1;
|
||||
|
|
|
@ -260,7 +260,10 @@ Widget::Widget(
|
|||
) | rpl::start_with_next([=](const ChosenRow &row) {
|
||||
const auto openSearchResult = !controller->selectingPeer()
|
||||
&& row.filteredRow;
|
||||
if (const auto history = row.key.history()) {
|
||||
const auto history = row.key.history();
|
||||
if (history && history->peer->isForum()) {
|
||||
controller->openForum(history->peer->asChannel());
|
||||
} else if (history) {
|
||||
const auto peer = history->peer;
|
||||
const auto showAtMsgId = controller->uniqueChatsInSearchResults()
|
||||
? ShowAtUnreadMsgId
|
||||
|
@ -399,6 +402,15 @@ Widget::Widget(
|
|||
changeOpenedFolder(folder, anim::type::normal);
|
||||
}, lifetime());
|
||||
|
||||
changeOpenedForum(
|
||||
controller->openedForum().current(),
|
||||
anim::type::instant);
|
||||
|
||||
controller->openedForum().changes(
|
||||
) | rpl::start_with_next([=](ChannelData *forum) {
|
||||
changeOpenedForum(forum, anim::type::normal);
|
||||
}, lifetime());
|
||||
|
||||
setupDownloadBar();
|
||||
}
|
||||
|
||||
|
@ -597,14 +609,14 @@ void Widget::updateControlsVisibility(bool fast) {
|
|||
if (_forwardCancel) {
|
||||
_forwardCancel->show();
|
||||
}
|
||||
if (_openedFolder && _filter->hasFocus()) {
|
||||
if ((_openedFolder || _openedForum) && _filter->hasFocus()) {
|
||||
setFocus();
|
||||
}
|
||||
if (_updateTelegram) {
|
||||
_updateTelegram->show();
|
||||
}
|
||||
_searchControls->setVisible(!_openedFolder);
|
||||
if (_openedFolder) {
|
||||
_searchControls->setVisible(!_openedFolder && !_openedForum);
|
||||
if (_openedFolder || _openedForum) {
|
||||
_folderTopBar->show();
|
||||
} else {
|
||||
if (hasFocus()) {
|
||||
|
@ -618,24 +630,26 @@ void Widget::updateControlsVisibility(bool fast) {
|
|||
_connecting->setForceHidden(false);
|
||||
}
|
||||
|
||||
void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
|
||||
void Widget::changeOpenedSubsection(
|
||||
FnMut<void()> change,
|
||||
bool fromRight,
|
||||
anim::type animated) {
|
||||
_a_show.stop();
|
||||
|
||||
if (isHidden()) {
|
||||
animated = anim::type::instant;
|
||||
}
|
||||
if (animated == anim::type::normal) {
|
||||
_showDirection = folder
|
||||
_showDirection = fromRight
|
||||
? Window::SlideDirection::FromRight
|
||||
: Window::SlideDirection::FromLeft;
|
||||
_showAnimationType = ShowAnimation::Internal;
|
||||
_connecting->setForceHidden(true);
|
||||
_cacheUnder = grabForFolderSlideAnimation();
|
||||
}
|
||||
_openedFolder = folder;
|
||||
change();
|
||||
refreshFolderTopBar();
|
||||
updateControlsVisibility(true);
|
||||
_inner->changeOpenedFolder(folder);
|
||||
if (animated == anim::type::normal) {
|
||||
_connecting->setForceHidden(true);
|
||||
_cacheOver = grabForFolderSlideAnimation();
|
||||
|
@ -644,15 +658,31 @@ void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
|
||||
changeOpenedSubsection([&] {
|
||||
_openedFolder = folder;
|
||||
_inner->changeOpenedFolder(folder);
|
||||
}, (folder != nullptr), animated);
|
||||
}
|
||||
|
||||
void Widget::changeOpenedForum(ChannelData *forum, anim::type animated) {
|
||||
changeOpenedSubsection([&] {
|
||||
_openedForum = forum;
|
||||
_inner->changeOpenedForum(forum);
|
||||
}, (forum != nullptr), animated);
|
||||
}
|
||||
|
||||
void Widget::refreshFolderTopBar() {
|
||||
if (_openedFolder) {
|
||||
if (_openedFolder || _openedForum) {
|
||||
if (!_folderTopBar) {
|
||||
_folderTopBar.create(this, controller());
|
||||
updateControlsGeometry();
|
||||
}
|
||||
_folderTopBar->setActiveChat(
|
||||
HistoryView::TopBarWidget::ActiveChat{
|
||||
.key = _openedFolder,
|
||||
.key = (_openedFolder
|
||||
? Dialogs::Key(_openedFolder)
|
||||
: Dialogs::Key(session().data().history(_openedForum))),
|
||||
.section = Dialogs::EntryState::Section::ChatsList,
|
||||
},
|
||||
nullptr);
|
||||
|
@ -713,7 +743,7 @@ void Widget::checkUpdateStatus() {
|
|||
}
|
||||
|
||||
void Widget::setInnerFocus() {
|
||||
if (_openedFolder) {
|
||||
if (_openedFolder || _openedForum) {
|
||||
setFocus();
|
||||
} else {
|
||||
_filter->setFocus();
|
||||
|
@ -853,6 +883,8 @@ void Widget::animationCallback() {
|
|||
void Widget::escape() {
|
||||
if (controller()->openedFolder().current()) {
|
||||
controller()->closeFolder();
|
||||
} else if (controller()->openedForum().current()) {
|
||||
controller()->closeForum();
|
||||
} else if (!cancelSearch()) {
|
||||
if (controller()->activeChatEntryCurrent().key) {
|
||||
controller()->content()->dialogsCancelled();
|
||||
|
@ -1633,6 +1665,7 @@ void Widget::updateLoadMoreChatsVisibility() {
|
|||
return;
|
||||
}
|
||||
const auto hidden = (_openedFolder != nullptr)
|
||||
|| (_openedForum != nullptr)
|
||||
|| !_filter->getLastText().isEmpty();
|
||||
if (_loadMoreChats->isHidden() != hidden) {
|
||||
_loadMoreChats->setVisible(!hidden);
|
||||
|
@ -1778,6 +1811,8 @@ void Widget::keyPressEvent(QKeyEvent *e) {
|
|||
if (e->key() == Qt::Key_Escape) {
|
||||
if (_openedFolder) {
|
||||
controller()->closeFolder();
|
||||
} else if (_openedForum) {
|
||||
controller()->closeForum();
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
|
|
|
@ -153,7 +153,12 @@ private:
|
|||
void updateControlsGeometry();
|
||||
void refreshFolderTopBar();
|
||||
void checkUpdateStatus();
|
||||
void changeOpenedSubsection(
|
||||
FnMut<void()> change,
|
||||
bool fromRight,
|
||||
anim::type animated);
|
||||
void changeOpenedFolder(Data::Folder *folder, anim::type animated);
|
||||
void changeOpenedForum(ChannelData *forum, anim::type animated);
|
||||
QPixmap grabForFolderSlideAnimation();
|
||||
void startSlideAnimation();
|
||||
|
||||
|
@ -209,6 +214,7 @@ private:
|
|||
object_ptr<Ui::HistoryDownButton> _scrollToTop;
|
||||
|
||||
Data::Folder *_openedFolder = nullptr;
|
||||
ChannelData *_openedForum = nullptr;
|
||||
Dialogs::Key _searchInChat;
|
||||
History *_searchInMigrated = nullptr;
|
||||
PeerData *_searchFromAuthor = nullptr;
|
||||
|
|
|
@ -1152,6 +1152,10 @@ ServiceAction ParseServiceAction(
|
|||
qs(data.vcurrency())).toUtf8();
|
||||
content.months = data.vmonths().v;
|
||||
result.content = content;
|
||||
}, [&](const MTPDmessageActionTopicCreate &data) {
|
||||
auto content = ActionTopicCreated();
|
||||
content.title = ParseString(data.vtitle());
|
||||
result.content = content;
|
||||
}, [](const MTPDmessageActionEmpty &data) {});
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -499,6 +499,10 @@ struct ActionGiftPremium {
|
|||
int months;
|
||||
};
|
||||
|
||||
struct ActionTopicCreated {
|
||||
Utf8String title;
|
||||
};
|
||||
|
||||
struct ServiceAction {
|
||||
std::variant<
|
||||
v::null_t,
|
||||
|
@ -531,7 +535,8 @@ struct ServiceAction {
|
|||
ActionSetChatTheme,
|
||||
ActionChatJoinedByRequest,
|
||||
ActionWebViewDataSent,
|
||||
ActionGiftPremium> content;
|
||||
ActionGiftPremium,
|
||||
ActionTopicCreated> content;
|
||||
};
|
||||
|
||||
ServiceAction ParseServiceAction(
|
||||
|
|
|
@ -1137,13 +1137,19 @@ auto HtmlWriter::Wrap::pushMessage(
|
|||
+ "» button to the bot";
|
||||
}, [&](const ActionGiftPremium &data) {
|
||||
if (!data.months || data.cost.isEmpty()) {
|
||||
return (serviceFrom + " sent you a gift.");
|
||||
return serviceFrom + " sent you a gift.";
|
||||
}
|
||||
return (serviceFrom
|
||||
return serviceFrom
|
||||
+ " sent you a gift for "
|
||||
+ data.cost
|
||||
+ ": Telegram Premium for "
|
||||
+ QString::number(data.months).toUtf8() + " months.");
|
||||
+ QString::number(data.months).toUtf8()
|
||||
+ " months.";
|
||||
}, [&](const ActionTopicCreated &data) {
|
||||
return serviceFrom
|
||||
+ " created topic «"
|
||||
+ SerializeString(data.title)
|
||||
+ "»";
|
||||
}, [](v::null_t) { return QByteArray(); });
|
||||
|
||||
if (!serviceText.isEmpty()) {
|
||||
|
|
|
@ -560,6 +560,10 @@ QByteArray SerializeMessage(
|
|||
if (data.months) {
|
||||
push("months", data.months);
|
||||
}
|
||||
}, [&](const ActionTopicCreated &data) {
|
||||
pushActor();
|
||||
pushAction("topic_created");
|
||||
push("title", data.title);
|
||||
}, [](v::null_t) {});
|
||||
|
||||
if (v::is_null(message.action.content)) {
|
||||
|
|
|
@ -633,6 +633,12 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) {
|
|||
return result;
|
||||
};
|
||||
|
||||
auto prepareTopicCreate = [&](const MTPDmessageActionTopicCreate &action) {
|
||||
auto result = PreparedText{};
|
||||
result.text = { "topic created" };
|
||||
return result;
|
||||
};
|
||||
|
||||
setServiceText(action.match([&](
|
||||
const MTPDmessageActionChatAddUser &data) {
|
||||
return prepareChatAddUserText(data);
|
||||
|
@ -702,6 +708,8 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) {
|
|||
return prepareWebViewDataSent(data);
|
||||
}, [&](const MTPDmessageActionGiftPremium &data) {
|
||||
return prepareGiftPremium(data);
|
||||
}, [&](const MTPDmessageActionTopicCreate &data) {
|
||||
return prepareTopicCreate(data);
|
||||
}, [&](const MTPDmessageActionWebViewDataSentMe &data) {
|
||||
LOG(("API Error: messageActionWebViewDataSentMe received."));
|
||||
return PreparedText{
|
||||
|
|
|
@ -477,8 +477,9 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
if (folder
|
||||
|| history->peer->sharedMediaInfo()
|
||||
|| (_activeChat.section == Section::Scheduled)
|
||||
|| (_activeChat.section == Section::Pinned)) {
|
||||
// #TODO feed name emoji.
|
||||
|| (_activeChat.section == Section::Pinned)
|
||||
|| (_activeChat.section == Section::ChatsList)) {
|
||||
// #TODO forum name emoji.
|
||||
auto text = (_activeChat.section == Section::Scheduled)
|
||||
? ((history && history->peer->isSelf())
|
||||
? tr::lng_reminder_messages(tr::now)
|
||||
|
@ -489,7 +490,9 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
? folder->chatListName()
|
||||
: history->peer->isSelf()
|
||||
? tr::lng_saved_messages(tr::now)
|
||||
: tr::lng_replies_messages(tr::now);
|
||||
: history->peer->isRepliesChat()
|
||||
? tr::lng_replies_messages(tr::now)
|
||||
: history->peer->name();
|
||||
const auto textWidth = st::historySavedFont->width(text);
|
||||
if (availableWidth < textWidth) {
|
||||
text = st::historySavedFont->elided(text, availableWidth);
|
||||
|
@ -686,6 +689,10 @@ void TopBarWidget::infoClicked() {
|
|||
void TopBarWidget::backClicked() {
|
||||
if (_activeChat.key.folder()) {
|
||||
_controller->closeFolder();
|
||||
} else if (_activeChat.section == Section::ChatsList
|
||||
&& _activeChat.key.history()
|
||||
&& _activeChat.key.history()->peer->isForum()) {
|
||||
_controller->closeForum();
|
||||
} else {
|
||||
_controller->showBackFromStack();
|
||||
}
|
||||
|
@ -933,7 +940,7 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
const auto isOneColumn = _controller->adaptive().isOneColumn();
|
||||
auto backVisible = isOneColumn
|
||||
|| !_controller->content()->stackIsEmpty()
|
||||
|| _activeChat.key.folder();
|
||||
|| (_activeChat.section == Section::ChatsList);
|
||||
_back->setVisible(backVisible && !_chooseForReportReason);
|
||||
_cancelChoose->setVisible(_chooseForReportReason.has_value());
|
||||
if (_info) {
|
||||
|
|
|
@ -676,6 +676,19 @@ SessionController::SessionController(
|
|||
closeFolder();
|
||||
}, lifetime());
|
||||
|
||||
_openedForum.changes(
|
||||
) | rpl::filter([](ChannelData *forum) {
|
||||
return (forum != nullptr);
|
||||
}) | rpl::map([](ChannelData *forum) {
|
||||
return forum->flagsValue(
|
||||
) | rpl::filter([](ChannelData::Flags::Change change) {
|
||||
return (change.diff & ChannelData::Flag::Forum)
|
||||
&& !(change.value & ChannelData::Flag::Forum);
|
||||
});
|
||||
}) | rpl::flatten_latest() | rpl::start_with_next([=] {
|
||||
closeForum();
|
||||
}, lifetime());
|
||||
|
||||
session->data().chatsFilters().changed(
|
||||
) | rpl::start_with_next([=] {
|
||||
checkOpenedFilter();
|
||||
|
@ -853,6 +866,7 @@ void SessionController::openFolder(not_null<Data::Folder*> folder) {
|
|||
resetFakeUnreadWhileOpened();
|
||||
}
|
||||
setActiveChatsFilter(0);
|
||||
closeForum();
|
||||
_openedFolder = folder.get();
|
||||
}
|
||||
|
||||
|
@ -860,6 +874,21 @@ void SessionController::closeFolder() {
|
|||
_openedFolder = nullptr;
|
||||
}
|
||||
|
||||
void SessionController::openForum(not_null<ChannelData*> forum) {
|
||||
Expects(forum->isForum());
|
||||
|
||||
if (_openedForum.current() != forum) {
|
||||
resetFakeUnreadWhileOpened();
|
||||
}
|
||||
setActiveChatsFilter(0);
|
||||
closeFolder();
|
||||
_openedForum = forum.get();
|
||||
}
|
||||
|
||||
void SessionController::closeForum() {
|
||||
_openedForum = nullptr;
|
||||
}
|
||||
|
||||
void SessionController::setupPremiumToast() {
|
||||
rpl::combine(
|
||||
Data::AmPremiumValue(&session()),
|
||||
|
@ -889,6 +918,10 @@ const rpl::variable<Data::Folder*> &SessionController::openedFolder() const {
|
|||
return _openedFolder;
|
||||
}
|
||||
|
||||
const rpl::variable<ChannelData*> &SessionController::openedForum() const {
|
||||
return _openedForum;
|
||||
}
|
||||
|
||||
void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) {
|
||||
const auto was = _activeChatEntry.current().key.history();
|
||||
const auto now = row.key.history();
|
||||
|
|
|
@ -340,10 +340,15 @@ public:
|
|||
// is changed in the Dialogs::Widget of the current window.
|
||||
rpl::variable<Dialogs::Key> searchInChat;
|
||||
bool uniqueChatsInSearchResults() const;
|
||||
|
||||
void openFolder(not_null<Data::Folder*> folder);
|
||||
void closeFolder();
|
||||
const rpl::variable<Data::Folder*> &openedFolder() const;
|
||||
|
||||
void openForum(not_null<ChannelData*> forum);
|
||||
void closeForum();
|
||||
const rpl::variable<ChannelData*> &openedForum() const;
|
||||
|
||||
void setActiveChatEntry(Dialogs::RowDescriptor row);
|
||||
void setActiveChatEntry(Dialogs::Key key);
|
||||
Dialogs::RowDescriptor activeChatEntryCurrent() const;
|
||||
|
@ -594,6 +599,7 @@ private:
|
|||
|
||||
PeerData *_showEditPeer = nullptr;
|
||||
rpl::variable<Data::Folder*> _openedFolder;
|
||||
rpl::variable<ChannelData*> _openedForum;
|
||||
|
||||
rpl::event_stream<> _filtersMenuChanged;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue