mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow editing topic title and icon.
This commit is contained in:
parent
c90f879c96
commit
3b3792ef75
42 changed files with 603 additions and 190 deletions
|
@ -178,6 +178,8 @@ PRIVATE
|
||||||
boxes/peers/add_participants_box.h
|
boxes/peers/add_participants_box.h
|
||||||
boxes/peers/edit_contact_box.cpp
|
boxes/peers/edit_contact_box.cpp
|
||||||
boxes/peers/edit_contact_box.h
|
boxes/peers/edit_contact_box.h
|
||||||
|
boxes/peers/edit_forum_topic_box.cpp
|
||||||
|
boxes/peers/edit_forum_topic_box.h
|
||||||
boxes/peers/edit_linked_chat_box.cpp
|
boxes/peers/edit_linked_chat_box.cpp
|
||||||
boxes/peers/edit_linked_chat_box.h
|
boxes/peers/edit_linked_chat_box.h
|
||||||
boxes/peers/edit_participant_box.cpp
|
boxes/peers/edit_participant_box.cpp
|
||||||
|
|
223
Telegram/SourceFiles/boxes/peers/edit_forum_topic_box.cpp
Normal file
223
Telegram/SourceFiles/boxes/peers/edit_forum_topic_box.cpp
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
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 "boxes/peers/edit_forum_topic_box.h"
|
||||||
|
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/abstract_button.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_forum.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "info/profile/info_profile_emoji_status_panel.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
#include "settings/settings_common.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] int EditIconSize() {
|
||||||
|
const auto tag = Data::CustomEmojiManager::SizeTag::Large;
|
||||||
|
return Data::FrameSizeFromTag(tag) / style::DevicePixelRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<DocumentId> EditIconButton(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
DocumentId id) {
|
||||||
|
using namespace Info::Profile;
|
||||||
|
struct State {
|
||||||
|
rpl::variable<DocumentId> id;
|
||||||
|
EmojiStatusPanel panel;
|
||||||
|
std::unique_ptr<Ui::Text::CustomEmoji> chosen;
|
||||||
|
};
|
||||||
|
const auto tag = Data::CustomEmojiManager::SizeTag::Large;
|
||||||
|
const auto size = EditIconSize();
|
||||||
|
const auto result = Ui::CreateChild<Ui::AbstractButton>(parent.get());
|
||||||
|
const auto state = result->lifetime().make_state<State>();
|
||||||
|
state->id.value(
|
||||||
|
) | rpl::start_with_next([=](DocumentId id) {
|
||||||
|
const auto owner = &controller->session().data();
|
||||||
|
state->chosen = id
|
||||||
|
? owner->customEmojiManager().create(
|
||||||
|
id,
|
||||||
|
[=] { result->update(); },
|
||||||
|
tag)
|
||||||
|
: nullptr;
|
||||||
|
result->update();
|
||||||
|
}, result->lifetime());
|
||||||
|
state->id = id;
|
||||||
|
state->panel.setChooseFilter([=](DocumentId) {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
state->panel.setChooseCallback([=](DocumentId id) {
|
||||||
|
state->id = id;
|
||||||
|
});
|
||||||
|
result->resize(size, size);
|
||||||
|
result->paintRequest(
|
||||||
|
) | rpl::filter([=] {
|
||||||
|
return !state->panel.paintBadgeFrame(result);
|
||||||
|
}) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
auto args = Ui::Text::CustomEmoji::Context{
|
||||||
|
.preview = st::windowBgOver->c,
|
||||||
|
.now = crl::now(),
|
||||||
|
.paused = controller->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::Layer),
|
||||||
|
};
|
||||||
|
auto p = QPainter(result);
|
||||||
|
if (state->chosen) {
|
||||||
|
state->chosen->paint(p, args);
|
||||||
|
} else {
|
||||||
|
p.fillRect(clip, Qt::red);
|
||||||
|
}
|
||||||
|
}, result->lifetime());
|
||||||
|
result->setClickedCallback([=] {
|
||||||
|
state->panel.show(controller, result, tag);
|
||||||
|
});
|
||||||
|
return state->id.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void NewForumTopicBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<History*> forum) {
|
||||||
|
EditForumTopicBox(box, controller, forum, MsgId(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditForumTopicBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<History*> forum,
|
||||||
|
MsgId rootId) {
|
||||||
|
const auto creating = !rootId;
|
||||||
|
const auto topic = (!creating && forum->peer->forum())
|
||||||
|
? forum->peer->forum()->topicFor(rootId)
|
||||||
|
: nullptr;
|
||||||
|
// #TODO forum lang
|
||||||
|
box->setTitle(rpl::single(creating ? u"New topic"_q : u"Edit topic"_q));
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
DocumentId iconId = 0;
|
||||||
|
mtpRequestId titleRequestId = 0;
|
||||||
|
mtpRequestId iconRequestId = 0;
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<State>();
|
||||||
|
// #TODO forum lang and design
|
||||||
|
Settings::AddSubsectionTitle(
|
||||||
|
box->verticalLayout(),
|
||||||
|
rpl::single(u"Topic Icon"_q));
|
||||||
|
const auto badgeWrap = box->addRow(
|
||||||
|
object_ptr<Ui::FixedHeightWidget>(box, EditIconSize()));
|
||||||
|
EditIconButton(
|
||||||
|
controller,
|
||||||
|
badgeWrap,
|
||||||
|
topic ? topic->iconId() : 0
|
||||||
|
) | rpl::start_with_next([=](DocumentId id) {
|
||||||
|
state->iconId = id;
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
const auto title = box->addRow(
|
||||||
|
object_ptr<Ui::InputField>(
|
||||||
|
box,
|
||||||
|
st::defaultInputField,
|
||||||
|
rpl::single(u"Topic Title"_q),
|
||||||
|
topic ? topic->title() : QString())); // #TODO forum lang
|
||||||
|
box->setFocusCallback([=] {
|
||||||
|
title->setFocusFast();
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto requestId = std::make_shared<mtpRequestId>();
|
||||||
|
const auto create = [=] {
|
||||||
|
if (!forum->peer->isForum()) {
|
||||||
|
box->closeBox();
|
||||||
|
return;
|
||||||
|
} else if (title->getLastText().trimmed().isEmpty()) {
|
||||||
|
title->setFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if 0 // #TODO forum create
|
||||||
|
const auto randomId = base::RandomValue<uint64>();
|
||||||
|
const auto api = &forum->session().api();
|
||||||
|
api->request(MTPchannels_CreateForumTopic(
|
||||||
|
MTP_flags(0),
|
||||||
|
forum->inputChannel,
|
||||||
|
MTP_string(title->getLastText().trimmed()),
|
||||||
|
MTPlong(), // icon_emoji_id
|
||||||
|
MTPInputMedia(),
|
||||||
|
MTP_string(message->getLastText().trimmed()),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPVector<MTPMessageEntity>(),
|
||||||
|
MTPInputPeer() // send_as
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
api->applyUpdates(result, randomId);
|
||||||
|
box->closeBox();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
api->sendMessageFail(error, forum, randomId);
|
||||||
|
}).send();
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto save = [=] {
|
||||||
|
const auto topic = forum->peer->forum()
|
||||||
|
? forum->peer->forum()->topicFor(rootId)
|
||||||
|
: nullptr;
|
||||||
|
if (!topic) {
|
||||||
|
box->closeBox();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto api = &forum->session().api();
|
||||||
|
if (state->titleRequestId <= 0) {
|
||||||
|
if (title->getLastText().trimmed().isEmpty()) {
|
||||||
|
title->setFocus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state->titleRequestId = api->request(MTPchannels_EditForumTitle(
|
||||||
|
topic->channel()->inputChannel,
|
||||||
|
MTP_int(rootId),
|
||||||
|
MTP_string(title->getLastText().trimmed())
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
api->applyUpdates(result);
|
||||||
|
state->titleRequestId = 0;
|
||||||
|
if (!state->iconRequestId) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
state->titleRequestId = -1;
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
if (state->iconRequestId <= 0) {
|
||||||
|
state->iconRequestId = api->request(MTPchannels_EditForumIcon(
|
||||||
|
topic->channel()->inputChannel,
|
||||||
|
MTP_int(rootId),
|
||||||
|
MTP_long(state->iconId)
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
api->applyUpdates(result);
|
||||||
|
state->iconRequestId = 0;
|
||||||
|
if (!state->titleRequestId) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
state->iconRequestId = -1;
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (creating) {
|
||||||
|
box->addButton(tr::lng_create_group_create(), create);
|
||||||
|
} else {
|
||||||
|
box->addButton(tr::lng_settings_save(), save);
|
||||||
|
}
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
}
|
27
Telegram/SourceFiles/boxes/peers/edit_forum_topic_box.h
Normal file
27
Telegram/SourceFiles/boxes/peers/edit_forum_topic_box.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/layers/generic_box.h"
|
||||||
|
|
||||||
|
class History;
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
class SessionController;
|
||||||
|
} // namespace Window
|
||||||
|
|
||||||
|
void NewForumTopicBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<History*> forum);
|
||||||
|
|
||||||
|
void EditForumTopicBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<History*> forum,
|
||||||
|
MsgId rootId);
|
|
@ -818,7 +818,7 @@ void Controller::fillForumButton() {
|
||||||
|
|
||||||
AddButtonWithText(
|
AddButtonWithText(
|
||||||
_controls.buttonsLayout,
|
_controls.buttonsLayout,
|
||||||
rpl::single(u"Forum"_q), // #TODO forum lang
|
rpl::single(u"Topics"_q), // #TODO forum lang
|
||||||
rpl::single(QString()),
|
rpl::single(QString()),
|
||||||
[] {},
|
[] {},
|
||||||
{ &st::settingsIconGroup, Settings::kIconPurple }
|
{ &st::settingsIconGroup, Settings::kIconPurple }
|
||||||
|
|
|
@ -1258,9 +1258,7 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
||||||
result->menu(),
|
result->menu(),
|
||||||
st::groupCallPopupCoverMenu,
|
st::groupCallPopupCoverMenu,
|
||||||
st::groupCallMenuCover,
|
st::groupCallMenuCover,
|
||||||
Info::Profile::NameValue(
|
Info::Profile::NameValue(participantPeer),
|
||||||
participantPeer
|
|
||||||
) | rpl::map([](const auto &text) { return text.text; }),
|
|
||||||
PrepareShortInfoStatus(participantPeer),
|
PrepareShortInfoStatus(participantPeer),
|
||||||
PrepareShortInfoUserpic(
|
PrepareShortInfoUserpic(
|
||||||
participantPeer,
|
participantPeer,
|
||||||
|
|
|
@ -182,10 +182,10 @@ void JoinAsAction::prepare() {
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
tr::lng_group_call_display_as_header(),
|
tr::lng_group_call_display_as_header(),
|
||||||
Info::Profile::NameValue(_peer)
|
Info::Profile::NameValue(_peer)
|
||||||
) | rpl::start_with_next([=](QString text, TextWithEntities name) {
|
) | rpl::start_with_next([=](QString text, QString name) {
|
||||||
const auto &padding = st::groupCallJoinAsPadding;
|
const auto &padding = st::groupCallJoinAsPadding;
|
||||||
_text.setMarkedText(_st.itemStyle, { text }, MenuTextOptions);
|
_text.setMarkedText(_st.itemStyle, { text }, MenuTextOptions);
|
||||||
_name.setMarkedText(_st.itemStyle, name, MenuTextOptions);
|
_name.setMarkedText(_st.itemStyle, { name }, MenuTextOptions);
|
||||||
const auto textWidth = _text.maxWidth();
|
const auto textWidth = _text.maxWidth();
|
||||||
const auto nameWidth = _name.maxWidth();
|
const auto nameWidth = _name.maxWidth();
|
||||||
const auto textLeft = padding.left()
|
const auto textLeft = padding.left()
|
||||||
|
|
|
@ -221,8 +221,8 @@ void Panel::migrate(not_null<ChannelData*> channel) {
|
||||||
void Panel::subscribeToPeerChanges() {
|
void Panel::subscribeToPeerChanges() {
|
||||||
Info::Profile::NameValue(
|
Info::Profile::NameValue(
|
||||||
_peer
|
_peer
|
||||||
) | rpl::start_with_next([=](const TextWithEntities &name) {
|
) | rpl::start_with_next([=](const QString &name) {
|
||||||
window()->setTitle(name.text);
|
window()->setTitle(name);
|
||||||
}, _peerLifetime);
|
}, _peerLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2336,10 +2336,8 @@ void Panel::refreshTitle() {
|
||||||
) | rpl::map([=](not_null<Data::GroupCall*> real) {
|
) | rpl::map([=](not_null<Data::GroupCall*> real) {
|
||||||
return real->titleValue();
|
return real->titleValue();
|
||||||
}) | rpl::flatten_latest())
|
}) | rpl::flatten_latest())
|
||||||
) | rpl::map([=](
|
) | rpl::map([=](const QString &name, const QString &title) {
|
||||||
const TextWithEntities &name,
|
return title.isEmpty() ? name : title;
|
||||||
const QString &title) {
|
|
||||||
return title.isEmpty() ? name.text : title;
|
|
||||||
}) | rpl::after_next([=] {
|
}) | rpl::after_next([=] {
|
||||||
refreshTitleGeometry();
|
refreshTitleGeometry();
|
||||||
});
|
});
|
||||||
|
|
|
@ -165,60 +165,4 @@ rpl::producer<> Forum::chatsListLoadedEvents() const {
|
||||||
return _chatsListLoadedEvents.events();
|
return _chatsListLoadedEvents.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowAddForumTopic(
|
|
||||||
not_null<Window::SessionController*> controller,
|
|
||||||
not_null<ChannelData*> forum) {
|
|
||||||
controller->show(Box([=](not_null<Ui::GenericBox*> box) {
|
|
||||||
box->setTitle(rpl::single(u"New Topic"_q));
|
|
||||||
|
|
||||||
const auto title = box->addRow(
|
|
||||||
object_ptr<Ui::InputField>(
|
|
||||||
box,
|
|
||||||
st::defaultInputField,
|
|
||||||
rpl::single(u"Topic Title"_q))); // #TODO forum lang
|
|
||||||
const auto message = box->addRow(
|
|
||||||
object_ptr<Ui::InputField>(
|
|
||||||
box,
|
|
||||||
st::newGroupDescription,
|
|
||||||
Ui::InputField::Mode::MultiLine,
|
|
||||||
rpl::single(u"Message"_q))); // #TODO forum lang
|
|
||||||
box->setFocusCallback([=] {
|
|
||||||
title->setFocusFast();
|
|
||||||
});
|
|
||||||
box->addButton(tr::lng_create_group_create(), [=] {
|
|
||||||
if (!forum->isForum()) {
|
|
||||||
box->closeBox();
|
|
||||||
return;
|
|
||||||
} else if (title->getLastText().trimmed().isEmpty()) {
|
|
||||||
title->setFocus();
|
|
||||||
return;
|
|
||||||
} else if (message->getLastText().trimmed().isEmpty()) {
|
|
||||||
message->setFocus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto randomId = base::RandomValue<uint64>();
|
|
||||||
const auto api = &forum->session().api();
|
|
||||||
api->request(MTPchannels_CreateForumTopic(
|
|
||||||
MTP_flags(0),
|
|
||||||
forum->inputChannel,
|
|
||||||
MTP_string(title->getLastText().trimmed()),
|
|
||||||
MTPlong(), // icon_emoji_id
|
|
||||||
MTPInputMedia(),
|
|
||||||
MTP_string(message->getLastText().trimmed()),
|
|
||||||
MTP_long(randomId),
|
|
||||||
MTPVector<MTPMessageEntity>(),
|
|
||||||
MTPInputPeer() // send_as
|
|
||||||
)).done([=](const MTPUpdates &result) {
|
|
||||||
api->applyUpdates(result, randomId);
|
|
||||||
box->closeBox();
|
|
||||||
}).fail([=](const MTP::Error &error) {
|
|
||||||
api->sendMessageFail(error, forum, randomId);
|
|
||||||
}).send();
|
|
||||||
});
|
|
||||||
box->addButton(tr::lng_cancel(), [=] {
|
|
||||||
box->closeBox();
|
|
||||||
});
|
|
||||||
}), Ui::LayerOption::KeepOther);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -59,8 +59,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShowAddForumTopic(
|
|
||||||
not_null<Window::SessionController*> controller,
|
|
||||||
not_null<ChannelData*> forum);
|
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -25,6 +25,10 @@ ForumTopic::ForumTopic(not_null<History*> forum, MsgId rootId)
|
||||||
, _rootId(rootId) {
|
, _rootId(rootId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_null<ChannelData*> ForumTopic::channel() const {
|
||||||
|
return _forum->peer->asChannel();
|
||||||
|
}
|
||||||
|
|
||||||
not_null<History*> ForumTopic::forum() const {
|
not_null<History*> ForumTopic::forum() const {
|
||||||
return _forum;
|
return _forum;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +42,11 @@ void ForumTopic::applyTopic(const MTPForumTopic &topic) {
|
||||||
|
|
||||||
const auto &data = topic.data();
|
const auto &data = topic.data();
|
||||||
applyTitle(qs(data.vtitle()));
|
applyTitle(qs(data.vtitle()));
|
||||||
|
if (const auto iconId = data.vicon_emoji_id()) {
|
||||||
|
applyIconId(iconId->v);
|
||||||
|
} else {
|
||||||
|
applyIconId(0);
|
||||||
|
}
|
||||||
|
|
||||||
const auto pinned = _list->pinned();
|
const auto pinned = _list->pinned();
|
||||||
#if 0 // #TODO forum pinned
|
#if 0 // #TODO forum pinned
|
||||||
|
@ -242,6 +251,10 @@ bool ForumTopic::lastServerMessageKnown() const {
|
||||||
return _lastServerMessage.has_value();
|
return _lastServerMessage.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ForumTopic::title() const {
|
||||||
|
return _title;
|
||||||
|
}
|
||||||
|
|
||||||
void ForumTopic::applyTitle(const QString &title) {
|
void ForumTopic::applyTitle(const QString &title) {
|
||||||
if (_title == title || (isGeneral() && !_title.isEmpty())) {
|
if (_title == title || (isGeneral() && !_title.isEmpty())) {
|
||||||
return;
|
return;
|
||||||
|
@ -252,6 +265,15 @@ void ForumTopic::applyTitle(const QString &title) {
|
||||||
updateChatListEntry();
|
updateChatListEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DocumentId ForumTopic::iconId() const {
|
||||||
|
return _iconId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForumTopic::applyIconId(DocumentId iconId) {
|
||||||
|
_iconId = iconId;
|
||||||
|
updateChatListEntry();
|
||||||
|
}
|
||||||
|
|
||||||
void ForumTopic::applyItemAdded(not_null<HistoryItem*> item) {
|
void ForumTopic::applyItemAdded(not_null<HistoryItem*> item) {
|
||||||
setLastMessage(item);
|
setLastMessage(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
ForumTopic(const ForumTopic &) = delete;
|
ForumTopic(const ForumTopic &) = delete;
|
||||||
ForumTopic &operator=(const ForumTopic &) = delete;
|
ForumTopic &operator=(const ForumTopic &) = delete;
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<ChannelData*> channel() const;
|
||||||
[[nodiscard]] not_null<History*> forum() const;
|
[[nodiscard]] not_null<History*> forum() const;
|
||||||
[[nodiscard]] MsgId rootId() const;
|
[[nodiscard]] MsgId rootId() const;
|
||||||
[[nodiscard]] bool isGeneral() const {
|
[[nodiscard]] bool isGeneral() const {
|
||||||
|
@ -62,7 +63,10 @@ public:
|
||||||
[[nodiscard]] bool lastMessageKnown() const;
|
[[nodiscard]] bool lastMessageKnown() const;
|
||||||
[[nodiscard]] bool lastServerMessageKnown() const;
|
[[nodiscard]] bool lastServerMessageKnown() const;
|
||||||
|
|
||||||
|
[[nodiscard]] QString title() const;
|
||||||
void applyTitle(const QString &title);
|
void applyTitle(const QString &title);
|
||||||
|
[[nodiscard]] DocumentId iconId() const;
|
||||||
|
void applyIconId(DocumentId iconId);
|
||||||
void applyItemAdded(not_null<HistoryItem*> item);
|
void applyItemAdded(not_null<HistoryItem*> item);
|
||||||
void applyItemRemoved(MsgId id);
|
void applyItemRemoved(MsgId id);
|
||||||
|
|
||||||
|
@ -108,6 +112,7 @@ private:
|
||||||
const MsgId _rootId = 0;
|
const MsgId _rootId = 0;
|
||||||
|
|
||||||
QString _title;
|
QString _title;
|
||||||
|
DocumentId _iconId = 0;
|
||||||
base::flat_set<QString> _titleWords;
|
base::flat_set<QString> _titleWords;
|
||||||
base::flat_set<QChar> _titleFirstLetters;
|
base::flat_set<QChar> _titleFirstLetters;
|
||||||
int _titleVersion = 0;
|
int _titleVersion = 0;
|
||||||
|
|
|
@ -54,6 +54,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
#include "boxes/filters/edit_filter_box.h"
|
#include "boxes/filters/edit_filter_box.h"
|
||||||
|
#include "boxes/peers/edit_forum_topic_box.h"
|
||||||
#include "api/api_chat_filters.h"
|
#include "api/api_chat_filters.h"
|
||||||
#include "base/qt/qt_common_adapters.h"
|
#include "base/qt/qt_common_adapters.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
@ -2411,7 +2412,8 @@ void InnerWidget::refreshEmptyLabel() {
|
||||||
} else if (_emptyState == EmptyState::EmptyFolder) {
|
} else if (_emptyState == EmptyState::EmptyFolder) {
|
||||||
editOpenedFilter();
|
editOpenedFilter();
|
||||||
} else if (_emptyState == EmptyState::EmptyForum) {
|
} else if (_emptyState == EmptyState::EmptyForum) {
|
||||||
Data::ShowAddForumTopic(_controller, _openedForum->channel());
|
_controller->show(
|
||||||
|
Box(NewForumTopicBox, _controller, _openedForum->history()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_empty->setVisible(_state == WidgetState::Default);
|
_empty->setVisible(_state == WidgetState::Default);
|
||||||
|
@ -3287,9 +3289,10 @@ void InnerWidget::setupShortcuts() {
|
||||||
});
|
});
|
||||||
request->check(Command::ChatSelf) && request->handle([=] {
|
request->check(Command::ChatSelf) && request->handle([=] {
|
||||||
if (_openedForum) {
|
if (_openedForum) {
|
||||||
Data::ShowAddForumTopic(
|
_controller->show(Box(
|
||||||
|
NewForumTopicBox,
|
||||||
_controller,
|
_controller,
|
||||||
_openedForum->channel());
|
_openedForum->history()));
|
||||||
} else {
|
} else {
|
||||||
_controller->content()->choosePeer(
|
_controller->content()->choosePeer(
|
||||||
session().userPeerId(),
|
session().userPeerId(),
|
||||||
|
|
|
@ -55,8 +55,17 @@ ForumTopic *Key::topic() const {
|
||||||
return _value ? _value->asTopic() : nullptr;
|
return _value ? _value->asTopic() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
History *Key::parentHistory() const {
|
||||||
|
if (const auto result = history()) {
|
||||||
|
return result;
|
||||||
|
} else if (const auto child = topic()) {
|
||||||
|
return child->forum();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *Key::peer() const {
|
PeerData *Key::peer() const {
|
||||||
if (const auto history = this->history()) {
|
if (const auto history = parentHistory()) {
|
||||||
return history->peer;
|
return history->peer;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
History *history() const;
|
History *history() const;
|
||||||
Data::Folder *folder() const;
|
Data::Folder *folder() const;
|
||||||
Data::ForumTopic *topic() const;
|
Data::ForumTopic *topic() const;
|
||||||
|
History *parentHistory() const;
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
|
|
||||||
inline bool operator<(const Key &other) const {
|
inline bool operator<(const Key &other) const {
|
||||||
|
|
|
@ -386,7 +386,9 @@ void Widget::chosenRow(const ChosenRow &row) {
|
||||||
if (const auto topic = row.key.topic()) {
|
if (const auto topic = row.key.topic()) {
|
||||||
controller()->showRepliesForMessage(
|
controller()->showRepliesForMessage(
|
||||||
topic->forum(),
|
topic->forum(),
|
||||||
topic->rootId());
|
topic->rootId(),
|
||||||
|
ShowAtUnreadMsgId,
|
||||||
|
Window::SectionShow::Way::ClearStack);
|
||||||
} else if (history && history->peer->isForum()) {
|
} else if (history && history->peer->isForum()) {
|
||||||
controller()->openForum(history->peer->asChannel());
|
controller()->openForum(history->peer->asChannel());
|
||||||
} else if (history) {
|
} else if (history) {
|
||||||
|
|
|
@ -453,7 +453,9 @@ Data::ForumTopic *RepliesWidget::lookupTopic() {
|
||||||
).done([=](const MTPmessages_ForumTopics &result) {
|
).done([=](const MTPmessages_ForumTopics &result) {
|
||||||
if (const auto forum = _history->peer->forum()) {
|
if (const auto forum = _history->peer->forum()) {
|
||||||
forum->applyReceivedTopics(result);
|
forum->applyReceivedTopics(result);
|
||||||
_topic = forum->topicFor(_rootId);
|
if ((_topic = forum->topicFor(_rootId))) {
|
||||||
|
refreshTopBarActiveChat();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_resolveTopicRequestId = 0;
|
_resolveTopicRequestId = 0;
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
|
@ -1310,9 +1312,10 @@ SendMenu::Type RepliesWidget::sendMenuType() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::refreshTopBarActiveChat() {
|
void RepliesWidget::refreshTopBarActiveChat() {
|
||||||
const auto state = Dialogs::EntryState{
|
using namespace Dialogs;
|
||||||
.key = _history,
|
const auto state = EntryState{
|
||||||
.section = Dialogs::EntryState::Section::Replies,
|
.key = (_topic ? Key{ _topic } : Key{ _history }),
|
||||||
|
.section = EntryState::Section::Replies,
|
||||||
.rootId = _rootId,
|
.rootId = _rootId,
|
||||||
.currentReplyToId = _composeControls->replyingToMessage().msg,
|
.currentReplyToId = _composeControls->replyingToMessage().msg,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "history/view/history_view_top_bar_widget.h"
|
#include "history/view/history_view_top_bar_widget.h"
|
||||||
|
|
||||||
#include <rpl/combine.h>
|
|
||||||
#include <rpl/combine_previous.h>
|
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/view/history_view_send_action.h"
|
#include "history/view/history_view_send_action.h"
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
|
@ -48,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_send_action.h"
|
#include "data/data_send_action.h"
|
||||||
#include "chat_helpers/emoji_interactions.h"
|
#include "chat_helpers/emoji_interactions.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
@ -474,7 +473,27 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
const auto history = _activeChat.key.history();
|
const auto history = _activeChat.key.history();
|
||||||
const auto folder = _activeChat.key.folder();
|
const auto folder = _activeChat.key.folder();
|
||||||
if (folder
|
if (const auto topic = _activeChat.key.topic()) {
|
||||||
|
p.setPen(st::dialogsNameFg);
|
||||||
|
topic->chatListNameText().drawElided(
|
||||||
|
p,
|
||||||
|
nameleft,
|
||||||
|
nametop,
|
||||||
|
availableWidth);
|
||||||
|
|
||||||
|
p.setFont(st::dialogsTextFont);
|
||||||
|
if (!paintConnectingState(p, nameleft, statustop, width())
|
||||||
|
&& !paintSendAction(
|
||||||
|
p,
|
||||||
|
nameleft,
|
||||||
|
statustop,
|
||||||
|
availableWidth,
|
||||||
|
width(),
|
||||||
|
st::historyStatusFgTyping,
|
||||||
|
now)) {
|
||||||
|
paintStatus(p, nameleft, statustop, availableWidth, width());
|
||||||
|
}
|
||||||
|
} else if (folder
|
||||||
|| history->peer->sharedMediaInfo()
|
|| history->peer->sharedMediaInfo()
|
||||||
|| (_activeChat.section == Section::Scheduled)
|
|| (_activeChat.section == Section::Scheduled)
|
||||||
|| (_activeChat.section == Section::Pinned)
|
|| (_activeChat.section == Section::Pinned)
|
||||||
|
@ -673,6 +692,8 @@ void TopBarWidget::infoClicked() {
|
||||||
return;
|
return;
|
||||||
} else if (key.folder()) {
|
} else if (key.folder()) {
|
||||||
_controller->closeFolder();
|
_controller->closeFolder();
|
||||||
|
} else if (const auto topic = key.topic()) {
|
||||||
|
_controller->showSection(std::make_shared<Info::Memento>(topic));
|
||||||
} else if (key.peer()->isSelf()) {
|
} else if (key.peer()->isSelf()) {
|
||||||
_controller->showSection(std::make_shared<Info::Memento>(
|
_controller->showSection(std::make_shared<Info::Memento>(
|
||||||
key.peer(),
|
key.peer(),
|
||||||
|
@ -706,6 +727,8 @@ void TopBarWidget::setActiveChat(
|
||||||
_activeChat = activeChat;
|
_activeChat = activeChat;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto topicChanged = (_activeChat.key.topic()
|
||||||
|
!= activeChat.key.topic());
|
||||||
const auto peerChanged = (_activeChat.key.history()
|
const auto peerChanged = (_activeChat.key.history()
|
||||||
!= activeChat.key.history());
|
!= activeChat.key.history());
|
||||||
|
|
||||||
|
@ -715,12 +738,12 @@ void TopBarWidget::setActiveChat(
|
||||||
_back->clearState();
|
_back->clearState();
|
||||||
update();
|
update();
|
||||||
|
|
||||||
if (peerChanged) {
|
if (peerChanged || topicChanged) {
|
||||||
_titleBadge.unload();
|
_titleBadge.unload();
|
||||||
_titleNameVersion = 0;
|
_titleNameVersion = 0;
|
||||||
_emojiInteractionSeen = nullptr;
|
_emojiInteractionSeen = nullptr;
|
||||||
_activeChatLifetime.destroy();
|
_activeChatLifetime.destroy();
|
||||||
if (const auto history = _activeChat.key.history()) {
|
if (const auto history = _activeChat.key.parentHistory()) {
|
||||||
session().changes().peerFlagsValue(
|
session().changes().peerFlagsValue(
|
||||||
history->peer,
|
history->peer,
|
||||||
Data::PeerUpdate::Flag::GroupCall
|
Data::PeerUpdate::Flag::GroupCall
|
||||||
|
@ -737,7 +760,9 @@ void TopBarWidget::setActiveChat(
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}, _activeChatLifetime);
|
}, _activeChatLifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto history = _activeChat.key.history()) {
|
||||||
using InteractionSeen = ChatHelpers::EmojiInteractionSeen;
|
using InteractionSeen = ChatHelpers::EmojiInteractionSeen;
|
||||||
_controller->emojiInteractions().seen(
|
_controller->emojiInteractions().seen(
|
||||||
) | rpl::filter([=](const InteractionSeen &seen) {
|
) | rpl::filter([=](const InteractionSeen &seen) {
|
||||||
|
|
|
@ -7,9 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
|
||||||
#include <rpl/never.h>
|
|
||||||
#include <rpl/combine.h>
|
|
||||||
#include <rpl/range.h>
|
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
@ -23,7 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "info/info_section_widget.h"
|
#include "info/info_section_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
|
#include "data/data_chat.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "history/history.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_profile.h"
|
#include "styles/style_profile.h"
|
||||||
|
@ -323,7 +323,9 @@ rpl::producer<bool> ContentWidget::desiredBottomShadowVisibility() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Key ContentMemento::key() const {
|
Key ContentMemento::key() const {
|
||||||
if (const auto peer = this->peer()) {
|
if (const auto topic = this->topic()) {
|
||||||
|
return Key(topic);
|
||||||
|
} else if (const auto peer = this->peer()) {
|
||||||
return Key(peer);
|
return Key(peer);
|
||||||
} else if (const auto poll = this->poll()) {
|
} else if (const auto poll = this->poll()) {
|
||||||
return Key(poll, pollContextId());
|
return Key(poll, pollContextId());
|
||||||
|
@ -334,6 +336,12 @@ Key ContentMemento::key() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContentMemento::ContentMemento(not_null<Data::ForumTopic*> topic)
|
||||||
|
: _peer(topic->forum()->peer)
|
||||||
|
, _migratedPeerId(_peer->migrateFrom() ? _peer->migrateFrom()->id : 0)
|
||||||
|
, _topic(topic) {
|
||||||
|
}
|
||||||
|
|
||||||
ContentMemento::ContentMemento(Settings::Tag settings)
|
ContentMemento::ContentMemento(Settings::Tag settings)
|
||||||
: _settingsSelf(settings.self.get()) {
|
: _settingsSelf(settings.self.get()) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ public:
|
||||||
: _peer(peer)
|
: _peer(peer)
|
||||||
, _migratedPeerId(migratedPeerId) {
|
, _migratedPeerId(migratedPeerId) {
|
||||||
}
|
}
|
||||||
|
explicit ContentMemento(not_null<Data::ForumTopic*> topic);
|
||||||
explicit ContentMemento(Settings::Tag settings);
|
explicit ContentMemento(Settings::Tag settings);
|
||||||
explicit ContentMemento(Downloads::Tag downloads);
|
explicit ContentMemento(Downloads::Tag downloads);
|
||||||
ContentMemento(not_null<PollData*> poll, FullMsgId contextId)
|
ContentMemento(not_null<PollData*> poll, FullMsgId contextId)
|
||||||
|
@ -166,6 +167,9 @@ public:
|
||||||
PeerId migratedPeerId() const {
|
PeerId migratedPeerId() const {
|
||||||
return _migratedPeerId;
|
return _migratedPeerId;
|
||||||
}
|
}
|
||||||
|
Data::ForumTopic *topic() const {
|
||||||
|
return _topic;
|
||||||
|
}
|
||||||
UserData *settingsSelf() const {
|
UserData *settingsSelf() const {
|
||||||
return _settingsSelf;
|
return _settingsSelf;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +213,7 @@ public:
|
||||||
private:
|
private:
|
||||||
PeerData * const _peer = nullptr;
|
PeerData * const _peer = nullptr;
|
||||||
const PeerId _migratedPeerId = 0;
|
const PeerId _migratedPeerId = 0;
|
||||||
|
Data::ForumTopic * const _topic = nullptr;
|
||||||
UserData * const _settingsSelf = nullptr;
|
UserData * const _settingsSelf = nullptr;
|
||||||
PollData * const _poll = nullptr;
|
PollData * const _poll = nullptr;
|
||||||
const FullMsgId _pollContextId;
|
const FullMsgId _pollContextId;
|
||||||
|
|
|
@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
#include <rpl/range.h>
|
|
||||||
#include <rpl/then.h>
|
|
||||||
#include "ui/search_field_controller.h"
|
#include "ui/search_field_controller.h"
|
||||||
#include "data/data_shared_media.h"
|
#include "data/data_shared_media.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
@ -19,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "data/data_download_manager.h"
|
#include "data/data_download_manager.h"
|
||||||
|
@ -32,6 +31,9 @@ namespace Info {
|
||||||
Key::Key(not_null<PeerData*> peer) : _value(peer) {
|
Key::Key(not_null<PeerData*> peer) : _value(peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Key::Key(not_null<Data::ForumTopic*> topic) : _value(topic) {
|
||||||
|
}
|
||||||
|
|
||||||
Key::Key(Settings::Tag settings) : _value(settings) {
|
Key::Key(Settings::Tag settings) : _value(settings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +47,16 @@ Key::Key(not_null<PollData*> poll, FullMsgId contextId)
|
||||||
PeerData *Key::peer() const {
|
PeerData *Key::peer() const {
|
||||||
if (const auto peer = std::get_if<not_null<PeerData*>>(&_value)) {
|
if (const auto peer = std::get_if<not_null<PeerData*>>(&_value)) {
|
||||||
return *peer;
|
return *peer;
|
||||||
|
} else if (const auto topic = this->topic()) {
|
||||||
|
return topic->forum()->peer;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data::ForumTopic *Key::topic() const {
|
||||||
|
if (const auto topic = std::get_if<not_null<Data::ForumTopic*>>(
|
||||||
|
&_value)) {
|
||||||
|
return *topic;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rpl/variable.h>
|
|
||||||
#include "data/data_search_controller.h"
|
#include "data/data_search_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class SearchFieldController;
|
class SearchFieldController;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Info {
|
namespace Info::Settings {
|
||||||
namespace Settings {
|
|
||||||
|
|
||||||
struct Tag {
|
struct Tag {
|
||||||
explicit Tag(not_null<UserData*> self) : self(self) {
|
explicit Tag(not_null<UserData*> self) : self(self) {
|
||||||
|
@ -25,23 +27,27 @@ struct Tag {
|
||||||
not_null<UserData*> self;
|
not_null<UserData*> self;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Info::Settings
|
||||||
|
|
||||||
namespace Downloads {
|
namespace Info::Downloads {
|
||||||
|
|
||||||
struct Tag {
|
struct Tag {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Downloads
|
} // namespace Info::Downloads
|
||||||
|
|
||||||
|
namespace Info {
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
public:
|
public:
|
||||||
Key(not_null<PeerData*> peer);
|
explicit Key(not_null<PeerData*> peer);
|
||||||
|
explicit Key(not_null<Data::ForumTopic*> topic);
|
||||||
Key(Settings::Tag settings);
|
Key(Settings::Tag settings);
|
||||||
Key(Downloads::Tag downloads);
|
Key(Downloads::Tag downloads);
|
||||||
Key(not_null<PollData*> poll, FullMsgId contextId);
|
Key(not_null<PollData*> poll, FullMsgId contextId);
|
||||||
|
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
|
Data::ForumTopic *topic() const;
|
||||||
UserData *settingsSelf() const;
|
UserData *settingsSelf() const;
|
||||||
bool isDownloads() const;
|
bool isDownloads() const;
|
||||||
PollData *poll() const;
|
PollData *poll() const;
|
||||||
|
@ -54,6 +60,7 @@ private:
|
||||||
};
|
};
|
||||||
std::variant<
|
std::variant<
|
||||||
not_null<PeerData*>,
|
not_null<PeerData*>,
|
||||||
|
not_null<Data::ForumTopic*>,
|
||||||
Settings::Tag,
|
Settings::Tag,
|
||||||
Downloads::Tag,
|
Downloads::Tag,
|
||||||
PollKey> _value;
|
PollKey> _value;
|
||||||
|
|
|
@ -33,6 +33,14 @@ Memento::Memento(not_null<PeerData*> peer, Section section)
|
||||||
: Memento(DefaultStack(peer, section)) {
|
: Memento(DefaultStack(peer, section)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::ForumTopic*> topic)
|
||||||
|
: Memento(topic, Section::Type::Profile) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::ForumTopic*> topic, Section section)
|
||||||
|
: Memento(DefaultStack(topic, section)) {
|
||||||
|
}
|
||||||
|
|
||||||
Memento::Memento(Settings::Tag settings, Section section)
|
Memento::Memento(Settings::Tag settings, Section section)
|
||||||
: Memento(DefaultStack(settings, section)) {
|
: Memento(DefaultStack(settings, section)) {
|
||||||
}
|
}
|
||||||
|
@ -53,6 +61,14 @@ std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
|
not_null<Data::ForumTopic*> topic,
|
||||||
|
Section section) {
|
||||||
|
auto result = std::vector<std::shared_ptr<ContentMemento>>();
|
||||||
|
result.push_back(DefaultContent(topic, section));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
Settings::Tag settings,
|
Settings::Tag settings,
|
||||||
Section section) {
|
Section section) {
|
||||||
|
@ -111,6 +127,18 @@ std::shared_ptr<ContentMemento> Memento::DefaultContent(
|
||||||
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ContentMemento> Memento::DefaultContent(
|
||||||
|
not_null<Data::ForumTopic*> topic,
|
||||||
|
Section section) {
|
||||||
|
switch (section.type()) {
|
||||||
|
case Section::Type::Profile:
|
||||||
|
return std::make_shared<Profile::Memento>(topic);
|
||||||
|
case Section::Type::Media:
|
||||||
|
return std::make_shared<Media::Memento>(topic, section.mediaType());
|
||||||
|
}
|
||||||
|
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<Window::SectionWidget> Memento::createWidget(
|
object_ptr<Window::SectionWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
|
|
|
@ -17,6 +17,10 @@ namespace Storage {
|
||||||
enum class SharedMediaType : signed char;
|
enum class SharedMediaType : signed char;
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ScrollArea;
|
class ScrollArea;
|
||||||
struct ScrollToRequest;
|
struct ScrollToRequest;
|
||||||
|
@ -38,6 +42,8 @@ class Memento final : public Window::SectionMemento {
|
||||||
public:
|
public:
|
||||||
explicit Memento(not_null<PeerData*> peer);
|
explicit Memento(not_null<PeerData*> peer);
|
||||||
Memento(not_null<PeerData*> peer, Section section);
|
Memento(not_null<PeerData*> peer, Section section);
|
||||||
|
explicit Memento(not_null<Data::ForumTopic*> topic);
|
||||||
|
Memento(not_null<Data::ForumTopic*> topic, Section section);
|
||||||
Memento(Settings::Tag settings, Section section);
|
Memento(Settings::Tag settings, Section section);
|
||||||
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
||||||
explicit Memento(std::vector<std::shared_ptr<ContentMemento>> stack);
|
explicit Memento(std::vector<std::shared_ptr<ContentMemento>> stack);
|
||||||
|
@ -72,6 +78,9 @@ private:
|
||||||
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Section section);
|
Section section);
|
||||||
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
|
not_null<Data::ForumTopic*> topic,
|
||||||
|
Section section);
|
||||||
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
Settings::Tag settings,
|
Settings::Tag settings,
|
||||||
Section section);
|
Section section);
|
||||||
|
@ -82,6 +91,9 @@ private:
|
||||||
static std::shared_ptr<ContentMemento> DefaultContent(
|
static std::shared_ptr<ContentMemento> DefaultContent(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Section section);
|
Section section);
|
||||||
|
static std::shared_ptr<ContentMemento> DefaultContent(
|
||||||
|
not_null<Data::ForumTopic*> topic,
|
||||||
|
Section section);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ContentMemento>> _stack;
|
std::vector<std::shared_ptr<ContentMemento>> _stack;
|
||||||
|
|
||||||
|
|
|
@ -541,10 +541,13 @@ void WrapWidget::showTopBarMenu(bool check) {
|
||||||
[=] { deleteAllDownloads(); },
|
[=] { deleteAllDownloads(); },
|
||||||
&st::menuIconDelete);
|
&st::menuIconDelete);
|
||||||
} else if (const auto peer = key().peer()) {
|
} else if (const auto peer = key().peer()) {
|
||||||
|
const auto topic = key().topic();
|
||||||
Window::FillDialogsEntryMenu(
|
Window::FillDialogsEntryMenu(
|
||||||
_controller->parentController(),
|
_controller->parentController(),
|
||||||
Dialogs::EntryState{
|
Dialogs::EntryState{
|
||||||
.key = peer->owner().history(peer),
|
.key = (topic
|
||||||
|
? Dialogs::Key{ topic }
|
||||||
|
: Dialogs::Key{ peer->owner().history(peer) }),
|
||||||
.section = Dialogs::EntryState::Section::Profile,
|
.section = Dialogs::EntryState::Section::Profile,
|
||||||
},
|
},
|
||||||
addAction);
|
addAction);
|
||||||
|
|
|
@ -18,8 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info::Media {
|
||||||
namespace Media {
|
|
||||||
|
|
||||||
std::optional<int> TypeToTabIndex(Type type) {
|
std::optional<int> TypeToTabIndex(Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -61,6 +60,17 @@ Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::ForumTopic*> topic, Type type)
|
||||||
|
: ContentMemento(topic)
|
||||||
|
, _type(type) {
|
||||||
|
_searchState.query.type = type; // #TODO forum search
|
||||||
|
_searchState.query.peerId = peer()->id;
|
||||||
|
_searchState.query.migratedPeerId = migratedPeerId();
|
||||||
|
if (migratedPeerId()) {
|
||||||
|
_searchState.migratedList = Storage::SparseIdsList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
return Section(_type);
|
return Section(_type);
|
||||||
}
|
}
|
||||||
|
@ -162,5 +172,4 @@ void Widget::restoreState(not_null<Memento*> memento) {
|
||||||
_inner->restoreState(memento);
|
_inner->restoreState(memento);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Media
|
} // namespace Info::Media
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -7,13 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rpl/producer.h>
|
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "data/data_search_controller.h"
|
#include "data/data_search_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Data {
|
||||||
namespace Media {
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Info::Media {
|
||||||
|
|
||||||
using Type = Storage::SharedMediaType;
|
using Type = Storage::SharedMediaType;
|
||||||
|
|
||||||
|
@ -24,8 +26,9 @@ class InnerWidget;
|
||||||
|
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
Memento(not_null<Controller*> controller);
|
explicit Memento(not_null<Controller*> controller);
|
||||||
Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type);
|
Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type);
|
||||||
|
Memento(not_null<Data::ForumTopic*> peer, Type type);
|
||||||
|
|
||||||
using SearchState = Api::DelayedSearchController::SavedState;
|
using SearchState = Api::DelayedSearchController::SavedState;
|
||||||
|
|
||||||
|
@ -120,5 +123,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Media
|
} // namespace Info::Media
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -70,11 +70,7 @@ Cover::Cover(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Cover(parent, peer, controller, NameValue(
|
: Cover(parent, peer, controller, NameValue(peer)) {
|
||||||
peer
|
|
||||||
) | rpl::map([=](const TextWithEntities &name) {
|
|
||||||
return name.text;
|
|
||||||
})) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cover::Cover(
|
Cover::Cover(
|
||||||
|
|
|
@ -171,6 +171,14 @@ EmojiStatusPanel::EmojiStatusPanel() = default;
|
||||||
|
|
||||||
EmojiStatusPanel::~EmojiStatusPanel() = default;
|
EmojiStatusPanel::~EmojiStatusPanel() = default;
|
||||||
|
|
||||||
|
void EmojiStatusPanel::setChooseFilter(Fn<bool(DocumentId)> filter) {
|
||||||
|
_chooseFilter = std::move(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiStatusPanel::setChooseCallback(Fn<void(DocumentId)> callback) {
|
||||||
|
_chooseCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiStatusPanel::show(
|
void EmojiStatusPanel::show(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<QWidget*> button,
|
not_null<QWidget*> button,
|
||||||
|
@ -278,32 +286,48 @@ void EmojiStatusPanel::create(
|
||||||
return Chosen{ .animation = data.messageSendingFrom };
|
return Chosen{ .animation = data.messageSendingFrom };
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto set = [=](Chosen chosen) {
|
const auto accept = [=](Chosen chosen) {
|
||||||
Expects(chosen.until != Selector::kPickCustomTimeId);
|
Expects(chosen.until != Selector::kPickCustomTimeId);
|
||||||
|
|
||||||
const auto owner = &controller->session().data();
|
const auto owner = &controller->session().data();
|
||||||
startAnimation(owner, body, chosen.id, chosen.animation);
|
startAnimation(owner, body, chosen.id, chosen.animation);
|
||||||
owner->emojiStatuses().set(chosen.id, chosen.until);
|
if (_chooseCallback) {
|
||||||
|
_chooseCallback(chosen.id);
|
||||||
|
} else {
|
||||||
|
owner->emojiStatuses().set(chosen.id, chosen.until);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
std::move(statusChosen),
|
std::move(statusChosen),
|
||||||
std::move(emojiChosen)
|
std::move(emojiChosen)
|
||||||
) | rpl::start_with_next([=](const Chosen chosen) {
|
) | rpl::filter([=](const Chosen &chosen) {
|
||||||
if (chosen.id && !controller->session().premium()) {
|
return filter(controller, chosen.id);
|
||||||
ShowPremiumPreviewBox(controller, PremiumPreview::EmojiStatus);
|
}) | rpl::start_with_next([=](const Chosen &chosen) {
|
||||||
} else if (chosen.until == Selector::kPickCustomTimeId) {
|
if (chosen.until == Selector::kPickCustomTimeId) {
|
||||||
_panel->hideAnimated();
|
_panel->hideAnimated();
|
||||||
controller->show(Box(PickUntilBox, [=](TimeId seconds) {
|
controller->show(Box(PickUntilBox, [=](TimeId seconds) {
|
||||||
set({ chosen.id, base::unixtime::now() + seconds });
|
accept({ chosen.id, base::unixtime::now() + seconds });
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
set(chosen);
|
accept(chosen);
|
||||||
_panel->hideAnimated();
|
_panel->hideAnimated();
|
||||||
}
|
}
|
||||||
}, _panel->lifetime());
|
}, _panel->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EmojiStatusPanel::filter(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
DocumentId chosenId) const {
|
||||||
|
if (_chooseFilter) {
|
||||||
|
return _chooseFilter(chosenId);
|
||||||
|
} else if (chosenId && !controller->session().premium()) {
|
||||||
|
ShowPremiumPreviewBox(controller, PremiumPreview::EmojiStatus);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiStatusPanel::startAnimation(
|
void EmojiStatusPanel::startAnimation(
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
not_null<Ui::RpWidget*> body,
|
not_null<Ui::RpWidget*> body,
|
||||||
|
|
|
@ -39,6 +39,9 @@ public:
|
||||||
EmojiStatusPanel();
|
EmojiStatusPanel();
|
||||||
~EmojiStatusPanel();
|
~EmojiStatusPanel();
|
||||||
|
|
||||||
|
void setChooseFilter(Fn<bool(DocumentId)> filter);
|
||||||
|
void setChooseCallback(Fn<void(DocumentId)> callback);
|
||||||
|
|
||||||
void show(
|
void show(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<QWidget*> button,
|
not_null<QWidget*> button,
|
||||||
|
@ -50,6 +53,9 @@ private:
|
||||||
class Animation;
|
class Animation;
|
||||||
|
|
||||||
void create(not_null<Window::SessionController*> controller);
|
void create(not_null<Window::SessionController*> controller);
|
||||||
|
[[nodiscard]] bool filter(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
DocumentId chosenId) const;
|
||||||
|
|
||||||
void startAnimation(
|
void startAnimation(
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
|
@ -58,6 +64,8 @@ private:
|
||||||
Ui::MessageSendingAnimationFrom from);
|
Ui::MessageSendingAnimationFrom from);
|
||||||
|
|
||||||
base::unique_qptr<ChatHelpers::TabbedPanel> _panel;
|
base::unique_qptr<ChatHelpers::TabbedPanel> _panel;
|
||||||
|
Fn<bool(DocumentId)> _chooseFilter;
|
||||||
|
Fn<void(DocumentId)> _chooseCallback;
|
||||||
QPointer<QWidget> _panelButton;
|
QPointer<QWidget> _panelButton;
|
||||||
std::unique_ptr<Animation> _animation;
|
std::unique_ptr<Animation> _animation;
|
||||||
Data::CustomEmojiSizeTag _animationSizeTag = {};
|
Data::CustomEmojiSizeTag _animationSizeTag = {};
|
||||||
|
|
|
@ -51,6 +51,7 @@ InnerWidget::InnerWidget(
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(_controller->key().peer())
|
, _peer(_controller->key().peer())
|
||||||
, _migrated(_controller->migrated())
|
, _migrated(_controller->migrated())
|
||||||
|
, _topic(_controller->key().topic())
|
||||||
, _content(setupContent(this)) {
|
, _content(setupContent(this)) {
|
||||||
_content->heightValue(
|
_content->heightValue(
|
||||||
) | rpl::start_with_next([this](int height) {
|
) | rpl::start_with_next([this](int height) {
|
||||||
|
@ -67,15 +68,21 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||||
_cover = result->add(object_ptr<Cover>(
|
_cover = result->add(object_ptr<Cover>(
|
||||||
result,
|
result,
|
||||||
_peer,
|
_peer,
|
||||||
_controller->parentController()));
|
_controller->parentController(),
|
||||||
|
_topic ? TitleValue(_topic) : NameValue(_peer)));
|
||||||
_cover->showSection(
|
_cover->showSection(
|
||||||
) | rpl::start_with_next([=](Section section) {
|
) | rpl::start_with_next([=](Section section) {
|
||||||
_controller->showSection(
|
_controller->showSection(
|
||||||
std::make_shared<Info::Memento>(_peer, section));
|
std::make_shared<Info::Memento>(_peer, section));
|
||||||
}, _cover->lifetime());
|
}, _cover->lifetime());
|
||||||
_cover->setOnlineCount(rpl::single(0));
|
_cover->setOnlineCount(rpl::single(0));
|
||||||
auto details = SetupDetails(_controller, parent, _peer);
|
if (_topic) {
|
||||||
result->add(std::move(details));
|
// #TODO forum
|
||||||
|
//result->add(setupSharedMedia(result.data()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->add(SetupDetails(_controller, parent, _peer));
|
||||||
result->add(setupSharedMedia(result.data()));
|
result->add(setupSharedMedia(result.data()));
|
||||||
if (auto members = SetupChannelMembers(_controller, result.data(), _peer)) {
|
if (auto members = SetupChannelMembers(_controller, result.data(), _peer)) {
|
||||||
result->add(std::move(members));
|
result->add(std::move(members));
|
||||||
|
|
|
@ -10,7 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
#include <rpl/variable.h>
|
namespace Data {
|
||||||
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
|
@ -65,6 +67,7 @@ private:
|
||||||
const not_null<Controller*> _controller;
|
const not_null<Controller*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
PeerData * const _migrated = nullptr;
|
PeerData * const _migrated = nullptr;
|
||||||
|
Data::ForumTopic * const _topic = nullptr;
|
||||||
|
|
||||||
Members *_members = nullptr;
|
Members *_members = nullptr;
|
||||||
Cover *_cover = nullptr;
|
Cover *_cover = nullptr;
|
||||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_premium_limits.h"
|
#include "data/data_premium_limits.h"
|
||||||
#include "boxes/peers/edit_peer_permissions_box.h"
|
#include "boxes/peers/edit_peer_permissions_box.h"
|
||||||
|
@ -74,13 +75,15 @@ void StripExternalLinks(TextWithEntities &text) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
|
rpl::producer<QString> NameValue(not_null<PeerData*> peer) {
|
||||||
return peer->session().changes().peerFlagsValue(
|
return peer->session().changes().peerFlagsValue(
|
||||||
peer,
|
peer,
|
||||||
UpdateFlag::Name
|
UpdateFlag::Name
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] { return peer->name(); });
|
||||||
return peer->name();
|
}
|
||||||
}) | Ui::Text::ToWithEntities();
|
|
||||||
|
rpl::producer<QString> TitleValue(not_null<Data::ForumTopic*> topic) {
|
||||||
|
return rpl::single(topic->title()); // #TODO forum title changes
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
|
||||||
|
|
|
@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
struct ChannelLocation;
|
struct ChannelLocation;
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
@ -28,8 +32,7 @@ namespace Storage {
|
||||||
enum class SharedMediaType : signed char;
|
enum class SharedMediaType : signed char;
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
||||||
namespace Info {
|
namespace Info::Profile {
|
||||||
namespace Profile {
|
|
||||||
|
|
||||||
inline auto ToSingleLine() {
|
inline auto ToSingleLine() {
|
||||||
return rpl::map([](const QString &text) {
|
return rpl::map([](const QString &text) {
|
||||||
|
@ -40,8 +43,9 @@ inline auto ToSingleLine() {
|
||||||
rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
|
rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> NameValue(
|
[[nodiscard]] rpl::producer<QString> NameValue(not_null<PeerData*> peer);
|
||||||
not_null<PeerData*> peer);
|
[[nodiscard]] rpl::producer<QString> TitleValue(
|
||||||
|
not_null<Data::ForumTopic*> topic);
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> PhoneValue(
|
[[nodiscard]] rpl::producer<TextWithEntities> PhoneValue(
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> PhoneOrHiddenValue(
|
[[nodiscard]] rpl::producer<TextWithEntities> PhoneOrHiddenValue(
|
||||||
|
@ -95,5 +99,4 @@ enum class BadgeType;
|
||||||
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
} // namespace Profile
|
} // namespace Info::Profile
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info::Profile {
|
||||||
namespace Profile {
|
|
||||||
|
|
||||||
Memento::Memento(not_null<Controller*> controller)
|
Memento::Memento(not_null<Controller*> controller)
|
||||||
: Memento(
|
: Memento(
|
||||||
|
@ -30,6 +29,10 @@ Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
||||||
: ContentMemento(peer, migratedPeerId) {
|
: ContentMemento(peer, migratedPeerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::ForumTopic*> topic)
|
||||||
|
: ContentMemento(topic) {
|
||||||
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
return Section(Section::Type::Profile);
|
return Section(Section::Type::Profile);
|
||||||
}
|
}
|
||||||
|
@ -38,9 +41,7 @@ object_ptr<ContentWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
const QRect &geometry) {
|
const QRect &geometry) {
|
||||||
auto result = object_ptr<Widget>(
|
auto result = object_ptr<Widget>(parent, controller);
|
||||||
parent,
|
|
||||||
controller);
|
|
||||||
result->setInternalState(geometry, this);
|
result->setInternalState(geometry, this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -55,9 +56,7 @@ std::unique_ptr<MembersState> Memento::membersState() {
|
||||||
|
|
||||||
Memento::~Memento() = default;
|
Memento::~Memento() = default;
|
||||||
|
|
||||||
Widget::Widget(
|
Widget::Widget(QWidget *parent, not_null<Controller*> controller)
|
||||||
QWidget *parent,
|
|
||||||
not_null<Controller*> controller)
|
|
||||||
: ContentWidget(parent, controller) {
|
: ContentWidget(parent, controller) {
|
||||||
controller->setSearchEnabledByContent(false);
|
controller->setSearchEnabledByContent(false);
|
||||||
|
|
||||||
|
@ -81,6 +80,9 @@ void Widget::setInnerFocus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> Widget::title() {
|
rpl::producer<QString> Widget::title() {
|
||||||
|
if (const auto topic = controller()->key().topic()) {
|
||||||
|
return rpl::single(u"Topic Info"_q); // #TODO forum lang
|
||||||
|
}
|
||||||
const auto peer = controller()->key().peer();
|
const auto peer = controller()->key().peer();
|
||||||
if (const auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
return (user->isBot() && !user->isSupport())
|
return (user->isBot() && !user->isSupport())
|
||||||
|
@ -132,5 +134,4 @@ void Widget::restoreState(not_null<Memento*> memento) {
|
||||||
scrollTopRestore(memento->scrollTop());
|
scrollTopRestore(memento->scrollTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Profile
|
} // namespace Info::Profile
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -7,19 +7,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rpl/producer.h>
|
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Data {
|
||||||
namespace Profile {
|
class ForumTopic;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Info::Profile {
|
||||||
|
|
||||||
class InnerWidget;
|
class InnerWidget;
|
||||||
struct MembersState;
|
struct MembersState;
|
||||||
|
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
Memento(not_null<Controller*> controller);
|
explicit Memento(not_null<Controller*> controller);
|
||||||
Memento(not_null<PeerData*> peer, PeerId migratedPeerId);
|
Memento(not_null<PeerData*> peer, PeerId migratedPeerId);
|
||||||
|
explicit Memento(not_null<Data::ForumTopic*> topic);
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -40,9 +43,7 @@ private:
|
||||||
|
|
||||||
class Widget final : public ContentWidget {
|
class Widget final : public ContentWidget {
|
||||||
public:
|
public:
|
||||||
Widget(
|
Widget(QWidget *parent, not_null<Controller*> controller);
|
||||||
QWidget *parent,
|
|
||||||
not_null<Controller*> controller);
|
|
||||||
|
|
||||||
bool showInternal(
|
bool showInternal(
|
||||||
not_null<ContentMemento*> memento) override;
|
not_null<ContentMemento*> memento) override;
|
||||||
|
@ -65,5 +66,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Profile
|
} // namespace Info::Profile
|
||||||
} // namespace Info
|
|
||||||
|
|
|
@ -818,11 +818,7 @@ void AttachWebView::show(
|
||||||
}
|
}
|
||||||
Payments::CheckoutProcess::Start(session, slug, reactivate);
|
Payments::CheckoutProcess::Start(session, slug, reactivate);
|
||||||
};
|
};
|
||||||
auto title = Info::Profile::NameValue(
|
auto title = Info::Profile::NameValue(_bot);
|
||||||
_bot
|
|
||||||
) | rpl::map([](const TextWithEntities &value) {
|
|
||||||
return value.text;
|
|
||||||
});
|
|
||||||
ActiveWebViews().emplace(this);
|
ActiveWebViews().emplace(this);
|
||||||
|
|
||||||
using Button = Ui::BotWebView::MenuButton;
|
using Button = Ui::BotWebView::MenuButton;
|
||||||
|
|
|
@ -2409,6 +2409,8 @@ auto MainWidget::thirdSectionForCurrentMainSection(
|
||||||
-> std::shared_ptr<Window::SectionMemento> {
|
-> std::shared_ptr<Window::SectionMemento> {
|
||||||
if (_thirdSectionFromStack) {
|
if (_thirdSectionFromStack) {
|
||||||
return std::move(_thirdSectionFromStack);
|
return std::move(_thirdSectionFromStack);
|
||||||
|
} else if (const auto topic = key.topic()) {
|
||||||
|
return std::make_shared<Info::Memento>(topic);
|
||||||
} else if (const auto peer = key.peer()) {
|
} else if (const auto peer = key.peer()) {
|
||||||
return std::make_shared<Info::Memento>(
|
return std::make_shared<Info::Memento>(
|
||||||
peer,
|
peer,
|
||||||
|
|
|
@ -313,7 +313,7 @@ void SetupPhoto(
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
int max,
|
int max,
|
||||||
int photoWidth,
|
int photoWidth,
|
||||||
const TextWithEntities&,
|
const QString&,
|
||||||
int statusWidth) {
|
int statusWidth) {
|
||||||
photo->moveToLeft(
|
photo->moveToLeft(
|
||||||
(max - photoWidth) / 2,
|
(max - photoWidth) / 2,
|
||||||
|
@ -398,7 +398,7 @@ void SetupRows(
|
||||||
AddRow(
|
AddRow(
|
||||||
container,
|
container,
|
||||||
tr::lng_settings_name_label(),
|
tr::lng_settings_name_label(),
|
||||||
Info::Profile::NameValue(self),
|
Info::Profile::NameValue(self) | Ui::Text::ToWithEntities(),
|
||||||
tr::lng_profile_copy_fullname(tr::now),
|
tr::lng_profile_copy_fullname(tr::now),
|
||||||
[=] { controller->show(Box<EditNameBox>(self)); },
|
[=] { controller->show(Box<EditNameBox>(self)); },
|
||||||
{ &st::settingsIconUser, kIconLightBlue });
|
{ &st::settingsIconUser, kIconLightBlue });
|
||||||
|
|
|
@ -176,8 +176,8 @@ void Cover::setupChildGeometry() {
|
||||||
void Cover::initViewers() {
|
void Cover::initViewers() {
|
||||||
Info::Profile::NameValue(
|
Info::Profile::NameValue(
|
||||||
_user
|
_user
|
||||||
) | rpl::start_with_next([=](const TextWithEntities &value) {
|
) | rpl::start_with_next([=](const QString &name) {
|
||||||
_name->setText(value.text);
|
_name->setText(name);
|
||||||
refreshNameGeometry(width());
|
refreshNameGeometry(width());
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
|
|
@ -671,7 +671,7 @@ TopBarUser::TopBarUser(
|
||||||
Info::Profile::NameValue(peer)
|
Info::Profile::NameValue(peer)
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
DocumentData *document,
|
DocumentData *document,
|
||||||
TextWithEntities name) {
|
const QString &name) {
|
||||||
if (document) {
|
if (document) {
|
||||||
_emojiStatus = std::make_unique<EmojiStatusTopBar>(
|
_emojiStatus = std::make_unique<EmojiStatusTopBar>(
|
||||||
document,
|
document,
|
||||||
|
@ -713,7 +713,7 @@ TopBarUser::TopBarUser(
|
||||||
_emojiStatus = nullptr;
|
_emojiStatus = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTitle(document, name, controller);
|
updateTitle(document, { name }, controller);
|
||||||
updateAbout(document);
|
updateAbout(document);
|
||||||
|
|
||||||
auto event = QResizeEvent(size(), size());
|
auto event = QResizeEvent(size(), size());
|
||||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/report_messages_box.h"
|
#include "boxes/report_messages_box.h"
|
||||||
#include "boxes/peers/add_bot_to_chat_box.h"
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
#include "boxes/peers/add_participants_box.h"
|
#include "boxes/peers/add_participants_box.h"
|
||||||
|
#include "boxes/peers/edit_forum_topic_box.h"
|
||||||
#include "boxes/peers/edit_contact_box.h"
|
#include "boxes/peers/edit_contact_box.h"
|
||||||
#include "ui/boxes/report_box.h"
|
#include "ui/boxes/report_box.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
@ -63,6 +64,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
#include "data/data_histories.h"
|
#include "data/data_histories.h"
|
||||||
|
@ -188,6 +190,7 @@ private:
|
||||||
void addClearHistory();
|
void addClearHistory();
|
||||||
void addDeleteChat();
|
void addDeleteChat();
|
||||||
void addLeaveChat();
|
void addLeaveChat();
|
||||||
|
void addManageTopic();
|
||||||
void addManageChat();
|
void addManageChat();
|
||||||
void addCreatePoll();
|
void addCreatePoll();
|
||||||
void addThemeEdit();
|
void addThemeEdit();
|
||||||
|
@ -207,6 +210,7 @@ private:
|
||||||
not_null<SessionController*> _controller;
|
not_null<SessionController*> _controller;
|
||||||
Dialogs::EntryState _request;
|
Dialogs::EntryState _request;
|
||||||
PeerData *_peer = nullptr;
|
PeerData *_peer = nullptr;
|
||||||
|
Data::ForumTopic *_topic = nullptr;
|
||||||
Data::Folder *_folder = nullptr;
|
Data::Folder *_folder = nullptr;
|
||||||
const PeerMenuCallback &_addAction;
|
const PeerMenuCallback &_addAction;
|
||||||
|
|
||||||
|
@ -326,12 +330,13 @@ Filler::Filler(
|
||||||
: _controller(controller)
|
: _controller(controller)
|
||||||
, _request(request)
|
, _request(request)
|
||||||
, _peer(request.key.peer())
|
, _peer(request.key.peer())
|
||||||
|
, _topic(request.key.topic())
|
||||||
, _folder(request.key.folder())
|
, _folder(request.key.folder())
|
||||||
, _addAction(addAction) {
|
, _addAction(addAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addHidePromotion() {
|
void Filler::addHidePromotion() {
|
||||||
const auto history = _peer->owner().historyLoaded(_peer);
|
const auto history = _request.key.history();
|
||||||
if (!history
|
if (!history
|
||||||
|| !history->useTopPromotion()
|
|| !history->useTopPromotion()
|
||||||
|| history->topPromotionType().isEmpty()) {
|
|| history->topPromotionType().isEmpty()) {
|
||||||
|
@ -346,6 +351,10 @@ void Filler::addHidePromotion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addTogglePin() {
|
void Filler::addTogglePin() {
|
||||||
|
if (!_peer) {
|
||||||
|
// #TODO forum pin
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto controller = _controller;
|
const auto controller = _controller;
|
||||||
const auto filterId = _request.filterId;
|
const auto filterId = _request.filterId;
|
||||||
const auto peer = _peer;
|
const auto peer = _peer;
|
||||||
|
@ -400,11 +409,12 @@ void Filler::addSupportInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addInfo() {
|
void Filler::addInfo() {
|
||||||
if (_peer->isSelf() || _peer->isRepliesChat()) {
|
if (_peer && (_peer->isSelf() || _peer->isRepliesChat())) {
|
||||||
return;
|
return;
|
||||||
} else if (_controller->adaptive().isThreeColumn()) {
|
} else if (_controller->adaptive().isThreeColumn()) {
|
||||||
const auto history = _controller->activeChatCurrent().history();
|
const auto peer = _controller->activeChatCurrent().peer();
|
||||||
if (history && history->peer == _peer) {
|
const auto topic = _controller->activeChatCurrent().topic();
|
||||||
|
if ((peer && peer == _peer) || (topic && topic == _topic)) {
|
||||||
if (Core::App().settings().thirdSectionInfoEnabled()
|
if (Core::App().settings().thirdSectionInfoEnabled()
|
||||||
|| Core::App().settings().tabbedReplacedWithInfo()) {
|
|| Core::App().settings().tabbedReplacedWithInfo()) {
|
||||||
return;
|
return;
|
||||||
|
@ -412,6 +422,7 @@ void Filler::addInfo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto controller = _controller;
|
const auto controller = _controller;
|
||||||
|
const auto id = _topic ? _topic->rootId() : 0;
|
||||||
const auto peer = _peer;
|
const auto peer = _peer;
|
||||||
const auto text = (peer->isChat() || peer->isMegagroup())
|
const auto text = (peer->isChat() || peer->isMegagroup())
|
||||||
? tr::lng_context_view_group(tr::now)
|
? tr::lng_context_view_group(tr::now)
|
||||||
|
@ -468,6 +479,9 @@ void Filler::addToggleUnreadMark() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addToggleArchive() {
|
void Filler::addToggleArchive() {
|
||||||
|
if (!_peer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto peer = _peer;
|
const auto peer = _peer;
|
||||||
const auto history = peer->owner().historyLoaded(peer);
|
const auto history = peer->owner().historyLoaded(peer);
|
||||||
if (history && history->useTopPromotion()) {
|
if (history && history->useTopPromotion()) {
|
||||||
|
@ -533,7 +547,7 @@ void Filler::addDeleteChat() {
|
||||||
|
|
||||||
void Filler::addLeaveChat() {
|
void Filler::addLeaveChat() {
|
||||||
const auto channel = _peer->asChannel();
|
const auto channel = _peer->asChannel();
|
||||||
if (!channel || !channel->amIn()) {
|
if (_topic || !channel || !channel->amIn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_addAction({
|
_addAction({
|
||||||
|
@ -618,7 +632,7 @@ void Filler::addViewDiscussion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addExportChat() {
|
void Filler::addExportChat() {
|
||||||
if (!_peer->canExportChatHistory()) {
|
if (_topic || !_peer->canExportChatHistory()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto peer = _peer;
|
const auto peer = _peer;
|
||||||
|
@ -733,6 +747,19 @@ void Filler::addDeleteContact() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Filler::addManageTopic() {
|
||||||
|
if (!_topic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #TODO forum lang
|
||||||
|
const auto history = _topic->forum();
|
||||||
|
const auto rootId = _topic->rootId();
|
||||||
|
const auto navigation = _controller;
|
||||||
|
_addAction(u"Edit topic"_q, [=] {
|
||||||
|
navigation->show(Box(EditForumTopicBox, navigation, history, rootId));
|
||||||
|
}, &st::menuIconEdit);
|
||||||
|
}
|
||||||
|
|
||||||
void Filler::addManageChat() {
|
void Filler::addManageChat() {
|
||||||
if (!EditPeerInfoBox::Available(_peer)) {
|
if (!EditPeerInfoBox::Available(_peer)) {
|
||||||
return;
|
return;
|
||||||
|
@ -794,6 +821,9 @@ void Filler::addThemeEdit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::addTTLSubmenu(bool addSeparator) {
|
void Filler::addTTLSubmenu(bool addSeparator) {
|
||||||
|
if (_topic) {
|
||||||
|
return; // #TODO later forum
|
||||||
|
}
|
||||||
const auto validator = TTLMenu::TTLValidator(
|
const auto validator = TTLMenu::TTLValidator(
|
||||||
std::make_shared<Window::Show>(_controller),
|
std::make_shared<Window::Show>(_controller),
|
||||||
_peer);
|
_peer);
|
||||||
|
@ -887,6 +917,7 @@ void Filler::fillProfileActions() {
|
||||||
addGiftPremium();
|
addGiftPremium();
|
||||||
addBotToGroup();
|
addBotToGroup();
|
||||||
addNewMembers();
|
addNewMembers();
|
||||||
|
addManageTopic();
|
||||||
addManageChat();
|
addManageChat();
|
||||||
addViewDiscussion();
|
addViewDiscussion();
|
||||||
addExportChat();
|
addExportChat();
|
||||||
|
@ -897,6 +928,11 @@ void Filler::fillProfileActions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filler::fillRepliesActions() {
|
void Filler::fillRepliesActions() {
|
||||||
|
if (_topic) {
|
||||||
|
addInfo();
|
||||||
|
addManageTopic();
|
||||||
|
addManageChat();
|
||||||
|
}
|
||||||
addCreatePoll();
|
addCreatePoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -478,17 +478,6 @@ void SessionNavigation::showRepliesForMessage(
|
||||||
_api.request(base::take(_showingRepliesRequestId)).cancel();
|
_api.request(base::take(_showingRepliesRequestId)).cancel();
|
||||||
|
|
||||||
const auto postPeer = history->peer;
|
const auto postPeer = history->peer;
|
||||||
//const auto item = _session->data().message(postPeer, rootId);
|
|
||||||
//if (!commentId && (!item || !item->repliesAreComments())) {
|
|
||||||
// showSection(std::make_shared<HistoryView::RepliesMemento>(history, rootId));
|
|
||||||
// return;
|
|
||||||
//} else if (const auto id = item ? item->commentsItemId() : FullMsgId()) {
|
|
||||||
// if (const auto commentsItem = _session->data().message(id)) {
|
|
||||||
// showSection(
|
|
||||||
// std::make_shared<HistoryView::RepliesMemento>(commentsItem));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
_showingRepliesHistory = history;
|
_showingRepliesHistory = history;
|
||||||
_showingRepliesRootId = rootId;
|
_showingRepliesRootId = rootId;
|
||||||
_showingRepliesRequestId = _api.request(
|
_showingRepliesRequestId = _api.request(
|
||||||
|
@ -537,9 +526,11 @@ void SessionNavigation::showRepliesForMessage(
|
||||||
post->setRepliesOutboxReadTill(
|
post->setRepliesOutboxReadTill(
|
||||||
data.vread_outbox_max_id().value_or_empty());
|
data.vread_outbox_max_id().value_or_empty());
|
||||||
}
|
}
|
||||||
showSection(std::make_shared<HistoryView::RepliesMemento>(
|
showSection(
|
||||||
item,
|
std::make_shared<HistoryView::RepliesMemento>(
|
||||||
commentId));
|
item,
|
||||||
|
commentId),
|
||||||
|
params);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
@ -1577,9 +1568,8 @@ void SessionController::cancelUploadLayer(not_null<HistoryItem*> item) {
|
||||||
void SessionController::showSection(
|
void SessionController::showSection(
|
||||||
std::shared_ptr<SectionMemento> memento,
|
std::shared_ptr<SectionMemento> memento,
|
||||||
const SectionShow ¶ms) {
|
const SectionShow ¶ms) {
|
||||||
if (!params.thirdColumn && widget()->showSectionInExistingLayer(
|
if (!params.thirdColumn
|
||||||
memento.get(),
|
&& widget()->showSectionInExistingLayer(memento.get(), params)) {
|
||||||
params)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
content()->showSection(std::move(memento), params);
|
content()->showSection(std::move(memento), params);
|
||||||
|
|
Loading…
Add table
Reference in a new issue