mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-08 08:04:08 +02:00
Use new message bar for pinned message.
This commit is contained in:
parent
ae298818a8
commit
67290eed58
6 changed files with 473 additions and 238 deletions
|
@ -561,6 +561,8 @@ PRIVATE
|
||||||
history/view/history_view_message.cpp
|
history/view/history_view_message.cpp
|
||||||
history/view/history_view_message.h
|
history/view/history_view_message.h
|
||||||
history/view/history_view_object.h
|
history/view/history_view_object.h
|
||||||
|
history/view/history_view_pinned_bar.cpp
|
||||||
|
history/view/history_view_pinned_bar.h
|
||||||
history/view/history_view_pinned_tracker.cpp
|
history/view/history_view_pinned_tracker.cpp
|
||||||
history/view/history_view_pinned_tracker.h
|
history/view/history_view_pinned_tracker.h
|
||||||
history/view/history_view_replies_section.cpp
|
history/view/history_view_replies_section.cpp
|
||||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/chat/message_bar.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
|
@ -62,6 +63,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_scheduled_section.h"
|
#include "history/view/history_view_scheduled_section.h"
|
||||||
#include "history/view/history_view_schedule_box.h"
|
#include "history/view/history_view_schedule_box.h"
|
||||||
#include "history/view/history_view_webpage_preview.h"
|
#include "history/view/history_view_webpage_preview.h"
|
||||||
|
#include "history/view/history_view_top_bar_widget.h"
|
||||||
|
#include "history/view/history_view_contact_status.h"
|
||||||
|
#include "history/view/history_view_pinned_tracker.h"
|
||||||
|
#include "history/view/history_view_pinned_bar.h"
|
||||||
#include "history/view/media/history_view_media.h"
|
#include "history/view/media/history_view_media.h"
|
||||||
#include "profile/profile_block_group_members.h"
|
#include "profile/profile_block_group_members.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
@ -86,9 +91,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "history/view/history_view_top_bar_widget.h"
|
|
||||||
#include "history/view/history_view_contact_status.h"
|
|
||||||
#include "history/view/history_view_pinned_tracker.h"
|
|
||||||
#include "base/qthelp_regex.h"
|
#include "base/qthelp_regex.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
|
@ -552,7 +554,6 @@ HistoryWidget::HistoryWidget(
|
||||||
UpdateFlag::Rights
|
UpdateFlag::Rights
|
||||||
| UpdateFlag::Migration
|
| UpdateFlag::Migration
|
||||||
| UpdateFlag::UnavailableReason
|
| UpdateFlag::UnavailableReason
|
||||||
| UpdateFlag::PinnedMessage
|
|
||||||
| UpdateFlag::IsBlocked
|
| UpdateFlag::IsBlocked
|
||||||
| UpdateFlag::Admins
|
| UpdateFlag::Admins
|
||||||
| UpdateFlag::Members
|
| UpdateFlag::Members
|
||||||
|
@ -590,14 +591,6 @@ HistoryWidget::HistoryWidget(
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
if (flags & UpdateFlag::PinnedMessage) {
|
|
||||||
if (pinnedMsgVisibilityUpdated()) {
|
|
||||||
updateHistoryGeometry();
|
|
||||||
updateControlsVisibility();
|
|
||||||
updateControlsGeometry();
|
|
||||||
this->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flags & UpdateFlag::Slowmode) {
|
if (flags & UpdateFlag::Slowmode) {
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
}
|
}
|
||||||
|
@ -1142,7 +1135,7 @@ void HistoryWidget::orderWidgets() {
|
||||||
_contactStatus->raise();
|
_contactStatus->raise();
|
||||||
}
|
}
|
||||||
if (_pinnedBar) {
|
if (_pinnedBar) {
|
||||||
_pinnedBar->shadow->raise();
|
_pinnedBar->raise();
|
||||||
}
|
}
|
||||||
_topShadow->raise();
|
_topShadow->raise();
|
||||||
if (_membersDropdown) {
|
if (_membersDropdown) {
|
||||||
|
@ -1698,7 +1691,7 @@ void HistoryWidget::showHistory(
|
||||||
_history->showAtMsgId = _showAtMsgId;
|
_history->showAtMsgId = _showAtMsgId;
|
||||||
|
|
||||||
destroyUnreadBarOnClose();
|
destroyUnreadBarOnClose();
|
||||||
showPinnedMessage(FullMsgId());
|
_pinnedBar = nullptr;
|
||||||
_pinnedTracker = nullptr;
|
_pinnedTracker = nullptr;
|
||||||
_membersDropdown.destroy();
|
_membersDropdown.destroy();
|
||||||
_scrollToAnimation.stop();
|
_scrollToAnimation.stop();
|
||||||
|
@ -1814,7 +1807,6 @@ void HistoryWidget::showHistory(
|
||||||
_updateHistoryItems.stop();
|
_updateHistoryItems.stop();
|
||||||
|
|
||||||
setupPinnedTracker();
|
setupPinnedTracker();
|
||||||
pinnedMsgVisibilityUpdated();
|
|
||||||
if (_history->scrollTopItem
|
if (_history->scrollTopItem
|
||||||
|| (_migrated && _migrated->scrollTopItem)
|
|| (_migrated && _migrated->scrollTopItem)
|
||||||
|| _history->isReadyFor(_showAtMsgId)) {
|
|| _history->isReadyFor(_showAtMsgId)) {
|
||||||
|
@ -2026,13 +2018,15 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
if (_tabbedPanel) {
|
if (_tabbedPanel) {
|
||||||
_tabbedPanel->hideFast();
|
_tabbedPanel->hideFast();
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar) {
|
||||||
|
_pinnedBar->hide();
|
||||||
|
}
|
||||||
hideChildren();
|
hideChildren();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pinnedBar) {
|
if (_pinnedBar) {
|
||||||
_pinnedBar->cancel->show();
|
_pinnedBar->show();
|
||||||
_pinnedBar->shadow->show();
|
|
||||||
}
|
}
|
||||||
if (_firstLoadRequest && !_scroll->isHidden()) {
|
if (_firstLoadRequest && !_scroll->isHidden()) {
|
||||||
_scroll->hide();
|
_scroll->hide();
|
||||||
|
@ -2242,7 +2236,7 @@ void HistoryWidget::showAboutTopPromotion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateMouseTracking() {
|
void HistoryWidget::updateMouseTracking() {
|
||||||
bool trackMouse = !_fieldBarCancel->isHidden() || _pinnedBar;
|
const auto trackMouse = !_fieldBarCancel->isHidden();
|
||||||
setMouseTracking(trackMouse);
|
setMouseTracking(trackMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3180,6 +3174,9 @@ void HistoryWidget::showAnimated(
|
||||||
if (_tabbedPanel) {
|
if (_tabbedPanel) {
|
||||||
_tabbedPanel->hideFast();
|
_tabbedPanel->hideFast();
|
||||||
}
|
}
|
||||||
|
if (_pinnedBar) {
|
||||||
|
_pinnedBar->hide();
|
||||||
|
}
|
||||||
hideChildren();
|
hideChildren();
|
||||||
if (params.withTopBarShadow) _topShadow->show();
|
if (params.withTopBarShadow) _topShadow->show();
|
||||||
|
|
||||||
|
@ -3336,14 +3333,12 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void HistoryWidget::updateOverStates(QPoint pos) {
|
void HistoryWidget::updateOverStates(QPoint pos) {
|
||||||
auto inField = pos.y() >= (_scroll->y() + _scroll->height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
|
auto inField = pos.y() >= (_scroll->y() + _scroll->height()) && pos.y() < height() && pos.x() >= 0 && pos.x() < width();
|
||||||
auto inReplyEditForward = QRect(st::historyReplySkip, _field->y() - st::historySendPadding - st::historyReplyHeight, width() - st::historyReplySkip - _fieldBarCancel->width(), st::historyReplyHeight).contains(pos) && (_editMsgId || replyToId() || readyToForward());
|
auto inReplyEditForward = QRect(st::historyReplySkip, _field->y() - st::historySendPadding - st::historyReplyHeight, width() - st::historyReplySkip - _fieldBarCancel->width(), st::historyReplyHeight).contains(pos) && (_editMsgId || replyToId() || readyToForward());
|
||||||
auto inPinnedMsg = QRect(0, _topBar->bottomNoMargins(), width(), st::historyReplyHeight).contains(pos) && _pinnedBar;
|
auto inClickable = inReplyEditForward;
|
||||||
auto inClickable = inReplyEditForward || inPinnedMsg;
|
|
||||||
if (inField != _inField && _recording) {
|
if (inField != _inField && _recording) {
|
||||||
_inField = inField;
|
_inField = inField;
|
||||||
_send->setRecordActive(_inField);
|
_send->setRecordActive(_inField);
|
||||||
}
|
}
|
||||||
_inReplyEditForward = inReplyEditForward;
|
_inReplyEditForward = inReplyEditForward;
|
||||||
_inPinnedMsg = inPinnedMsg;
|
|
||||||
if (inClickable != _inClickable) {
|
if (inClickable != _inClickable) {
|
||||||
_inClickable = inClickable;
|
_inClickable = inClickable;
|
||||||
setCursor(_inClickable ? style::cur_pointer : style::cur_default);
|
setCursor(_inClickable ? style::cur_pointer : style::cur_default);
|
||||||
|
@ -4442,10 +4437,10 @@ void HistoryWidget::updateControlsGeometry() {
|
||||||
|
|
||||||
const auto pinnedBarTop = _topBar->bottomNoMargins();
|
const auto pinnedBarTop = _topBar->bottomNoMargins();
|
||||||
if (_pinnedBar) {
|
if (_pinnedBar) {
|
||||||
_pinnedBar->cancel->moveToLeft(width() - _pinnedBar->cancel->width(), pinnedBarTop);
|
_pinnedBar->move(0, pinnedBarTop);
|
||||||
_pinnedBar->shadow->setGeometryToLeft(0, pinnedBarTop + st::historyReplyHeight, width(), st::lineWidth);
|
_pinnedBar->resizeToWidth(width());
|
||||||
}
|
}
|
||||||
const auto contactStatusTop = pinnedBarTop + (_pinnedBar ? st::historyReplyHeight : 0);
|
const auto contactStatusTop = pinnedBarTop + (_pinnedBar ? _pinnedBar->height() : 0);
|
||||||
if (_contactStatus) {
|
if (_contactStatus) {
|
||||||
_contactStatus->move(0, contactStatusTop);
|
_contactStatus->move(0, contactStatusTop);
|
||||||
}
|
}
|
||||||
|
@ -4487,9 +4482,6 @@ void HistoryWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
while (item == _replyReturn) {
|
while (item == _replyReturn) {
|
||||||
calcNextReplyReturn();
|
calcNextReplyReturn();
|
||||||
}
|
}
|
||||||
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
|
||||||
pinnedMsgVisibilityUpdated();
|
|
||||||
}
|
|
||||||
if (_kbReplyTo && item == _kbReplyTo) {
|
if (_kbReplyTo && item == _kbReplyTo) {
|
||||||
toggleKeyboard();
|
toggleKeyboard();
|
||||||
_kbReplyTo = nullptr;
|
_kbReplyTo = nullptr;
|
||||||
|
@ -4509,9 +4501,6 @@ void HistoryWidget::itemEdited(not_null<HistoryItem*> item) {
|
||||||
if (item.get() == _replyEditMsg) {
|
if (item.get() == _replyEditMsg) {
|
||||||
updateReplyEditTexts(true);
|
updateReplyEditTexts(true);
|
||||||
}
|
}
|
||||||
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
|
||||||
updatePinnedBar(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateScrollColors() {
|
void HistoryWidget::updateScrollColors() {
|
||||||
|
@ -4612,7 +4601,7 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
|
|
||||||
auto newScrollHeight = height() - _topBar->height();
|
auto newScrollHeight = height() - _topBar->height();
|
||||||
if (_pinnedBar) {
|
if (_pinnedBar) {
|
||||||
newScrollHeight -= st::historyReplyHeight;
|
newScrollHeight -= _pinnedBar->height();
|
||||||
}
|
}
|
||||||
if (_contactStatus) {
|
if (_contactStatus) {
|
||||||
newScrollHeight -= _contactStatus->height();
|
newScrollHeight -= _contactStatus->height();
|
||||||
|
@ -4848,7 +4837,7 @@ int HistoryWidget::computeMaxFieldHeight() const {
|
||||||
const auto available = height()
|
const auto available = height()
|
||||||
- _topBar->height()
|
- _topBar->height()
|
||||||
- (_contactStatus ? _contactStatus->height() : 0)
|
- (_contactStatus ? _contactStatus->height() : 0)
|
||||||
- (_pinnedBar ? st::historyReplyHeight : 0)
|
- (_pinnedBar ? _pinnedBar->height() : 0)
|
||||||
- ((_editMsgId
|
- ((_editMsgId
|
||||||
|| replyToId()
|
|| replyToId()
|
||||||
|| readyToForward()
|
|| readyToForward()
|
||||||
|
@ -4980,9 +4969,9 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
||||||
}
|
}
|
||||||
} else if (_inPinnedMsg) {
|
//} else if (_inPinnedMsg) { // #TODO pinned
|
||||||
Assert(_pinnedBar != nullptr);
|
// Assert(_pinnedBar != nullptr);
|
||||||
Ui::showPeerHistory(_peer, _pinnedBar->msgId);
|
// Ui::showPeerHistory(_peer, _pinnedBar->msgId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5189,48 +5178,6 @@ void HistoryWidget::sendInlineResult(
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryWidget::PinnedBar::PinnedBar(MsgId msgId, HistoryWidget *parent)
|
|
||||||
: msgId(msgId)
|
|
||||||
, cancel(parent, st::historyReplyCancel)
|
|
||||||
, shadow(parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
HistoryWidget::PinnedBar::~PinnedBar() {
|
|
||||||
cancel.destroyDelayed();
|
|
||||||
shadow.destroyDelayed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::updatePinnedBar(bool force) {
|
|
||||||
update();
|
|
||||||
if (!_pinnedBar) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto messageId = _pinnedBar->msgId;
|
|
||||||
if (!force) {
|
|
||||||
if (_pinnedBar->msg) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert(_history != nullptr);
|
|
||||||
if (!_pinnedBar->msg) {
|
|
||||||
_pinnedBar->msg = session().data().message(
|
|
||||||
_history->channelId(),
|
|
||||||
messageId);
|
|
||||||
}
|
|
||||||
if (_pinnedBar->msg) {
|
|
||||||
_pinnedBar->text.setText(
|
|
||||||
st::messageTextStyle,
|
|
||||||
_pinnedBar->msg->inReplyText(),
|
|
||||||
Ui::DialogTextOptions());
|
|
||||||
update();
|
|
||||||
} else if (force) {
|
|
||||||
destroyPinnedBar();
|
|
||||||
_history->peer->removePinnedMessage(messageId);
|
|
||||||
updateControlsGeometry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::updatePinnedViewer() {
|
void HistoryWidget::updatePinnedViewer() {
|
||||||
if (_firstLoadRequest
|
if (_firstLoadRequest
|
||||||
|| _delayedShowAtRequest
|
|| _delayedShowAtRequest
|
||||||
|
@ -5264,80 +5211,90 @@ void HistoryWidget::setupPinnedTracker() {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
_pinnedTracker = std::make_unique<HistoryView::PinnedTracker>(_history);
|
_pinnedTracker = std::make_unique<HistoryView::PinnedTracker>(_history);
|
||||||
_pinnedTracker->shownMessageId(
|
_pinnedBar = std::make_unique<HistoryView::PinnedBar>(
|
||||||
) | rpl::start_with_next([=](MsgId messageId) {
|
this,
|
||||||
showPinnedMessage({ peerToChannel(_peer->id), messageId });
|
&session(),
|
||||||
}, _list->lifetime());
|
_pinnedTracker->shownMessageId() | rpl::map([=](MsgId messageId) {
|
||||||
}
|
return FullMsgId{ peerToChannel(_peer->id), messageId };
|
||||||
|
}),
|
||||||
|
true);
|
||||||
|
|
||||||
void HistoryWidget::showPinnedMessage(FullMsgId id) {
|
_pinnedBar->closeClicks(
|
||||||
if (_pinnedId == id) {
|
) | rpl::start_with_next([=] {
|
||||||
return;
|
|
||||||
}
|
|
||||||
_pinnedId = id;
|
|
||||||
if (pinnedMsgVisibilityUpdated()) {
|
|
||||||
updateHistoryGeometry();
|
|
||||||
updateControlsVisibility();
|
|
||||||
updateControlsGeometry();
|
|
||||||
this->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HistoryWidget::pinnedMsgVisibilityUpdated() {
|
|
||||||
auto result = false;
|
|
||||||
auto pinnedId = _pinnedId;
|
|
||||||
if (pinnedId && !_peer->canPinMessages()) {
|
|
||||||
const auto hiddenId = session().settings().hiddenPinnedMessageId(
|
|
||||||
_peer->id);
|
|
||||||
if (hiddenId == pinnedId.msg) {
|
|
||||||
pinnedId = FullMsgId();
|
|
||||||
} else if (hiddenId) {
|
|
||||||
session().settings().setHiddenPinnedMessageId(_peer->id, 0);
|
|
||||||
session().saveSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pinnedId) {
|
|
||||||
if (!_pinnedBar) {
|
|
||||||
_pinnedBar = std::make_unique<PinnedBar>(pinnedId.msg, this);
|
|
||||||
if (_a_show.animating()) {
|
|
||||||
_pinnedBar->cancel->hide();
|
|
||||||
_pinnedBar->shadow->hide();
|
|
||||||
} else {
|
|
||||||
_pinnedBar->cancel->show();
|
|
||||||
_pinnedBar->shadow->show();
|
|
||||||
}
|
|
||||||
_pinnedBar->cancel->addClickHandler([=] {
|
|
||||||
hidePinnedMessage();
|
hidePinnedMessage();
|
||||||
});
|
}, _pinnedBar->lifetime());
|
||||||
orderWidgets();
|
|
||||||
|
|
||||||
updatePinnedBar();
|
_pinnedBarHeight = 0;
|
||||||
result = true;
|
_pinnedBar->heightValue(
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
const auto barTop = unreadBarTop();
|
_topDelta = (height - _pinnedBarHeight);
|
||||||
if (!barTop || _scroll->scrollTop() != *barTop) {
|
_pinnedBarHeight = height;
|
||||||
synteticScrollToY(_scroll->scrollTop() + st::historyReplyHeight);
|
updateHistoryGeometry();
|
||||||
}
|
|
||||||
} else if (_pinnedBar->msgId != pinnedId.msg) {
|
|
||||||
_pinnedBar->msgId = pinnedId.msg;
|
|
||||||
_pinnedBar->msg = nullptr;
|
|
||||||
_pinnedBar->text.clear();
|
|
||||||
updatePinnedBar();
|
|
||||||
}
|
|
||||||
if (!_pinnedBar->msg) {
|
|
||||||
requestMessageData(_pinnedBar->msgId);
|
|
||||||
}
|
|
||||||
} else if (_pinnedBar) {
|
|
||||||
destroyPinnedBar();
|
|
||||||
result = true;
|
|
||||||
const auto barTop = unreadBarTop();
|
|
||||||
if (!barTop || _scroll->scrollTop() != *barTop) {
|
|
||||||
synteticScrollToY(_scroll->scrollTop() - st::historyReplyHeight);
|
|
||||||
}
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
_topDelta = 0;
|
||||||
|
}, _pinnedBar->lifetime());
|
||||||
|
orderWidgets();
|
||||||
|
if (_a_show.animating()) {
|
||||||
|
_pinnedBar->hide();
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//bool HistoryWidget::pinnedMsgVisibilityUpdated() {
|
||||||
|
// auto result = false;
|
||||||
|
// auto pinnedId = _pinnedId;
|
||||||
|
// if (pinnedId && !_peer->canPinMessages()) {
|
||||||
|
// const auto hiddenId = session().settings().hiddenPinnedMessageId(
|
||||||
|
// _peer->id);
|
||||||
|
// if (hiddenId == pinnedId.msg) {
|
||||||
|
// pinnedId = FullMsgId();
|
||||||
|
// } else if (hiddenId) {
|
||||||
|
// session().settings().setHiddenPinnedMessageId(_peer->id, 0);
|
||||||
|
// session().saveSettings();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (pinnedId) {
|
||||||
|
// if (!_pinnedBar) {
|
||||||
|
// _pinnedBar = std::make_unique<PinnedBar>(pinnedId.msg, this);
|
||||||
|
// if (_a_show.animating()) {
|
||||||
|
// _pinnedBar->cancel->hide();
|
||||||
|
// _pinnedBar->bar->widget()->hide();
|
||||||
|
// _pinnedBar->shadow->hide();
|
||||||
|
// } else {
|
||||||
|
// _pinnedBar->cancel->show();
|
||||||
|
// _pinnedBar->bar->widget()->show();
|
||||||
|
// _pinnedBar->shadow->show();
|
||||||
|
// }
|
||||||
|
// _pinnedBar->cancel->addClickHandler([=] {
|
||||||
|
// hidePinnedMessage();
|
||||||
|
// });
|
||||||
|
// orderWidgets();
|
||||||
|
//
|
||||||
|
// updatePinnedBar();
|
||||||
|
// result = true;
|
||||||
|
//
|
||||||
|
// const auto barTop = unreadBarTop();
|
||||||
|
// if (!barTop || _scroll->scrollTop() != *barTop) {
|
||||||
|
// synteticScrollToY(_scroll->scrollTop() + st::historyReplyHeight);
|
||||||
|
// }
|
||||||
|
// } else if (_pinnedBar->msgId != pinnedId.msg) {
|
||||||
|
// _pinnedBar->msgId = pinnedId.msg;
|
||||||
|
// _pinnedBar->msg = nullptr;
|
||||||
|
// updatePinnedBar();
|
||||||
|
// }
|
||||||
|
// if (!_pinnedBar->msg) {
|
||||||
|
// requestMessageData(_pinnedBar->msgId);
|
||||||
|
// }
|
||||||
|
// } else if (_pinnedBar) {
|
||||||
|
// destroyPinnedBar();
|
||||||
|
// result = true;
|
||||||
|
// const auto barTop = unreadBarTop();
|
||||||
|
// if (!barTop || _scroll->scrollTop() != *barTop) {
|
||||||
|
// synteticScrollToY(_scroll->scrollTop() - st::historyReplyHeight);
|
||||||
|
// }
|
||||||
|
// updateControlsGeometry();
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
//}
|
||||||
|
|
||||||
void HistoryWidget::requestMessageData(MsgId msgId) {
|
void HistoryWidget::requestMessageData(MsgId msgId) {
|
||||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||||
|
@ -5349,11 +5306,6 @@ void HistoryWidget::requestMessageData(MsgId msgId) {
|
||||||
crl::guard(this, callback));
|
crl::guard(this, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::destroyPinnedBar() {
|
|
||||||
_pinnedBar.reset();
|
|
||||||
_inPinnedMsg = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HistoryWidget::sendExistingDocument(
|
bool HistoryWidget::sendExistingDocument(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
Api::SendOptions options) {
|
Api::SendOptions options) {
|
||||||
|
@ -5622,25 +5574,25 @@ void HistoryWidget::UnpinMessage(not_null<PeerData*> peer, MsgId msgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::hidePinnedMessage() {
|
void HistoryWidget::hidePinnedMessage() {
|
||||||
const auto pinnedId = _pinnedId;
|
//const auto pinnedId = _pinnedId; // #TODO pinned
|
||||||
if (!pinnedId) {
|
//if (!pinnedId) {
|
||||||
if (pinnedMsgVisibilityUpdated()) {
|
// if (pinnedMsgVisibilityUpdated()) {
|
||||||
updateControlsGeometry();
|
// updateControlsGeometry();
|
||||||
update();
|
// update();
|
||||||
}
|
// }
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (_peer->canPinMessages()) {
|
//if (_peer->canPinMessages()) {
|
||||||
unpinMessage(pinnedId);
|
// unpinMessage(pinnedId);
|
||||||
} else {
|
//} else {
|
||||||
session().settings().setHiddenPinnedMessageId(_peer->id, pinnedId.msg);
|
// session().settings().setHiddenPinnedMessageId(_peer->id, pinnedId.msg);
|
||||||
session().saveSettings();
|
// session().saveSettings();
|
||||||
if (pinnedMsgVisibilityUpdated()) {
|
// if (pinnedMsgVisibilityUpdated()) {
|
||||||
updateControlsGeometry();
|
// updateControlsGeometry();
|
||||||
update();
|
// update();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
||||||
|
@ -6080,13 +6032,12 @@ void HistoryWidget::updateTopBarSelection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
void HistoryWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||||
if (!_peer || _peer->asChannel() != channel || !msgId) return;
|
if (!_peer || _peer->asChannel() != channel || !msgId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_editMsgId == msgId || _replyToId == msgId) {
|
if (_editMsgId == msgId || _replyToId == msgId) {
|
||||||
updateReplyEditTexts(true);
|
updateReplyEditTexts(true);
|
||||||
}
|
}
|
||||||
if (_pinnedBar && _pinnedBar->msgId == msgId) {
|
|
||||||
updatePinnedBar(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
|
void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
|
||||||
|
@ -6420,49 +6371,49 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
||||||
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
|
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
|
||||||
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, tr::lng_record_cancel(tr::now));
|
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, tr::lng_record_cancel(tr::now));
|
||||||
}
|
}
|
||||||
|
//
|
||||||
void HistoryWidget::drawPinnedBar(Painter &p) {
|
//void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||||
Expects(_pinnedBar != nullptr);
|
// Expects(_pinnedBar != nullptr);
|
||||||
|
//
|
||||||
auto top = _topBar->bottomNoMargins();
|
// auto top = _topBar->bottomNoMargins();
|
||||||
p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
// p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||||
|
//
|
||||||
top += st::msgReplyPadding.top();
|
// top += st::msgReplyPadding.top();
|
||||||
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
// QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||||
p.fillRect(rbar, st::msgInReplyBarColor);
|
// p.fillRect(rbar, st::msgInReplyBarColor);
|
||||||
|
//
|
||||||
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
// //int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
if (_pinnedBar->msg) {
|
// //if (_pinnedBar->msg) {
|
||||||
const auto media = _pinnedBar->msg->media();
|
// // const auto media = _pinnedBar->msg->media();
|
||||||
if (media && media->hasReplyPreview()) {
|
// // if (media && media->hasReplyPreview()) {
|
||||||
if (const auto image = media->replyPreview()) {
|
// // if (const auto image = media->replyPreview()) {
|
||||||
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
// // QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
||||||
p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
|
// // p.drawPixmap(to.x(), to.y(), image->pixSingle(image->width() / cIntRetinaFactor(), image->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
|
||||||
}
|
// // }
|
||||||
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
// // left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||||
}
|
// // }
|
||||||
p.setPen(st::historyReplyNameFg);
|
// // p.setPen(st::historyReplyNameFg);
|
||||||
p.setFont(st::msgServiceNameFont);
|
// // p.setFont(st::msgServiceNameFont);
|
||||||
const auto poll = media ? media->poll() : nullptr;
|
// // const auto poll = media ? media->poll() : nullptr;
|
||||||
const auto pinnedHeader = (_pinnedBar->msgId < _peer->topPinnedMessageId())
|
// // const auto pinnedHeader = (_pinnedBar->msgId < _peer->topPinnedMessageId())
|
||||||
? tr::lng_pinned_previous(tr::now)
|
// // ? tr::lng_pinned_previous(tr::now)
|
||||||
: !poll
|
// // : !poll
|
||||||
? tr::lng_pinned_message(tr::now)
|
// // ? tr::lng_pinned_message(tr::now)
|
||||||
: poll->quiz()
|
// // : poll->quiz()
|
||||||
? tr::lng_pinned_quiz(tr::now)
|
// // ? tr::lng_pinned_quiz(tr::now)
|
||||||
: tr::lng_pinned_poll(tr::now);
|
// // : tr::lng_pinned_poll(tr::now);
|
||||||
p.drawText(left, top + st::msgServiceNameFont->ascent, pinnedHeader);
|
// // p.drawText(left, top + st::msgServiceNameFont->ascent, pinnedHeader);
|
||||||
|
//
|
||||||
p.setPen(st::historyComposeAreaFg);
|
// // p.setPen(st::historyComposeAreaFg);
|
||||||
p.setTextPalette(st::historyComposeAreaPalette);
|
// // p.setTextPalette(st::historyComposeAreaPalette);
|
||||||
_pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
// // _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||||
p.restoreTextPalette();
|
// // p.restoreTextPalette();
|
||||||
} else {
|
// //} else {
|
||||||
p.setFont(st::msgDateFont);
|
// // p.setFont(st::msgDateFont);
|
||||||
p.setPen(st::historyComposeAreaFgService);
|
// // p.setPen(st::historyComposeAreaFgService);
|
||||||
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
|
// // p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
|
||||||
}
|
// //}
|
||||||
}
|
//}
|
||||||
|
|
||||||
bool HistoryWidget::paintShowAnimationFrame() {
|
bool HistoryWidget::paintShowAnimationFrame() {
|
||||||
auto progress = _a_show.value(1.);
|
auto progress = _a_show.value(1.);
|
||||||
|
@ -6513,9 +6464,6 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
} else if (const auto error = writeRestriction()) {
|
} else if (const auto error = writeRestriction()) {
|
||||||
drawRestrictedWrite(p, *error);
|
drawRestrictedWrite(p, *error);
|
||||||
}
|
}
|
||||||
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
|
|
||||||
drawPinnedBar(p);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const auto w = st::msgServiceFont->width(tr::lng_willbe_history(tr::now))
|
const auto w = st::msgServiceFont->width(tr::lng_willbe_history(tr::now))
|
||||||
+ st::msgPadding.left()
|
+ st::msgPadding.left()
|
||||||
|
|
|
@ -66,6 +66,7 @@ class SilentToggle;
|
||||||
class FlatButton;
|
class FlatButton;
|
||||||
class LinkButton;
|
class LinkButton;
|
||||||
class RoundButton;
|
class RoundButton;
|
||||||
|
class MessageBar;
|
||||||
namespace Toast {
|
namespace Toast {
|
||||||
class Instance;
|
class Instance;
|
||||||
} // namespace Toast
|
} // namespace Toast
|
||||||
|
@ -94,6 +95,7 @@ class TopBarWidget;
|
||||||
class ContactStatus;
|
class ContactStatus;
|
||||||
class Element;
|
class Element;
|
||||||
class PinnedTracker;
|
class PinnedTracker;
|
||||||
|
class PinnedBar;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
class DragArea;
|
class DragArea;
|
||||||
|
@ -326,16 +328,6 @@ private slots:
|
||||||
private:
|
private:
|
||||||
using TabbedPanel = ChatHelpers::TabbedPanel;
|
using TabbedPanel = ChatHelpers::TabbedPanel;
|
||||||
using TabbedSelector = ChatHelpers::TabbedSelector;
|
using TabbedSelector = ChatHelpers::TabbedSelector;
|
||||||
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 {
|
enum ScrollChangeType {
|
||||||
ScrollChangeNone,
|
ScrollChangeNone,
|
||||||
|
|
||||||
|
@ -492,10 +484,6 @@ private:
|
||||||
void updateReplyEditTexts(bool force = false);
|
void updateReplyEditTexts(bool force = false);
|
||||||
void updateReplyEditText(not_null<HistoryItem*> item);
|
void updateReplyEditText(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void showPinnedMessage(FullMsgId id);
|
|
||||||
void updatePinnedBar(bool force = false);
|
|
||||||
bool pinnedMsgVisibilityUpdated();
|
|
||||||
void destroyPinnedBar();
|
|
||||||
void updatePinnedViewer();
|
void updatePinnedViewer();
|
||||||
void setupPinnedTracker();
|
void setupPinnedTracker();
|
||||||
|
|
||||||
|
@ -511,7 +499,6 @@ private:
|
||||||
int left,
|
int left,
|
||||||
int top) const;
|
int top) const;
|
||||||
void drawRecording(Painter &p, float64 recordActive);
|
void drawRecording(Painter &p, float64 recordActive);
|
||||||
void drawPinnedBar(Painter &p);
|
|
||||||
void drawRestrictedWrite(Painter &p, const QString &error);
|
void drawRestrictedWrite(Painter &p, const QString &error);
|
||||||
bool paintShowAnimationFrame();
|
bool paintShowAnimationFrame();
|
||||||
|
|
||||||
|
@ -614,9 +601,9 @@ private:
|
||||||
|
|
||||||
object_ptr<Ui::IconButton> _fieldBarCancel;
|
object_ptr<Ui::IconButton> _fieldBarCancel;
|
||||||
|
|
||||||
FullMsgId _pinnedId;
|
|
||||||
std::unique_ptr<PinnedBar> _pinnedBar;
|
|
||||||
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
|
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
|
||||||
|
std::unique_ptr<HistoryView::PinnedBar> _pinnedBar;
|
||||||
|
int _pinnedBarHeight = 0;
|
||||||
|
|
||||||
mtpRequestId _saveEditMsgRequestId = 0;
|
mtpRequestId _saveEditMsgRequestId = 0;
|
||||||
|
|
||||||
|
@ -705,7 +692,6 @@ private:
|
||||||
bool _recording = false;
|
bool _recording = false;
|
||||||
bool _inField = false;
|
bool _inField = false;
|
||||||
bool _inReplyEditForward = false;
|
bool _inReplyEditForward = false;
|
||||||
bool _inPinnedMsg = false;
|
|
||||||
bool _inClickable = false;
|
bool _inClickable = false;
|
||||||
int _recordingSamples = 0;
|
int _recordingSamples = 0;
|
||||||
int _recordCancelWidth;
|
int _recordCancelWidth;
|
||||||
|
|
229
Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp
Normal file
229
Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
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_pinned_bar.h"
|
||||||
|
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_changes.h"
|
||||||
|
#include "data/data_poll.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
||||||
|
not_null<HistoryItem*> item) {
|
||||||
|
return item->history()->session().changes().messageFlagsValue(
|
||||||
|
item,
|
||||||
|
Data::MessageUpdate::Flag::Edited
|
||||||
|
) | rpl::map([=] {
|
||||||
|
const auto media = item->media();
|
||||||
|
const auto poll = media ? media->poll() : nullptr;
|
||||||
|
return Ui::MessageBarContent{
|
||||||
|
.id = item->id,
|
||||||
|
.title = ((item->id < item->history()->peer->topPinnedMessageId())
|
||||||
|
? tr::lng_pinned_previous(tr::now)
|
||||||
|
: !poll
|
||||||
|
? tr::lng_pinned_message(tr::now)
|
||||||
|
: poll->quiz()
|
||||||
|
? tr::lng_pinned_quiz(tr::now)
|
||||||
|
: tr::lng_pinned_poll(tr::now)),
|
||||||
|
.text = item->inReplyText(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
FullMsgId id,
|
||||||
|
bool alreadyLoaded = false) {
|
||||||
|
if (!id) {
|
||||||
|
return rpl::single(Ui::MessageBarContent());
|
||||||
|
} else if (const auto item = session->data().message(id)) {
|
||||||
|
return ContentByItem(item);
|
||||||
|
} else if (alreadyLoaded) {
|
||||||
|
return rpl::single(Ui::MessageBarContent()); // Deleted message?..
|
||||||
|
}
|
||||||
|
auto load = rpl::make_producer<Ui::MessageBarContent>([=](auto consumer) {
|
||||||
|
consumer.put_next(Ui::MessageBarContent{
|
||||||
|
.text = tr::lng_contacts_loading(tr::now),
|
||||||
|
});
|
||||||
|
const auto channel = id.channel
|
||||||
|
? session->data().channel(id.channel).get()
|
||||||
|
: nullptr;
|
||||||
|
const auto callback = [=](ChannelData *channel, MsgId id) {
|
||||||
|
consumer.put_done();
|
||||||
|
};
|
||||||
|
session->api().requestMessageData(channel, id.msg, callback);
|
||||||
|
return rpl::lifetime();
|
||||||
|
});
|
||||||
|
return std::move(
|
||||||
|
load
|
||||||
|
) | rpl::then(rpl::deferred([=] {
|
||||||
|
return ContentByItemId(session, id, true);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
PinnedBar::PinnedBar(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<FullMsgId> itemId,
|
||||||
|
bool withClose)
|
||||||
|
: _wrap(parent, object_ptr<Ui::RpWidget>(parent))
|
||||||
|
, _close(withClose
|
||||||
|
? std::make_unique<Ui::IconButton>(
|
||||||
|
_wrap.entity(),
|
||||||
|
st::historyReplyCancel)
|
||||||
|
: nullptr)
|
||||||
|
, _shadow(std::make_unique<Ui::PlainShadow>(_wrap.parentWidget())) {
|
||||||
|
_wrap.hide(anim::type::instant);
|
||||||
|
_shadow->hide();
|
||||||
|
|
||||||
|
_wrap.entity()->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
QPainter(_wrap.entity()).fillRect(clip, st::historyPinnedBg);
|
||||||
|
}, lifetime());
|
||||||
|
_wrap.setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
|
rpl::duplicate(
|
||||||
|
itemId
|
||||||
|
) | rpl::distinct_until_changed(
|
||||||
|
) | rpl::map([=](FullMsgId id) {
|
||||||
|
return ContentByItemId(session, id);
|
||||||
|
}) | rpl::flatten_latest(
|
||||||
|
) | rpl::filter([=](const Ui::MessageBarContent &content) {
|
||||||
|
return !content.title.isEmpty() || !content.text.text.isEmpty();
|
||||||
|
}) | rpl::start_with_next([=](Ui::MessageBarContent &&content) {
|
||||||
|
const auto creating = !_bar;
|
||||||
|
if (creating) {
|
||||||
|
createControls();
|
||||||
|
}
|
||||||
|
_bar->set(std::move(content));
|
||||||
|
if (creating) {
|
||||||
|
_bar->finishAnimating();
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
std::move(
|
||||||
|
itemId
|
||||||
|
) | rpl::map([=](FullMsgId id) {
|
||||||
|
return !id;
|
||||||
|
}) | rpl::start_with_next([=](bool hidden) {
|
||||||
|
_shouldBeShown = !hidden;
|
||||||
|
if (!_forceHidden) {
|
||||||
|
_wrap.toggle(_shouldBeShown, anim::type::normal);
|
||||||
|
} else if (!_shouldBeShown) {
|
||||||
|
_bar = nullptr;
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::createControls() {
|
||||||
|
Expects(!_bar);
|
||||||
|
|
||||||
|
_bar = std::make_unique<Ui::MessageBar>(
|
||||||
|
_wrap.entity(),
|
||||||
|
st::defaultMessageBar);
|
||||||
|
if (_close) {
|
||||||
|
_close->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
_bar->widget()->move(0, 0);
|
||||||
|
_bar->widget()->show();
|
||||||
|
_wrap.entity()->resize(_wrap.entity()->width(), _bar->widget()->height());
|
||||||
|
|
||||||
|
_wrap.geometryValue(
|
||||||
|
) | rpl::start_with_next([=](QRect rect) {
|
||||||
|
_shadow->setGeometry(
|
||||||
|
rect.x(),
|
||||||
|
rect.y() + rect.height(),
|
||||||
|
rect.width(),
|
||||||
|
st::lineWidth);
|
||||||
|
_bar->widget()->resizeToWidth(
|
||||||
|
rect.width() - (_close ? _close->width() : 0));
|
||||||
|
const auto hidden = _wrap.isHidden() || !rect.height();
|
||||||
|
if (_shadow->isHidden() != hidden) {
|
||||||
|
_shadow->setVisible(!hidden);
|
||||||
|
}
|
||||||
|
if (_close) {
|
||||||
|
_close->moveToRight(0, 0);
|
||||||
|
}
|
||||||
|
}, _bar->widget()->lifetime());
|
||||||
|
|
||||||
|
_wrap.shownValue(
|
||||||
|
) | rpl::skip(
|
||||||
|
1
|
||||||
|
) | rpl::filter([=](bool shown) {
|
||||||
|
return !shown && !_forceHidden;
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
_bar = nullptr;
|
||||||
|
}, _bar->widget()->lifetime());
|
||||||
|
|
||||||
|
Ensures(_bar != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::show() {
|
||||||
|
if (!_forceHidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_forceHidden = false;
|
||||||
|
if (_shouldBeShown) {
|
||||||
|
_wrap.show(anim::type::instant);
|
||||||
|
_shadow->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::hide() {
|
||||||
|
if (_forceHidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_forceHidden = true;
|
||||||
|
_wrap.hide(anim::type::instant);
|
||||||
|
_shadow->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::raise() {
|
||||||
|
_wrap.raise();
|
||||||
|
_shadow->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::move(int x, int y) {
|
||||||
|
_wrap.move(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedBar::resizeToWidth(int width) {
|
||||||
|
_wrap.entity()->resizeToWidth(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PinnedBar::height() const {
|
||||||
|
return !_forceHidden
|
||||||
|
? _wrap.height()
|
||||||
|
: _shouldBeShown
|
||||||
|
? st::historyReplyHeight
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<int> PinnedBar::heightValue() const {
|
||||||
|
return _wrap.heightValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> PinnedBar::closeClicks() const {
|
||||||
|
return !_close
|
||||||
|
? (rpl::never<>() | rpl::type_erased())
|
||||||
|
: (_close->clicks() | rpl::map([] { return rpl::empty_value(); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
59
Telegram/SourceFiles/history/view/history_view_pinned_bar.h
Normal file
59
Telegram/SourceFiles/history/view/history_view_pinned_bar.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
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/wrap/slide_wrap.h"
|
||||||
|
#include "ui/chat/message_bar.h"
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class IconButton;
|
||||||
|
class PlainShadow;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
|
||||||
|
class PinnedBar final {
|
||||||
|
public:
|
||||||
|
PinnedBar(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<FullMsgId> itemId,
|
||||||
|
bool withClose = false);
|
||||||
|
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
|
void raise();
|
||||||
|
|
||||||
|
void move(int x, int y);
|
||||||
|
void resizeToWidth(int width);
|
||||||
|
[[nodiscard]] int height() const;
|
||||||
|
[[nodiscard]] rpl::producer<int> heightValue() const;
|
||||||
|
[[nodiscard]] rpl::producer<> closeClicks() const;
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
|
return _wrap.lifetime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createControls();
|
||||||
|
|
||||||
|
Ui::SlideWrap<> _wrap;
|
||||||
|
std::unique_ptr<Ui::MessageBar> _bar;
|
||||||
|
std::unique_ptr<Ui::IconButton> _close;
|
||||||
|
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||||
|
rpl::event_stream<Ui::MessageBarContent> _content;
|
||||||
|
bool _shouldBeShown = false;
|
||||||
|
bool _forceHidden = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/palette.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
@ -205,7 +206,7 @@ void MessageBar::paint(Painter &p) {
|
||||||
const auto imageShown = _animation
|
const auto imageShown = _animation
|
||||||
? _animation->imageShown.value(imageFinal)
|
? _animation->imageShown.value(imageFinal)
|
||||||
: imageFinal;
|
: imageFinal;
|
||||||
if (progress == 1. && imageShown == 1. && _animation) {
|
if (progress == 1. && imageShown == imageFinal && _animation) {
|
||||||
_animation = nullptr;
|
_animation = nullptr;
|
||||||
}
|
}
|
||||||
const auto body = [&] {
|
const auto body = [&] {
|
||||||
|
@ -237,6 +238,13 @@ void MessageBar::paint(Painter &p) {
|
||||||
? (shiftTo - shiftFull)
|
? (shiftTo - shiftFull)
|
||||||
: (shiftTo + shiftFull);
|
: (shiftTo + shiftFull);
|
||||||
|
|
||||||
|
const auto bar = QRect(
|
||||||
|
st::msgReplyBarSkip + st::msgReplyBarPos.x(),
|
||||||
|
st::msgReplyPadding.top() + st::msgReplyBarPos.y(),
|
||||||
|
st::msgReplyBarSize.width(),
|
||||||
|
st::msgReplyBarSize.height());
|
||||||
|
p.fillRect(bar, st::msgInReplyBarColor);
|
||||||
|
|
||||||
if (!_animation) {
|
if (!_animation) {
|
||||||
if (!_image.isNull()) {
|
if (!_image.isNull()) {
|
||||||
p.drawPixmap(image, _image);
|
p.drawPixmap(image, _image);
|
||||||
|
@ -261,6 +269,7 @@ void MessageBar::paint(Painter &p) {
|
||||||
_animation->imageFrom);
|
_animation->imageFrom);
|
||||||
p.setOpacity(progress);
|
p.setOpacity(progress);
|
||||||
p.drawPixmap(rect.translated(0, shiftTo), _animation->imageTo);
|
p.drawPixmap(rect.translated(0, shiftTo), _animation->imageTo);
|
||||||
|
p.setOpacity(1.);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmap(rect, _image);
|
p.drawPixmap(rect, _image);
|
||||||
}
|
}
|
||||||
|
@ -277,6 +286,7 @@ void MessageBar::paint(Painter &p) {
|
||||||
_animation->bodyOrTextFrom);
|
_animation->bodyOrTextFrom);
|
||||||
p.setOpacity(progress);
|
p.setOpacity(progress);
|
||||||
p.drawPixmap(body.x(), text.y() + shiftTo, _animation->bodyOrTextTo);
|
p.drawPixmap(body.x(), text.y() + shiftTo, _animation->bodyOrTextTo);
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
if (!_animation || _animation->bodyAnimation != BodyAnimation::Full) {
|
if (!_animation || _animation->bodyAnimation != BodyAnimation::Full) {
|
||||||
p.setPen(_st.titleFg);
|
p.setPen(_st.titleFg);
|
||||||
|
@ -289,6 +299,7 @@ void MessageBar::paint(Painter &p) {
|
||||||
_animation->bodyOrTextFrom);
|
_animation->bodyOrTextFrom);
|
||||||
p.setOpacity(progress);
|
p.setOpacity(progress);
|
||||||
p.drawPixmap(body.x(), body.y() + shiftTo, _animation->bodyOrTextTo);
|
p.drawPixmap(body.x(), body.y() + shiftTo, _animation->bodyOrTextTo);
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue