mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 23:53:58 +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.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.h
|
||||
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/text/text_utilities.h" // Ui::Text::ToUpper
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/chat/message_bar.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/special_buttons.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_schedule_box.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 "profile/profile_block_group_members.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 "core/application.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 "ui/widgets/popup_menu.h"
|
||||
#include "ui/item_text_options.h"
|
||||
|
@ -552,7 +554,6 @@ HistoryWidget::HistoryWidget(
|
|||
UpdateFlag::Rights
|
||||
| UpdateFlag::Migration
|
||||
| UpdateFlag::UnavailableReason
|
||||
| UpdateFlag::PinnedMessage
|
||||
| UpdateFlag::IsBlocked
|
||||
| UpdateFlag::Admins
|
||||
| UpdateFlag::Members
|
||||
|
@ -590,14 +591,6 @@ HistoryWidget::HistoryWidget(
|
|||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (flags & UpdateFlag::PinnedMessage) {
|
||||
if (pinnedMsgVisibilityUpdated()) {
|
||||
updateHistoryGeometry();
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
if (flags & UpdateFlag::Slowmode) {
|
||||
updateSendButtonType();
|
||||
}
|
||||
|
@ -1142,7 +1135,7 @@ void HistoryWidget::orderWidgets() {
|
|||
_contactStatus->raise();
|
||||
}
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->shadow->raise();
|
||||
_pinnedBar->raise();
|
||||
}
|
||||
_topShadow->raise();
|
||||
if (_membersDropdown) {
|
||||
|
@ -1698,7 +1691,7 @@ void HistoryWidget::showHistory(
|
|||
_history->showAtMsgId = _showAtMsgId;
|
||||
|
||||
destroyUnreadBarOnClose();
|
||||
showPinnedMessage(FullMsgId());
|
||||
_pinnedBar = nullptr;
|
||||
_pinnedTracker = nullptr;
|
||||
_membersDropdown.destroy();
|
||||
_scrollToAnimation.stop();
|
||||
|
@ -1814,7 +1807,6 @@ void HistoryWidget::showHistory(
|
|||
_updateHistoryItems.stop();
|
||||
|
||||
setupPinnedTracker();
|
||||
pinnedMsgVisibilityUpdated();
|
||||
if (_history->scrollTopItem
|
||||
|| (_migrated && _migrated->scrollTopItem)
|
||||
|| _history->isReadyFor(_showAtMsgId)) {
|
||||
|
@ -2026,13 +2018,15 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hideFast();
|
||||
}
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->hide();
|
||||
}
|
||||
hideChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->cancel->show();
|
||||
_pinnedBar->shadow->show();
|
||||
_pinnedBar->show();
|
||||
}
|
||||
if (_firstLoadRequest && !_scroll->isHidden()) {
|
||||
_scroll->hide();
|
||||
|
@ -2242,7 +2236,7 @@ void HistoryWidget::showAboutTopPromotion() {
|
|||
}
|
||||
|
||||
void HistoryWidget::updateMouseTracking() {
|
||||
bool trackMouse = !_fieldBarCancel->isHidden() || _pinnedBar;
|
||||
const auto trackMouse = !_fieldBarCancel->isHidden();
|
||||
setMouseTracking(trackMouse);
|
||||
}
|
||||
|
||||
|
@ -3180,6 +3174,9 @@ void HistoryWidget::showAnimated(
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hideFast();
|
||||
}
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->hide();
|
||||
}
|
||||
hideChildren();
|
||||
if (params.withTopBarShadow) _topShadow->show();
|
||||
|
||||
|
@ -3336,14 +3333,12 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
|||
void HistoryWidget::updateOverStates(QPoint pos) {
|
||||
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 inPinnedMsg = QRect(0, _topBar->bottomNoMargins(), width(), st::historyReplyHeight).contains(pos) && _pinnedBar;
|
||||
auto inClickable = inReplyEditForward || inPinnedMsg;
|
||||
auto inClickable = inReplyEditForward;
|
||||
if (inField != _inField && _recording) {
|
||||
_inField = inField;
|
||||
_send->setRecordActive(_inField);
|
||||
}
|
||||
_inReplyEditForward = inReplyEditForward;
|
||||
_inPinnedMsg = inPinnedMsg;
|
||||
if (inClickable != _inClickable) {
|
||||
_inClickable = inClickable;
|
||||
setCursor(_inClickable ? style::cur_pointer : style::cur_default);
|
||||
|
@ -4442,10 +4437,10 @@ void HistoryWidget::updateControlsGeometry() {
|
|||
|
||||
const auto pinnedBarTop = _topBar->bottomNoMargins();
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->cancel->moveToLeft(width() - _pinnedBar->cancel->width(), pinnedBarTop);
|
||||
_pinnedBar->shadow->setGeometryToLeft(0, pinnedBarTop + st::historyReplyHeight, width(), st::lineWidth);
|
||||
_pinnedBar->move(0, pinnedBarTop);
|
||||
_pinnedBar->resizeToWidth(width());
|
||||
}
|
||||
const auto contactStatusTop = pinnedBarTop + (_pinnedBar ? st::historyReplyHeight : 0);
|
||||
const auto contactStatusTop = pinnedBarTop + (_pinnedBar ? _pinnedBar->height() : 0);
|
||||
if (_contactStatus) {
|
||||
_contactStatus->move(0, contactStatusTop);
|
||||
}
|
||||
|
@ -4487,9 +4482,6 @@ void HistoryWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
|||
while (item == _replyReturn) {
|
||||
calcNextReplyReturn();
|
||||
}
|
||||
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
||||
pinnedMsgVisibilityUpdated();
|
||||
}
|
||||
if (_kbReplyTo && item == _kbReplyTo) {
|
||||
toggleKeyboard();
|
||||
_kbReplyTo = nullptr;
|
||||
|
@ -4509,9 +4501,6 @@ void HistoryWidget::itemEdited(not_null<HistoryItem*> item) {
|
|||
if (item.get() == _replyEditMsg) {
|
||||
updateReplyEditTexts(true);
|
||||
}
|
||||
if (_pinnedBar && item->id == _pinnedBar->msgId) {
|
||||
updatePinnedBar(true);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::updateScrollColors() {
|
||||
|
@ -4612,7 +4601,7 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
|
||||
auto newScrollHeight = height() - _topBar->height();
|
||||
if (_pinnedBar) {
|
||||
newScrollHeight -= st::historyReplyHeight;
|
||||
newScrollHeight -= _pinnedBar->height();
|
||||
}
|
||||
if (_contactStatus) {
|
||||
newScrollHeight -= _contactStatus->height();
|
||||
|
@ -4848,7 +4837,7 @@ int HistoryWidget::computeMaxFieldHeight() const {
|
|||
const auto available = height()
|
||||
- _topBar->height()
|
||||
- (_contactStatus ? _contactStatus->height() : 0)
|
||||
- (_pinnedBar ? st::historyReplyHeight : 0)
|
||||
- (_pinnedBar ? _pinnedBar->height() : 0)
|
||||
- ((_editMsgId
|
||||
|| replyToId()
|
||||
|| readyToForward()
|
||||
|
@ -4980,9 +4969,9 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
|||
} else {
|
||||
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
||||
}
|
||||
} else if (_inPinnedMsg) {
|
||||
Assert(_pinnedBar != nullptr);
|
||||
Ui::showPeerHistory(_peer, _pinnedBar->msgId);
|
||||
//} else if (_inPinnedMsg) { // #TODO pinned
|
||||
// Assert(_pinnedBar != nullptr);
|
||||
// Ui::showPeerHistory(_peer, _pinnedBar->msgId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5189,48 +5178,6 @@ void HistoryWidget::sendInlineResult(
|
|||
_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() {
|
||||
if (_firstLoadRequest
|
||||
|| _delayedShowAtRequest
|
||||
|
@ -5264,80 +5211,90 @@ void HistoryWidget::setupPinnedTracker() {
|
|||
Expects(_history != nullptr);
|
||||
|
||||
_pinnedTracker = std::make_unique<HistoryView::PinnedTracker>(_history);
|
||||
_pinnedTracker->shownMessageId(
|
||||
) | rpl::start_with_next([=](MsgId messageId) {
|
||||
showPinnedMessage({ peerToChannel(_peer->id), messageId });
|
||||
}, _list->lifetime());
|
||||
}
|
||||
_pinnedBar = std::make_unique<HistoryView::PinnedBar>(
|
||||
this,
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId() | rpl::map([=](MsgId messageId) {
|
||||
return FullMsgId{ peerToChannel(_peer->id), messageId };
|
||||
}),
|
||||
true);
|
||||
|
||||
void HistoryWidget::showPinnedMessage(FullMsgId id) {
|
||||
if (_pinnedId == id) {
|
||||
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([=] {
|
||||
_pinnedBar->closeClicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
hidePinnedMessage();
|
||||
});
|
||||
orderWidgets();
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
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;
|
||||
_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);
|
||||
}
|
||||
_pinnedBarHeight = 0;
|
||||
_pinnedBar->heightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
_topDelta = (height - _pinnedBarHeight);
|
||||
_pinnedBarHeight = height;
|
||||
updateHistoryGeometry();
|
||||
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) {
|
||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||
|
@ -5349,11 +5306,6 @@ void HistoryWidget::requestMessageData(MsgId msgId) {
|
|||
crl::guard(this, callback));
|
||||
}
|
||||
|
||||
void HistoryWidget::destroyPinnedBar() {
|
||||
_pinnedBar.reset();
|
||||
_inPinnedMsg = false;
|
||||
}
|
||||
|
||||
bool HistoryWidget::sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
Api::SendOptions options) {
|
||||
|
@ -5622,25 +5574,25 @@ void HistoryWidget::UnpinMessage(not_null<PeerData*> peer, MsgId msgId) {
|
|||
}
|
||||
|
||||
void HistoryWidget::hidePinnedMessage() {
|
||||
const auto pinnedId = _pinnedId;
|
||||
if (!pinnedId) {
|
||||
if (pinnedMsgVisibilityUpdated()) {
|
||||
updateControlsGeometry();
|
||||
update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
//const auto pinnedId = _pinnedId; // #TODO pinned
|
||||
//if (!pinnedId) {
|
||||
// if (pinnedMsgVisibilityUpdated()) {
|
||||
// updateControlsGeometry();
|
||||
// update();
|
||||
// }
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (_peer->canPinMessages()) {
|
||||
unpinMessage(pinnedId);
|
||||
} else {
|
||||
session().settings().setHiddenPinnedMessageId(_peer->id, pinnedId.msg);
|
||||
session().saveSettings();
|
||||
if (pinnedMsgVisibilityUpdated()) {
|
||||
updateControlsGeometry();
|
||||
update();
|
||||
}
|
||||
}
|
||||
//if (_peer->canPinMessages()) {
|
||||
// unpinMessage(pinnedId);
|
||||
//} else {
|
||||
// session().settings().setHiddenPinnedMessageId(_peer->id, pinnedId.msg);
|
||||
// session().saveSettings();
|
||||
// if (pinnedMsgVisibilityUpdated()) {
|
||||
// updateControlsGeometry();
|
||||
// update();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
||||
|
@ -6080,13 +6032,12 @@ void HistoryWidget::updateTopBarSelection() {
|
|||
}
|
||||
|
||||
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) {
|
||||
updateReplyEditTexts(true);
|
||||
}
|
||||
if (_pinnedBar && _pinnedBar->msgId == msgId) {
|
||||
updatePinnedBar(true);
|
||||
}
|
||||
}
|
||||
|
||||
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.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, tr::lng_record_cancel(tr::now));
|
||||
}
|
||||
|
||||
void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
Expects(_pinnedBar != nullptr);
|
||||
|
||||
auto top = _topBar->bottomNoMargins();
|
||||
p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||
|
||||
top += st::msgReplyPadding.top();
|
||||
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||
p.fillRect(rbar, st::msgInReplyBarColor);
|
||||
|
||||
int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||
if (_pinnedBar->msg) {
|
||||
const auto media = _pinnedBar->msg->media();
|
||||
if (media && media->hasReplyPreview()) {
|
||||
if (const auto image = media->replyPreview()) {
|
||||
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));
|
||||
}
|
||||
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||
}
|
||||
p.setPen(st::historyReplyNameFg);
|
||||
p.setFont(st::msgServiceNameFont);
|
||||
const auto poll = media ? media->poll() : nullptr;
|
||||
const auto pinnedHeader = (_pinnedBar->msgId < _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);
|
||||
p.drawText(left, top + st::msgServiceNameFont->ascent, pinnedHeader);
|
||||
|
||||
p.setPen(st::historyComposeAreaFg);
|
||||
p.setTextPalette(st::historyComposeAreaPalette);
|
||||
_pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||
p.restoreTextPalette();
|
||||
} else {
|
||||
p.setFont(st::msgDateFont);
|
||||
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()));
|
||||
}
|
||||
}
|
||||
//
|
||||
//void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
// Expects(_pinnedBar != nullptr);
|
||||
//
|
||||
// auto top = _topBar->bottomNoMargins();
|
||||
// p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||
//
|
||||
// top += st::msgReplyPadding.top();
|
||||
// QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||
// p.fillRect(rbar, st::msgInReplyBarColor);
|
||||
//
|
||||
// //int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||
// //if (_pinnedBar->msg) {
|
||||
// // const auto media = _pinnedBar->msg->media();
|
||||
// // if (media && media->hasReplyPreview()) {
|
||||
// // if (const auto image = media->replyPreview()) {
|
||||
// // 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));
|
||||
// // }
|
||||
// // left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||
// // }
|
||||
// // p.setPen(st::historyReplyNameFg);
|
||||
// // p.setFont(st::msgServiceNameFont);
|
||||
// // const auto poll = media ? media->poll() : nullptr;
|
||||
// // const auto pinnedHeader = (_pinnedBar->msgId < _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);
|
||||
// // p.drawText(left, top + st::msgServiceNameFont->ascent, pinnedHeader);
|
||||
//
|
||||
// // p.setPen(st::historyComposeAreaFg);
|
||||
// // p.setTextPalette(st::historyComposeAreaPalette);
|
||||
// // _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||
// // p.restoreTextPalette();
|
||||
// //} else {
|
||||
// // p.setFont(st::msgDateFont);
|
||||
// // 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()));
|
||||
// //}
|
||||
//}
|
||||
|
||||
bool HistoryWidget::paintShowAnimationFrame() {
|
||||
auto progress = _a_show.value(1.);
|
||||
|
@ -6513,9 +6464,6 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
|||
} else if (const auto error = writeRestriction()) {
|
||||
drawRestrictedWrite(p, *error);
|
||||
}
|
||||
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
|
||||
drawPinnedBar(p);
|
||||
}
|
||||
} else {
|
||||
const auto w = st::msgServiceFont->width(tr::lng_willbe_history(tr::now))
|
||||
+ st::msgPadding.left()
|
||||
|
|
|
@ -66,6 +66,7 @@ class SilentToggle;
|
|||
class FlatButton;
|
||||
class LinkButton;
|
||||
class RoundButton;
|
||||
class MessageBar;
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
|
@ -94,6 +95,7 @@ class TopBarWidget;
|
|||
class ContactStatus;
|
||||
class Element;
|
||||
class PinnedTracker;
|
||||
class PinnedBar;
|
||||
} // namespace HistoryView
|
||||
|
||||
class DragArea;
|
||||
|
@ -326,16 +328,6 @@ private slots:
|
|||
private:
|
||||
using TabbedPanel = ChatHelpers::TabbedPanel;
|
||||
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 {
|
||||
ScrollChangeNone,
|
||||
|
||||
|
@ -492,10 +484,6 @@ private:
|
|||
void updateReplyEditTexts(bool force = false);
|
||||
void updateReplyEditText(not_null<HistoryItem*> item);
|
||||
|
||||
void showPinnedMessage(FullMsgId id);
|
||||
void updatePinnedBar(bool force = false);
|
||||
bool pinnedMsgVisibilityUpdated();
|
||||
void destroyPinnedBar();
|
||||
void updatePinnedViewer();
|
||||
void setupPinnedTracker();
|
||||
|
||||
|
@ -511,7 +499,6 @@ private:
|
|||
int left,
|
||||
int top) const;
|
||||
void drawRecording(Painter &p, float64 recordActive);
|
||||
void drawPinnedBar(Painter &p);
|
||||
void drawRestrictedWrite(Painter &p, const QString &error);
|
||||
bool paintShowAnimationFrame();
|
||||
|
||||
|
@ -614,9 +601,9 @@ private:
|
|||
|
||||
object_ptr<Ui::IconButton> _fieldBarCancel;
|
||||
|
||||
FullMsgId _pinnedId;
|
||||
std::unique_ptr<PinnedBar> _pinnedBar;
|
||||
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
|
||||
std::unique_ptr<HistoryView::PinnedBar> _pinnedBar;
|
||||
int _pinnedBarHeight = 0;
|
||||
|
||||
mtpRequestId _saveEditMsgRequestId = 0;
|
||||
|
||||
|
@ -705,7 +692,6 @@ private:
|
|||
bool _recording = false;
|
||||
bool _inField = false;
|
||||
bool _inReplyEditForward = false;
|
||||
bool _inPinnedMsg = false;
|
||||
bool _inClickable = false;
|
||||
int _recordingSamples = 0;
|
||||
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 "styles/style_chat.h"
|
||||
#include "styles/palette.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -205,7 +206,7 @@ void MessageBar::paint(Painter &p) {
|
|||
const auto imageShown = _animation
|
||||
? _animation->imageShown.value(imageFinal)
|
||||
: imageFinal;
|
||||
if (progress == 1. && imageShown == 1. && _animation) {
|
||||
if (progress == 1. && imageShown == imageFinal && _animation) {
|
||||
_animation = nullptr;
|
||||
}
|
||||
const auto body = [&] {
|
||||
|
@ -237,6 +238,13 @@ void MessageBar::paint(Painter &p) {
|
|||
? (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 (!_image.isNull()) {
|
||||
p.drawPixmap(image, _image);
|
||||
|
@ -261,6 +269,7 @@ void MessageBar::paint(Painter &p) {
|
|||
_animation->imageFrom);
|
||||
p.setOpacity(progress);
|
||||
p.drawPixmap(rect.translated(0, shiftTo), _animation->imageTo);
|
||||
p.setOpacity(1.);
|
||||
} else {
|
||||
p.drawPixmap(rect, _image);
|
||||
}
|
||||
|
@ -277,6 +286,7 @@ void MessageBar::paint(Painter &p) {
|
|||
_animation->bodyOrTextFrom);
|
||||
p.setOpacity(progress);
|
||||
p.drawPixmap(body.x(), text.y() + shiftTo, _animation->bodyOrTextTo);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
if (!_animation || _animation->bodyAnimation != BodyAnimation::Full) {
|
||||
p.setPen(_st.titleFg);
|
||||
|
@ -289,6 +299,7 @@ void MessageBar::paint(Painter &p) {
|
|||
_animation->bodyOrTextFrom);
|
||||
p.setOpacity(progress);
|
||||
p.drawPixmap(body.x(), body.y() + shiftTo, _animation->bodyOrTextTo);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue