Start scheduled compose controls.

This commit is contained in:
John Preston 2019-08-16 12:32:42 +03:00
parent 1c9775baf9
commit 385a7eb00d
12 changed files with 515 additions and 101 deletions

View File

@ -103,6 +103,7 @@ TabbedPanel::TabbedPanel(
setAttribute(Qt::WA_OpaquePaintEvent, false);
hideChildren();
hide();
}
void TabbedPanel::moveBottomRight(int bottom, int right) {

View File

@ -25,7 +25,9 @@ class TabbedSelector;
class TabbedPanel : public Ui::RpWidget {
public:
TabbedPanel(QWidget *parent, not_null<Window::SessionController*> controller);
TabbedPanel(
QWidget *parent,
not_null<Window::SessionController*> controller);
TabbedPanel(
QWidget *parent,
not_null<Window::SessionController*> controller,

View File

@ -443,7 +443,6 @@ HistoryWidget::HistoryWidget(
_botKeyboardHide->addClickHandler([=] { toggleKeyboard(); });
_botCommandStart->addClickHandler([=] { startBotCommand(); });
_tabbedPanel->hide();
_attachDragDocument->hide();
_attachDragPhoto->hide();
@ -3879,8 +3878,7 @@ void HistoryWidget::pushTabbedSelectorToThirdSection(
void HistoryWidget::toggleTabbedSelectorMode() {
if (_tabbedPanel) {
if (controller()->canShowThirdSection()
&& !Adaptive::OneColumn()) {
if (controller()->canShowThirdSection() && !Adaptive::OneColumn()) {
session().settings().setTabbedSelectorSectionEnabled(true);
session().saveSettingsDelayed();
pushTabbedSelectorToThirdSection(
@ -3899,7 +3897,6 @@ void HistoryWidget::returnTabbedSelector(
this,
controller(),
std::move(selector));
_tabbedPanel->hide();
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
_tabbedSelectorToggleTooltipShown = false;
@ -3928,7 +3925,7 @@ void HistoryWidget::moveFieldControls() {
}
// _attachToggle --------- _inlineResults -------------------------------------- _tabbedPanel --------- _fieldBarCancel
// (_attachDocument|_attachPhoto) _field (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) [_broadcast] _send
// (_attachDocument|_attachPhoto) _field (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
// (_botStart|_unblock|_joinChannel|{_muteUnmute&_discuss})
auto buttonsBottom = bottom - _attachToggle->height();

View File

@ -320,6 +320,41 @@ private:
using TabbedPanel = ChatHelpers::TabbedPanel;
using TabbedSelector = ChatHelpers::TabbedSelector;
using DragState = Storage::MimeDataState;
struct BotCallbackInfo {
UserData *bot;
FullMsgId msgId;
int row, col;
bool game;
};
struct PinnedBar {
PinnedBar(MsgId msgId, HistoryWidget *parent);
~PinnedBar();
MsgId msgId = 0;
HistoryItem *msg = nullptr;
Ui::Text::String text;
object_ptr<Ui::IconButton> cancel;
object_ptr<Ui::PlainShadow> shadow;
};
enum ScrollChangeType {
ScrollChangeNone,
// When we toggle a pinned message.
ScrollChangeAdd,
// When loading a history part while scrolling down.
ScrollChangeNoJumpToBottom,
};
struct ScrollChange {
ScrollChangeType type;
int value;
};
enum class TextUpdateEvent {
SaveDraft = (1 << 0),
SendTyping = (1 << 1),
};
using TextUpdateEvents = base::flags<TextUpdateEvent>;
friend inline constexpr bool is_flag_type(TextUpdateEvent) { return true; };
void initTabbedSelector();
void updateField();
@ -488,35 +523,9 @@ private:
void handlePeerMigration();
MsgId _replyToId = 0;
Ui::Text::String _replyToName;
int _replyToNameVersion = 0;
HistoryItemsList _toForward;
Ui::Text::String _toForwardFrom, _toForwardText;
int _toForwardNameVersion = 0;
MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg = nullptr;
Ui::Text::String _replyEditMsgText;
mutable base::Timer _updateEditTimeLeftDisplay;
object_ptr<Ui::IconButton> _fieldBarCancel;
void updateReplyEditTexts(bool force = false);
void updateReplyEditText(not_null<HistoryItem*> item);
struct PinnedBar {
PinnedBar(MsgId msgId, HistoryWidget *parent);
~PinnedBar();
MsgId msgId = 0;
HistoryItem *msg = nullptr;
Ui::Text::String text;
object_ptr<Ui::IconButton> cancel;
object_ptr<Ui::PlainShadow> shadow;
};
std::unique_ptr<PinnedBar> _pinnedBar;
void updatePinnedBar(bool force = false);
bool pinnedMsgVisibilityUpdated();
void destroyPinnedBar();
@ -542,7 +551,6 @@ private:
// destroys _history and _migrated unread bars
void destroyUnreadBar();
mtpRequestId _saveEditMsgRequestId = 0;
void saveEditMsg();
void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req);
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
@ -550,49 +558,13 @@ private:
void checkPreview();
void requestPreview();
void gotPreview(QString links, const MTPMessageMedia &media, mtpRequestId req);
QStringList _parsedLinks;
QString _previewLinks;
WebPageData *_previewData = nullptr;
typedef QMap<QString, WebPageId> PreviewCache;
PreviewCache _previewCache;
mtpRequestId _previewRequest = 0;
Ui::Text::String _previewTitle;
Ui::Text::String _previewDescription;
base::Timer _previewTimer;
bool _previewCancelled = false;
bool _replyForwardPressed = false;
HistoryItem *_replyReturn = nullptr;
QList<MsgId> _replyReturns;
bool messagesFailed(const RPCError &error, mtpRequestId requestId);
void addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages);
void addMessagesToBack(PeerData *peer, const QVector<MTPMessage> &messages);
struct BotCallbackInfo {
UserData *bot;
FullMsgId msgId;
int row, col;
bool game;
};
void botCallbackDone(BotCallbackInfo info, const MTPmessages_BotCallbackAnswer &answer, mtpRequestId req);
bool botCallbackFail(BotCallbackInfo info, const RPCError &error, mtpRequestId req);
enum ScrollChangeType {
ScrollChangeNone,
// When we toggle a pinned message.
ScrollChangeAdd,
// When loading a history part while scrolling down.
ScrollChangeNoJumpToBottom,
};
struct ScrollChange {
ScrollChangeType type;
int value;
};
void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
void updateListSize();
@ -613,13 +585,6 @@ private:
void countHistoryShowFrom();
enum class TextUpdateEvent {
SaveDraft = (1 << 0),
SendTyping = (1 << 1),
};
using TextUpdateEvents = base::flags<TextUpdateEvent>;
friend inline constexpr bool is_flag_type(TextUpdateEvent) { return true; };
void writeDrafts(Data::Draft **localDraft, Data::Draft **editDraft);
void writeDrafts(History *history);
void setFieldText(
@ -650,6 +615,58 @@ private:
void handleSupportSwitch(not_null<History*> updated);
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(QString name, const RPCError &error);
bool isBotStart() const;
bool isBlocked() const;
bool isJoinChannel() const;
bool isMuteUnmute() const;
bool updateCmdStartShown();
void updateSendButtonType();
bool showRecordButton() const;
bool showInlineBotCancel() const;
void refreshSilentToggle();
void setupScheduledToggle();
void refreshScheduledToggle();
MsgId _replyToId = 0;
Ui::Text::String _replyToName;
int _replyToNameVersion = 0;
HistoryItemsList _toForward;
Ui::Text::String _toForwardFrom, _toForwardText;
int _toForwardNameVersion = 0;
MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg = nullptr;
Ui::Text::String _replyEditMsgText;
mutable base::Timer _updateEditTimeLeftDisplay;
object_ptr<Ui::IconButton> _fieldBarCancel;
std::unique_ptr<PinnedBar> _pinnedBar;
mtpRequestId _saveEditMsgRequestId = 0;
QStringList _parsedLinks;
QString _previewLinks;
WebPageData *_previewData = nullptr;
typedef QMap<QString, WebPageId> PreviewCache;
PreviewCache _previewCache;
mtpRequestId _previewRequest = 0;
Ui::Text::String _previewTitle;
Ui::Text::String _previewDescription;
base::Timer _previewTimer;
bool _previewCancelled = false;
bool _replyForwardPressed = false;
HistoryItem *_replyReturn = nullptr;
QList<MsgId> _replyReturns;
PeerData *_peer = nullptr;
ChannelId _channel = NoChannel;
@ -699,21 +716,6 @@ private:
bool _inlineLookingUpBot = false;
mtpRequestId _inlineBotResolveRequestId = 0;
bool _isInlineBot = false;
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(QString name, const RPCError &error);
bool isBotStart() const;
bool isBlocked() const;
bool isJoinChannel() const;
bool isMuteUnmute() const;
bool updateCmdStartShown();
void updateSendButtonType();
bool showRecordButton() const;
bool showInlineBotCancel() const;
void refreshSilentToggle();
void setupScheduledToggle();
void refreshScheduledToggle();
std::unique_ptr<HistoryView::ContactStatus> _contactStatus;

View File

@ -0,0 +1,251 @@
/*
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 "history/view/history_view_compose_controls.h"
#include "ui/widgets/input_fields.h"
#include "ui/special_buttons.h"
#include "lang/lang_keys.h"
#include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_section.h"
#include "chat_helpers/tabbed_selector.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "window/window_session_controller.h"
#include "inline_bots/inline_results_widget.h"
#include "styles/style_history.h"
namespace HistoryView {
ComposeControls::ComposeControls(
not_null<QWidget*> parent,
not_null<Window::SessionController*> window,
Mode mode)
: _parent(parent)
, _window(window)
, _mode(mode)
, _wrap(std::make_unique<Ui::RpWidget>(parent))
, _send(Ui::CreateChild<Ui::SendButton>(_wrap.get()))
, _attachToggle(Ui::CreateChild<Ui::IconButton>(
_wrap.get(),
st::historyAttach))
, _tabbedSelectorToggle(Ui::CreateChild<Ui::EmojiButton>(
_wrap.get(),
st::historyAttachEmoji))
, _field(Ui::CreateChild<Ui::InputField>(
_wrap.get(),
st::historyComposeField,
Ui::InputField::Mode::MultiLine,
tr::lng_message_ph()))
, _tabbedPanel(std::make_unique<ChatHelpers::TabbedPanel>(parent, window))
, _tabbedSelector(_tabbedPanel->getSelector()) {
init();
}
ComposeControls::~ComposeControls() = default;
Main::Session &ComposeControls::session() const {
return _window->session();
}
void ComposeControls::move(int x, int y) {
_wrap->move(x, y);
}
void ComposeControls::resizeToWidth(int width) {
_wrap->resizeToWidth(width);
updateHeight();
}
rpl::producer<int> ComposeControls::height() const {
return _wrap->heightValue();
}
int ComposeControls::heightCurrent() const {
return _wrap->height();
}
void ComposeControls::focus() {
_field->setFocus();
}
rpl::producer<> ComposeControls::cancelRequests() const {
return _cancelRequests.events();
}
void ComposeControls::showStarted() {
if (_inlineResults) {
_inlineResults->hideFast();
}
if (_tabbedPanel) {
_tabbedPanel->hideFast();
}
_wrap->hide();
}
void ComposeControls::showFinished() {
if (_inlineResults) {
_inlineResults->hideFast();
}
if (_tabbedPanel) {
_tabbedPanel->hideFast();
}
_wrap->show();
}
void ComposeControls::showForGrab() {
showFinished();
}
void ComposeControls::init() {
initField();
initTabbedSelector();
_wrap->sizeValue(
) | rpl::start_with_next([=](QSize size) {
updateControlsGeometry(size);
}, _wrap->lifetime());
_wrap->geometryValue(
) | rpl::start_with_next([=](QRect rect) {
updateOuterGeometry(rect);
}, _wrap->lifetime());
_wrap->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
paintBackground(clip);
}, _wrap->lifetime());
}
void ComposeControls::initField() {
_field->setMaxHeight(st::historyComposeFieldMaxHeight);
//Ui::Connect(_field, &Ui::InputField::submitted, [=] { send(); });
Ui::Connect(_field, &Ui::InputField::cancelled, [=] { escape(); });
//Ui::Connect(_field, &Ui::InputField::tabbed, [=] { fieldTabbed(); });
Ui::Connect(_field, &Ui::InputField::resized, [=] { updateHeight(); });
//Ui::Connect(_field, &Ui::InputField::focused, [=] { fieldFocused(); });
//Ui::Connect(_field, &Ui::InputField::changed, [=] { fieldChanged(); });
InitMessageField(_window, _field);
const auto suggestions = Ui::Emoji::SuggestionsController::Init(
_parent,
_field,
&_window->session());
_raiseEmojiSuggestions = [=] { suggestions->raise(); };
}
void ComposeControls::initTabbedSelector() {
_tabbedSelectorToggle->installEventFilter(_tabbedPanel.get());
_tabbedSelectorToggle->addClickHandler([=] {
toggleTabbedSelectorMode();
});
}
void ComposeControls::updateControlsGeometry(QSize size) {
// _attachToggle -- _inlineResults ------ _tabbedPanel -- _fieldBarCancel
// (_attachDocument|_attachPhoto) _field _tabbedSelectorToggle _send
const auto fieldWidth = size.width()
- _attachToggle->width()
- st::historySendRight
- _send->width()
- _tabbedSelectorToggle->width();
_field->resizeToWidth(fieldWidth);
const auto buttonsTop = size.height() - _attachToggle->height();
auto left = 0;
_attachToggle->moveToLeft(left, buttonsTop);
left += _attachToggle->width();
_field->moveToLeft(
left,
size.height() - _field->height() - st::historySendPadding);
auto right = st::historySendRight;
_send->moveToRight(right, buttonsTop);
right += _send->width();
_tabbedSelectorToggle->moveToRight(right, buttonsTop);
}
void ComposeControls::updateOuterGeometry(QRect rect) {
if (_inlineResults) {
_inlineResults->moveBottom(rect.y());
}
if (_tabbedPanel) {
_tabbedPanel->moveBottomRight(
rect.y() + rect.height() - _attachToggle->height(),
rect.x() + rect.width());
}
}
void ComposeControls::paintBackground(QRect clip) {
Painter p(_wrap.get());
p.fillRect(clip, st::historyComposeAreaBg);
}
void ComposeControls::escape() {
_cancelRequests.fire({});
}
void ComposeControls::pushTabbedSelectorToThirdSection(
const Window::SectionShow &params) {
if (!_tabbedPanel) {
return;
//} else if (!_canSendMessages) {
// session().settings().setTabbedReplacedWithInfo(true);
// _window->showPeerInfo(_peer, params.withThirdColumn());
// return;
}
session().settings().setTabbedReplacedWithInfo(false);
_tabbedSelectorToggle->setColorOverrides(
&st::historyAttachEmojiActive,
&st::historyRecordVoiceFgActive,
&st::historyRecordVoiceRippleBgActive);
auto destroyingPanel = std::move(_tabbedPanel);
auto memento = ChatHelpers::TabbedMemento(
destroyingPanel->takeSelector(),
crl::guard(_wrap.get(), [=](
object_ptr<ChatHelpers::TabbedSelector> selector) {
returnTabbedSelector(std::move(selector));
}));
_window->resizeForThirdSection();
_window->showSection(std::move(memento), params.withThirdColumn());
}
void ComposeControls::toggleTabbedSelectorMode() {
if (_tabbedPanel) {
if (_window->canShowThirdSection() && !Adaptive::OneColumn()) {
session().settings().setTabbedSelectorSectionEnabled(true);
session().saveSettingsDelayed();
pushTabbedSelectorToThirdSection(
Window::SectionShow::Way::ClearStack);
} else {
_tabbedPanel->toggleAnimated();
}
} else {
_window->closeThirdSection();
}
}
void ComposeControls::returnTabbedSelector(
object_ptr<ChatHelpers::TabbedSelector> selector) {
_tabbedPanel = std::make_unique<ChatHelpers::TabbedPanel>(
_parent,
_window,
std::move(selector));
_tabbedPanel->hide();
_tabbedSelectorToggle->installEventFilter(_tabbedPanel.get());
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
updateOuterGeometry(_wrap->geometry());
}
void ComposeControls::updateHeight() {
const auto height = _field->height() + 2 * st::historySendPadding;
_wrap->resize(_wrap->width(), height);
}
} // namespace HistoryView

View File

@ -0,0 +1,121 @@
/*
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 "base/unique_qptr.h"
#include "ui/rp_widget.h"
#include "ui/effects/animations.h"
namespace ChatHelpers {
class TabbedPanel;
class TabbedSelector;
} // namespace ChatHelpers
namespace InlineBots {
namespace Layout {
class ItemBase;
class Widget;
} // namespace Layout
class Result;
} // namespace InlineBots
namespace Ui {
class SendButton;
class IconButton;
class EmojiButton;
class InputField;
} // namespace Ui
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
struct SectionShow;
} // namespace Window
namespace HistoryView {
class ComposeControls final {
public:
enum class Mode {
Normal,
Scheduled,
};
ComposeControls(
not_null<QWidget*> parent,
not_null<Window::SessionController*> window,
Mode mode);
~ComposeControls();
[[nodiscard]] Main::Session &session() const;
void move(int x, int y);
void resizeToWidth(int width);
[[nodiscard]] rpl::producer<int> height() const;
[[nodiscard]] int heightCurrent() const;
void focus();
[[nodiscard]] rpl::producer<> cancelRequests() const;
void showForGrab();
void showStarted();
void showFinished();
private:
void init();
void initField();
void initTabbedSelector();
void updateHeight();
void updateControlsGeometry(QSize size);
void updateOuterGeometry(QRect rect);
void paintBackground(QRect clip);
void escape();
void toggleTabbedSelectorMode();
void pushTabbedSelectorToThirdSection(const Window::SectionShow &params);
void returnTabbedSelector(
object_ptr<ChatHelpers::TabbedSelector> selector);
const not_null<QWidget*> _parent;
const not_null<Window::SessionController*> _window;
Mode _mode = Mode::Normal;
const std::unique_ptr<Ui::RpWidget> _wrap;
const not_null<Ui::SendButton*> _send;
const not_null<Ui::IconButton*> _attachToggle;
const not_null<Ui::EmojiButton*> _tabbedSelectorToggle;
const not_null<Ui::InputField*> _field;
std::unique_ptr<InlineBots::Layout::Widget> _inlineResults;
std::unique_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
const not_null<ChatHelpers::TabbedSelector*> _tabbedSelector;
rpl::event_stream<> _cancelRequests;
bool _recording = false;
bool _inField = false;
bool _inReplyEditForward = false;
bool _inClickable = false;
int _recordingSamples = 0;
int _recordCancelWidth;
rpl::lifetime _uploaderSubscriptions;
// This can animate for a very long time (like in music playing),
// so it should be a Basic, not a Simple animation.
Ui::Animations::Basic _recordingAnimation;
anim::value _recordingLevel;
Fn<void()> _raiseEmojiSuggestions;
};
} // namespace HistoryView

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_scheduled_section.h"
#include "history/view/history_view_compose_controls.h"
#include "history/view/history_view_top_bar_widget.h"
#include "history/view/history_view_list_widget.h"
#include "history/history.h"
@ -50,6 +51,10 @@ ScheduledWidget::ScheduledWidget(
, _scroll(this, st::historyScroll, false)
, _topBar(this, controller)
, _topBarShadow(this)
, _composeControls(std::make_unique<ComposeControls>(
this,
controller,
ComposeControls::Mode::Scheduled))
, _scrollDown(_scroll, st::historyToDown) {
_topBar->setActiveChat(_history, TopBarWidget::Section::Scheduled);
@ -83,6 +88,21 @@ ScheduledWidget::ScheduledWidget(
connect(_scroll, &Ui::ScrollArea::scrolled, [=] { onScroll(); });
setupScrollDownButton();
setupComposeControls();
}
ScheduledWidget::~ScheduledWidget() = default;
void ScheduledWidget::setupComposeControls() {
_composeControls->height(
) | rpl::start_with_next([=] {
updateControlsGeometry();
}, lifetime());
_composeControls->cancelRequests(
) | rpl::start_with_next([=] {
controller()->showBackFromStack();
}, lifetime());
}
void ScheduledWidget::setupScrollDownButton() {
@ -207,13 +227,14 @@ Dialogs::RowDescriptor ScheduledWidget::activeChat() const {
QPixmap ScheduledWidget::grabForShowAnimation(const Window::SectionSlideParams &params) {
_topBar->updateControlsVisibility();
if (params.withTopBarShadow) _topBarShadow->hide();
_composeControls->showForGrab();
auto result = Ui::GrabWidget(this);
if (params.withTopBarShadow) _topBarShadow->show();
return result;
}
void ScheduledWidget::doSetInnerFocus() {
_inner->setFocus();
_composeControls->focus();
}
bool ScheduledWidget::showInternal(
@ -254,6 +275,7 @@ void ScheduledWidget::resizeEvent(QResizeEvent *e) {
if (!width() || !height()) {
return;
}
_composeControls->resizeToWidth(width());
updateControlsGeometry();
}
@ -267,9 +289,8 @@ void ScheduledWidget::updateControlsGeometry() {
_topBarShadow->resize(contentWidth, st::lineWidth);
const auto bottom = height();
const auto scrollHeight = bottom
- _topBar->height();
// - _showNext->height();
const auto controlsHeight = _composeControls->heightCurrent();
const auto scrollHeight = bottom - _topBar->height() - controlsHeight;
const auto scrollSize = QSize(contentWidth, scrollHeight);
if (_scroll->size() != scrollSize) {
_skipScrollEvent = true;
@ -283,6 +304,7 @@ void ScheduledWidget::updateControlsGeometry() {
}
updateInnerVisibleArea();
}
_composeControls->move(0, bottom - controlsHeight);
updateScrollDownPosition();
}
@ -324,10 +346,12 @@ void ScheduledWidget::showAnimatedHook(
if (params.withTopBarShadow) {
_topBarShadow->show();
}
_composeControls->showStarted();
}
void ScheduledWidget::showFinishedHook() {
_topBar->setAnimatingMode(false);
_composeControls->showFinished();
}
bool ScheduledWidget::wheelEventFromFloatPlayer(QEvent *e) {

View File

@ -33,6 +33,7 @@ namespace HistoryView {
class Element;
class TopBarWidget;
class ScheduledMemento;
class ComposeControls;
class ScheduledWidget final
: public Window::SectionWidget
@ -42,6 +43,7 @@ public:
QWidget *parent,
not_null<Window::SessionController*> controller,
not_null<History*> history);
~ScheduledWidget();
not_null<History*> history() const;
Dialogs::RowDescriptor activeChat() const override;
@ -106,6 +108,8 @@ private:
void showAtPosition(Data::MessagePosition position);
bool showAtPositionNow(Data::MessagePosition position);
void setupComposeControls();
void setupScrollDownButton();
void scrollDownClicked();
void scrollDownAnimationFinish();
@ -121,6 +125,7 @@ private:
QPointer<ListWidget> _inner;
object_ptr<TopBarWidget> _topBar;
object_ptr<Ui::PlainShadow> _topBarShadow;
std::unique_ptr<ComposeControls> _composeControls;
bool _skipScrollEvent = false;
FullMsgId _highlightMessageId;

View File

@ -510,16 +510,21 @@ void TopBarWidget::refreshInfoButton() {
}
void TopBarWidget::resizeEvent(QResizeEvent *e) {
updateSearchVisibility();
updateControlsGeometry();
const auto smallDialogsColumn = _activeChat.folder()
&& (width() < _back->width() + _search->width());
_search->setVisible(!smallDialogsColumn);
}
int TopBarWidget::countSelectedButtonsTop(float64 selectedShown) {
return (1. - selectedShown) * (-st::topBarHeight);
}
void TopBarWidget::updateSearchVisibility() {
const auto historyMode = (_section == Section::History);
const auto smallDialogsColumn = _activeChat.folder()
&& (width() < _back->width() + _search->width());
_search->setVisible(historyMode && !smallDialogsColumn);
}
void TopBarWidget::updateControlsGeometry() {
auto hasSelected = (_selectedCount > 0);
auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.value(hasSelected ? 1. : 0.));
@ -620,9 +625,7 @@ void TopBarWidget::updateControlsVisibility() {
_unreadBadge->show();
}
const auto historyMode = (_section == Section::History);
const auto smallDialogsColumn = _activeChat.folder()
&& (width() < _back->width() + _search->width());
_search->setVisible(historyMode && !smallDialogsColumn);
updateSearchVisibility();
_menuToggle->setVisible(historyMode && !_activeChat.folder());
_infoToggle->setVisible(historyMode
&& !_activeChat.folder()

View File

@ -86,6 +86,7 @@ protected:
private:
void refreshInfoButton();
void refreshLang();
void updateSearchVisibility();
void updateControlsGeometry();
void selectedShowCallback();
void updateInfoToggleActive();

View File

@ -77,6 +77,11 @@ inline void DestroyChild(QWidget *child) {
delete child;
}
template <typename ...Args>
inline auto Connect(Args &&...args) {
return QObject::connect(std::forward<Args>(args)...);
}
void ResizeFitChild(
not_null<RpWidget*> parent,
not_null<RpWidget*> child);

View File

@ -318,6 +318,8 @@
<(src_loc)/history/view/media/history_view_wall_paper.cpp
<(src_loc)/history/view/media/history_view_web_page.h
<(src_loc)/history/view/media/history_view_web_page.cpp
<(src_loc)/history/view/history_view_compose_controls.cpp
<(src_loc)/history/view/history_view_compose_controls.h
<(src_loc)/history/view/history_view_contact_status.cpp
<(src_loc)/history/view/history_view_contact_status.h
<(src_loc)/history/view/history_view_context_menu.cpp