Support topic icon display in topic profile.

This commit is contained in:
John Preston 2022-10-18 16:38:43 +04:00
parent fcc4503791
commit df5602d203
26 changed files with 317 additions and 119 deletions

View file

@ -2003,9 +2003,8 @@ void ApiWrap::applyAffectedMessages(
}
void ApiWrap::saveCurrentDraftToCloud() {
Core::App().saveCurrentDraftsToHistories();
for (const auto &controller : _session->windows()) {
controller->materializeLocalDrafts();
if (const auto thread = controller->activeChatCurrent().thread()) {
const auto history = thread->owningHistory();
_session->local().writeDrafts(history);
@ -2028,10 +2027,8 @@ void ApiWrap::saveDraftsToCloud() {
if (!thread) {
i = _draftsSaveRequestIds.erase(i);
continue;
}
auto &requestId = i->second;
++i;
if (requestId) {
} else if (i->second) {
++i;
continue; // sent already
}
@ -2055,9 +2052,9 @@ void ApiWrap::saveDraftsToCloud() {
}
if (cloudDraft->msgId) {
flags |= MTPmessages_SaveDraft::Flag::f_reply_to_msg_id;
if (cloudDraft->topicRootId) {
flags |= MTPmessages_SaveDraft::Flag::f_top_msg_id;
}
}
if (cloudDraft->topicRootId) {
flags |= MTPmessages_SaveDraft::Flag::f_top_msg_id;
}
if (!textWithTags.tags.isEmpty()) {
flags |= MTPmessages_SaveDraft::Flag::f_entities;
@ -2111,6 +2108,7 @@ void ApiWrap::saveDraftsToCloud() {
}).send();
i->second = cloudDraft->saveRequestId;
++i;
}
}

View file

@ -51,7 +51,7 @@ namespace ChatHelpers {
enum class StickerLottieSize : uint8 {
MessageHistory,
StickerSet,
StickerSet, // In Emoji used for forum topic profile cover icons.
StickersPanel,
StickersFooter,
SetsListThumbnail,

View file

@ -1144,14 +1144,6 @@ bool Application::hasActiveWindow(not_null<Main::Session*> session) const {
return false;
}
void Application::saveCurrentDraftsToHistories() {
if (!_primaryWindow) {
return;
} else if (const auto controller = _primaryWindow->sessionController()) {
controller->content()->saveFieldToHistoryLocalDraft();
}
}
Window::Controller *Application::primaryWindow() const {
return _primaryWindow.get();
}

View file

@ -152,7 +152,6 @@ public:
// Windows interface.
bool hasActiveWindow(not_null<Main::Session*> session) const;
void saveCurrentDraftsToHistories();
[[nodiscard]] Window::Controller *primaryWindow() const;
[[nodiscard]] Window::Controller *activeWindow() const;
[[nodiscard]] Window::Controller *separateWindowForPeer(

View file

@ -151,10 +151,11 @@ struct TopicUpdate {
UnreadReactions = (1U << 3),
Notifications = (1U << 4),
Title = (1U << 5),
Icon = (1U << 6),
CloudDraft = (1U << 7),
IconId = (1U << 6),
ColorId = (1U << 7),
CloudDraft = (1U << 8),
LastUsedBit = (1U << 7),
LastUsedBit = (1U << 8),
};
using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }

View file

@ -492,7 +492,7 @@ void ForumTopic::applyIconId(DocumentId iconId) {
_defaultIcon = QImage();
}
updateChatListEntry();
session().changes().topicUpdated(this, UpdateFlag::Icon);
session().changes().topicUpdated(this, UpdateFlag::IconId);
}
int32 ForumTopic::colorId() const {
@ -500,7 +500,10 @@ int32 ForumTopic::colorId() const {
}
void ForumTopic::applyColorId(int32 colorId) {
_colorId = colorId;
if (_colorId != colorId) {
_colorId = colorId;
session().changes().topicUpdated(this, UpdateFlag::ColorId);
}
}
void ForumTopic::applyItemAdded(not_null<HistoryItem*> item) {

View file

@ -39,6 +39,22 @@ constexpr auto kUnsubscribeUpdatesDelay = 3 * crl::time(1000);
using SizeTag = CustomEmojiManager::SizeTag;
class CallbackListener final : public CustomEmojiManager::Listener {
public:
explicit CallbackListener(Fn<void(not_null<DocumentData*>)> callback)
: _callback(std::move(callback)) {
Expects(_callback != nullptr);
}
private:
void customEmojiResolveDone(not_null<DocumentData*> document) {
_callback(document);
}
Fn<void(not_null<DocumentData*>)> _callback;
};
[[nodiscard]] ChatHelpers::StickerLottieSize LottieSizeFromTag(SizeTag tag) {
// NB! onlyCustomEmoji dimensions caching uses last ::EmojiInteraction-s.
using LottieSize = ChatHelpers::StickerLottieSize;
@ -546,6 +562,28 @@ void CustomEmojiManager::unregisterListener(not_null<Listener*> listener) {
}
}
rpl::producer<not_null<DocumentData*>> CustomEmojiManager::resolve(
DocumentId documentId) {
return [=](auto consumer) {
auto result = rpl::lifetime();
const auto put = [=](not_null<DocumentData*> document) {
if (!document->sticker()) {
return false;
}
consumer.put_next_copy(document);
return true;
};
if (!put(owner().document(documentId))) {
const auto listener = new CallbackListener(put);
result.add([=] {
unregisterListener(listener);
delete listener;
});
}
return result;
};
}
std::unique_ptr<Ui::CustomEmoji::Loader> CustomEmojiManager::createLoader(
not_null<DocumentData*> document,
SizeTag tag,

View file

@ -65,6 +65,9 @@ public:
void resolve(DocumentId documentId, not_null<Listener*> listener);
void unregisterListener(not_null<Listener*> listener);
[[nodiscard]] rpl::producer<not_null<DocumentData*>> resolve(
DocumentId documentId);
[[nodiscard]] std::unique_ptr<Ui::CustomEmoji::Loader> createLoader(
not_null<DocumentData*> document,
SizeTag tag,

View file

@ -35,6 +35,11 @@ largeForumTopicIcon: ForumTopicIcon {
font: font(bold 13px);
textTop: 3px;
}
infoForumTopicIcon: ForumTopicIcon {
size: 32px;
font: font(bold 15px);
textTop: 4px;
}
dialogsUnreadFont: font(12px bold);
dialogsUnreadHeight: 19px;

View file

@ -182,9 +182,9 @@ constexpr auto kSkipRepaintWhileScrollMs = 100;
constexpr auto kShowMembersDropdownTimeoutMs = 300;
constexpr auto kDisplayEditTimeWarningMs = 300 * 1000;
constexpr auto kFullDayInMs = 86400 * 1000;
constexpr auto kSaveDraftTimeout = 1000;
constexpr auto kSaveDraftAnywayTimeout = 5000;
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
constexpr auto kSaveDraftTimeout = crl::time(1000);
constexpr auto kSaveDraftAnywayTimeout = 5 * crl::time(1000);
constexpr auto kSaveCloudDraftIdleTimeout = 14 * crl::time(1000);
constexpr auto kRefreshSlowmodeLabelTimeout = crl::time(200);
constexpr auto kCommonModifiers = 0
| Qt::ShiftModifier
@ -865,6 +865,11 @@ HistoryWidget::HistoryWidget(
}, lifetime());
}
controller->materializeLocalDraftsRequests(
) | rpl::start_with_next([=] {
saveFieldToHistoryLocalDraft();
}, lifetime());
setupScheduledToggle();
setupSendAsToggle();
orderWidgets();

View file

@ -227,7 +227,6 @@ public:
void clearSupportPreloadRequest();
void clearDelayedShowAtRequest();
void clearDelayedShowAt();
void saveFieldToHistoryLocalDraft();
void toggleChooseChatTheme(not_null<PeerData*> peer);
[[nodiscard]] Ui::ChatTheme *customChatTheme() const;
@ -355,6 +354,7 @@ private:
void checkFieldAutocomplete();
void showMembersDropdown();
void windowIsVisibleChanged();
void saveFieldToHistoryLocalDraft();
// Checks if we are too close to the top or to the bottom
// in the scroll area and preloads history if needed.

View file

@ -68,6 +68,7 @@ namespace {
constexpr auto kSaveDraftTimeout = crl::time(1000);
constexpr auto kSaveDraftAnywayTimeout = 5 * crl::time(1000);
constexpr auto kSaveCloudDraftIdleTimeout = 14 * crl::time(1000);
constexpr auto kMouseEvents = {
QEvent::MouseMove,
QEvent::MouseButtonPress,
@ -870,7 +871,8 @@ ComposeControls::ComposeControls(
st::historySendSize.height()))
, _sendMenuType(sendMenuType)
, _unavailableEmojiPasted(unavailableEmojiPasted)
, _saveDraftTimer([=] { saveDraft(); }) {
, _saveDraftTimer([=] { saveDraft(); })
, _saveCloudDraftTimer([=] { saveCloudDraft(); }) {
init();
}
@ -1341,6 +1343,11 @@ void ComposeControls::init() {
}, _wrap->lifetime());
}
_window->materializeLocalDraftsRequests(
) | rpl::start_with_next([=] {
saveFieldToHistoryLocalDraft();
}, _wrap->lifetime());
orderControls();
}
@ -1660,6 +1667,7 @@ void ComposeControls::fieldChanged() {
}
});
_saveCloudDraftTimer.cancel();
if (!(_textUpdateEvents & TextUpdateEvent::SaveDraft)) {
return;
}
@ -1709,6 +1717,10 @@ void ComposeControls::saveDraft(bool delayed) {
writeDrafts();
}
void ComposeControls::saveCloudDraft() {
session().api().saveCurrentDraftToCloud();
}
void ComposeControls::writeDraftTexts() {
Expects(_history != nullptr);
@ -1773,9 +1785,15 @@ void ComposeControls::writeDrafts() {
}
_saveDraftText = false;
//if (!isEditingMessage() && !_inlineBot) {
// _saveCloudDraftTimer.callOnce(kSaveCloudDraftIdleTimeout);
//}
if (!isEditingMessage() && !_inlineBot) {
_saveCloudDraftTimer.callOnce(kSaveCloudDraftIdleTimeout);
}
}
void ComposeControls::applyCloudDraft() {
if (!isEditingMessage()) {
applyDraft(Ui::InputField::HistoryAction::NewEntry);
}
}
void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {

View file

@ -179,6 +179,7 @@ public:
[[nodiscard]] bool isLockPresent() const;
[[nodiscard]] bool isRecording() const;
void applyCloudDraft();
void applyDraft(
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
@ -265,6 +266,7 @@ private:
[[nodiscard]] Data::DraftKey draftKeyCurrent() const;
void saveDraft(bool delayed = false);
void saveDraftDelayed();
void saveCloudDraft();
void writeDrafts();
void writeDraftTexts();
@ -334,6 +336,7 @@ private:
crl::time _saveDraftStart = 0;
bool _saveDraftText = false;
base::Timer _saveDraftTimer;
base::Timer _saveCloudDraftTimer;
UserData *_inlineBot = nullptr;
QString _inlineBotUsername;

View file

@ -44,22 +44,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
namespace {
class Listener final : public Data::CustomEmojiManager::Listener {
public:
explicit Listener(Fn<void(not_null<DocumentData*>)> check)
: _check(std::move(check)) {
}
void customEmojiResolveDone(
not_null<DocumentData*> document) override {
_check(document);
}
private:
Fn<void(not_null<DocumentData*>)> _check;
};
[[nodiscard]] bool BarCurrentlyHidden(not_null<PeerData*> peer) {
const auto settings = peer->settings();
if (!settings) {
@ -83,43 +67,29 @@ private:
[[nodiscard]] rpl::producer<TextWithEntities> ResolveIsCustom(
not_null<Data::Session*> owner,
DocumentId id) {
return [=](auto consumer) {
const auto document = owner->document(id);
const auto manager = &owner->customEmojiManager();
const auto check = [=](not_null<DocumentData*> document) {
if (const auto sticker = document->sticker()) {
const auto setId = manager->coloredSetId();
const auto text = (setId == sticker->set.id)
? QString()
: sticker->alt;
if (text.isEmpty()) {
consumer.put_next({});
} else {
consumer.put_next({
.text = text,
.entities = { EntityInText(
EntityType::CustomEmoji,
0,
text.size(),
Data::SerializeCustomEmojiId(document)) },
});
}
return true;
}
return false;
};
auto lifetime = rpl::lifetime();
if (!check(document)) {
const auto manager = &owner->customEmojiManager();
const auto listener = new Listener(check);
lifetime.add([=] {
manager->unregisterListener(listener);
delete listener;
});
manager->resolve(id, listener);
return owner->customEmojiManager().resolve(
id
) | rpl::map([=](not_null<DocumentData*> document) {
const auto sticker = document->sticker();
Assert(sticker != nullptr);
const auto &manager = document->owner().customEmojiManager();
const auto setId = manager.coloredSetId();
const auto text = (setId == sticker->set.id)
? QString()
: sticker->alt;
if (text.isEmpty()) {
return TextWithEntities();
}
return lifetime;
};
return TextWithEntities{
.text = text,
.entities = { EntityInText(
EntityType::CustomEmoji,
0,
text.size(),
Data::SerializeCustomEmojiId(document)) },
};
});
}
[[nodiscard]] rpl::producer<TextWithEntities> PeerCustomStatus(

View file

@ -359,6 +359,7 @@ RepliesWidget::~RepliesWidget() {
_history->owner().sendActionManager().repliesPainterRemoved(
_history,
_rootId);
session().api().saveCurrentDraftToCloud();
controller()->sendingAnimation().clear();
}
@ -461,13 +462,19 @@ void RepliesWidget::setupTopicViewer() {
void RepliesWidget::subscribeToTopic() {
Expects(_topic != nullptr);
using TopicUpdateFlag = Data::TopicUpdate::Flag;
using Flag = Data::TopicUpdate::Flag;
session().changes().topicUpdates(
_topic,
(TopicUpdateFlag::UnreadMentions
| TopicUpdateFlag::UnreadReactions)
(Flag::UnreadMentions
| Flag::UnreadReactions
| Flag::CloudDraft)
) | rpl::start_with_next([=](const Data::TopicUpdate &update) {
_cornerButtons.updateUnreadThingsVisibility();
if (update.flags & (Flag::UnreadMentions | Flag::UnreadReactions)) {
_cornerButtons.updateUnreadThingsVisibility();
}
if (update.flags & Flag::CloudDraft) {
_composeControls->applyCloudDraft();
}
}, _topicLifetime);
_topic->destroyed(

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_sticker_player.h"
#include "core/file_location.h"
namespace HistoryView {
namespace {
@ -114,4 +116,46 @@ bool WebmPlayer::markFrameShown() {
return _reader->moveToNextFrame();
}
StaticStickerPlayer::StaticStickerPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size)
: _frame(Images::Read({
.path = location.name(),
.content = data,
.forceOpaque = true,
}).image) {
if (!_frame.isNull()) {
size = _frame.size().scaled(size, Qt::KeepAspectRatio);
const auto ratio = style::DevicePixelRatio();
_frame = Images::Prepare(std::move(_frame), size * ratio, {});
_frame.setDevicePixelRatio(ratio);
}
}
void StaticStickerPlayer::setRepaintCallback(Fn<void()> callback) {
callback();
}
bool StaticStickerPlayer::ready() {
return true;
}
int StaticStickerPlayer::framesCount() {
return 1;
}
StaticStickerPlayer::FrameInfo StaticStickerPlayer::frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) {
return { _frame };
}
bool StaticStickerPlayer::markFrameShown() {
return false;
}
} // namespace HistoryView

View file

@ -66,4 +66,27 @@ private:
};
class StaticStickerPlayer final : public StickerPlayer {
public:
StaticStickerPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size);
void setRepaintCallback(Fn<void()> callback) override;
bool ready() override;
int framesCount() override;
FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) override;
bool markFrameShown() override;
private:
QImage _frame;
};
} // namespace HistoryView

View file

@ -315,6 +315,11 @@ infoProfileMegagroupCover: InfoProfileCover(infoProfileCover) {
}
infoTopicCover: InfoProfileCover(infoProfileMegagroupCover) {
height: 77px;
photo: UserpicButton(defaultUserpicButton) {
size: size(36px, 36px);
}
photoLeft: 22px;
photoTop: 18px;
nameLeft: 79px;
nameTop: 14px;
statusLeft: 79px;

View file

@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_changes.h"
#include "data/data_session.h"
#include "data/data_forum_topic.h"
@ -19,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/profile/info_profile_badge.h"
#include "info/profile/info_profile_emoji_status_panel.h"
#include "info/info_controller.h"
#include "history/view/media/history_view_sticker_player.h"
#include "lang/lang_keys.h"
#include "ui/widgets/labels.h"
#include "ui/text/text_utilities.h"
@ -27,10 +30,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_session_controller.h"
#include "main/main_session.h"
#include "settings/settings_premium.h"
#include "chat_helpers/stickers_lottie.h"
#include "apiwrap.h"
#include "api/api_peer_photo.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
#include "styles/style_dialogs.h"
namespace Info::Profile {
namespace {
@ -185,32 +190,90 @@ Cover::Cover(
}
}
void Cover::setupIcon(not_null<Data::ForumTopic*> topic) {
const auto tag = Data::CustomEmojiManager::SizeTag::Large;
void Cover::setupIconPlayer(not_null<Data::ForumTopic*> topic) {
IconIdValue(
topic
) | rpl::start_with_next([=](DocumentId id) {
_icon = id
? topic->owner().customEmojiManager().create(
id,
[=] { _iconView->update(); },
tag)
: nullptr;
) | rpl::map([=](DocumentId id) {
return topic->owner().customEmojiManager().resolve(id);
}) | rpl::flatten_latest(
) | rpl::map([=](not_null<DocumentData*> document) {
const auto media = document->createMediaView();
media->checkStickerLarge();
media->goodThumbnailWanted();
return rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
}) | rpl::take(1) | rpl::map([=] {
auto result = std::shared_ptr<StickerPlayer>();
const auto sticker = document->sticker();
if (sticker->isLottie()) {
result = std::make_shared<HistoryView::LottiePlayer>(
ChatHelpers::LottiePlayerFromDocument(
media.get(),
ChatHelpers::StickerLottieSize::StickerSet,
_st.photo.size,
Lottie::Quality::High));
} else if (sticker->isWebm()) {
result = std::make_shared<HistoryView::WebmPlayer>(
media->owner()->location(),
media->bytes(),
_st.photo.size);
} else {
result = std::make_shared<HistoryView::StaticStickerPlayer>(
media->owner()->location(),
media->bytes(),
_st.photo.size);
}
result->setRepaintCallback([=] { _iconView->update(); });
return result;
});
}) | rpl::flatten_latest(
) | rpl::start_with_next([=](std::shared_ptr<StickerPlayer> player) {
_iconPlayer = std::move(player);
}, lifetime());
const auto size = Data::FrameSizeFromTag(tag);
_iconView->resize(size, size);
}
void Cover::setupIconImage(not_null<Data::ForumTopic*> topic) {
rpl::combine(
TitleValue(topic),
ColorIdValue(topic)
) | rpl::map([=](const QString &title, int32 colorId) {
using namespace Data;
return ForumTopicIconFrame(colorId, title, st::infoForumTopicIcon);
}) | rpl::start_with_next([=](QImage &&image) {
_iconImage = std::move(image);
_iconView->update();
}, lifetime());
}
void Cover::setupIcon(not_null<Data::ForumTopic*> topic) {
setupIconPlayer(topic);
setupIconImage(topic);
_iconView->resize(_st.photo.size);
_iconView->paintRequest(
) | rpl::start_with_next([=] {
auto p = QPainter(_iconView.data());
if (_icon) {
_icon->paint(p, {
.preview = st::windowBgOver->c,
.now = crl::now(),
.paused = _controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer),
});
} else {
const auto paint = [&](const QImage &image) {
const auto size = image.size() / image.devicePixelRatio();
p.drawImage(
(_st.photo.size.width() - size.width()) / 2,
(_st.photo.size.height() - size.height()) / 2,
image);
};
if (_iconPlayer && _iconPlayer->ready()) {
paint(_iconPlayer->frame(
_st.photo.size,
QColor(0, 0, 0, 0),
false,
crl::now(),
_controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer)).image);
_iconPlayer->markFrameShown();
} else if (!topic->iconId() && !_iconImage.isNull()) {
paint(_iconImage);
}
}, _iconView->lifetime());
}

View file

@ -21,9 +21,9 @@ template <typename Widget>
class SlideWrap;
} // namespace Ui
namespace Ui::Text {
struct CustomEmojiColored;
} // namespace Ui::Text
namespace HistoryView {
class StickerPlayer;
} // namespace HistoryView
namespace Data {
class ForumTopic;
@ -67,6 +67,8 @@ public:
}
private:
using StickerPlayer = HistoryView::StickerPlayer;
Cover(
QWidget *parent,
not_null<PeerData*> peer,
@ -75,6 +77,8 @@ private:
rpl::producer<QString> title);
void setupIcon(not_null<Data::ForumTopic*> topic);
void setupIconPlayer(not_null<Data::ForumTopic*> topic);
void setupIconImage(not_null<Data::ForumTopic*> topic);
void setupChildGeometry();
void initViewers(rpl::producer<QString> title);
void refreshStatusText();
@ -92,7 +96,8 @@ private:
object_ptr<Ui::UserpicButton> _userpic;
object_ptr<Ui::RpWidget> _iconView;
std::unique_ptr<Ui::Text::CustomEmoji> _icon;
std::shared_ptr<StickerPlayer> _iconPlayer;
QImage _iconImage;
object_ptr<Ui::FlatLabel> _name = { nullptr };
object_ptr<Ui::FlatLabel> _status = { nullptr };
//object_ptr<CoverDropArea> _dropArea = { nullptr };

View file

@ -104,10 +104,17 @@ rpl::producer<QString> TitleValue(not_null<Data::ForumTopic*> topic) {
rpl::producer<DocumentId> IconIdValue(not_null<Data::ForumTopic*> topic) {
return topic->session().changes().topicFlagsValue(
topic,
Data::TopicUpdate::Flag::Icon
Data::TopicUpdate::Flag::IconId
) | rpl::map([=] { return topic->iconId(); });
}
rpl::producer<int32> ColorIdValue(not_null<Data::ForumTopic*> topic) {
return topic->session().changes().topicFlagsValue(
topic,
Data::TopicUpdate::Flag::ColorId
) | rpl::map([=] { return topic->colorId(); });
}
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
return rpl::merge(
Countries::Instance().updated(),

View file

@ -49,6 +49,8 @@ rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
not_null<Data::ForumTopic*> topic);
[[nodiscard]] rpl::producer<DocumentId> IconIdValue(
not_null<Data::ForumTopic*> topic);
[[nodiscard]] rpl::producer<int32> ColorIdValue(
not_null<Data::ForumTopic*> topic);
[[nodiscard]] rpl::producer<TextWithEntities> PhoneValue(
not_null<UserData*> user);
[[nodiscard]] rpl::producer<TextWithEntities> PhoneOrHiddenValue(

View file

@ -2727,10 +2727,6 @@ bool MainWidget::doWeMarkAsRead() const {
return isActive() && !_mainSection;
}
void MainWidget::saveFieldToHistoryLocalDraft() {
_history->saveFieldToHistoryLocalDraft();
}
bool MainWidget::isOneColumn() const {
return _controller->adaptive().isOneColumn();
}

View file

@ -169,8 +169,6 @@ public:
bool isActive() const;
[[nodiscard]] bool doWeMarkAsRead() const;
void saveFieldToHistoryLocalDraft();
void showForwardLayer(Data::ForwardDraft &&draft);
void showSendPathsLayer();
void shareUrlLayer(const QString &url, const QString &text);

View file

@ -1119,6 +1119,14 @@ void SessionController::floatPlayerAreaUpdated() {
}
}
void SessionController::materializeLocalDrafts() {
_materializeLocalDraftsRequests.fire({});
}
rpl::producer<> SessionController::materializeLocalDraftsRequests() const {
return _materializeLocalDraftsRequests.events();
}
int SessionController::dialogsSmallColumnWidth() const {
return st::defaultDialogRow.padding.left()
+ st::defaultDialogRow.photoSize

View file

@ -378,6 +378,9 @@ public:
bool isGifPausedAtLeastFor(GifPauseReason reason) const;
void floatPlayerAreaUpdated();
void materializeLocalDrafts();
[[nodiscard]] rpl::producer<> materializeLocalDraftsRequests() const;
struct ColumnLayout {
int bodyWidth = 0;
int dialogsWidth = 0;
@ -629,6 +632,8 @@ private:
QString _premiumRef;
rpl::event_stream<> _materializeLocalDraftsRequests;
rpl::lifetime _lifetime;
};