mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Add button to show all pinned messages.
This commit is contained in:
parent
6b38b94db4
commit
d742fa32de
13 changed files with 99 additions and 224 deletions
BIN
Telegram/Resources/icons/pinned_show_all.png
Normal file
BIN
Telegram/Resources/icons/pinned_show_all.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 642 B |
BIN
Telegram/Resources/icons/pinned_show_all@2x.png
Normal file
BIN
Telegram/Resources/icons/pinned_show_all@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/Resources/icons/pinned_show_all@3x.png
Normal file
BIN
Telegram/Resources/icons/pinned_show_all@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -5239,10 +5239,22 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
messageId.count
|
||||
};
|
||||
});
|
||||
auto barContent = HistoryView::PinnedBarContent(
|
||||
&session(),
|
||||
std::move(shown));
|
||||
_pinnedBar = std::make_unique<Ui::PinnedBar>(
|
||||
this,
|
||||
HistoryView::PinnedBarContent(&session(), std::move(shown)),
|
||||
true);
|
||||
std::move(barContent));
|
||||
Info::Profile::SharedMediaCountValue(
|
||||
_peer,
|
||||
nullptr,
|
||||
Storage::SharedMediaType::Pinned
|
||||
) | rpl::map([=](int count) {
|
||||
return (count > 1);
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](bool many) {
|
||||
refreshPinnedBarButton(many);
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
rpl::single(
|
||||
rpl::empty_value()
|
||||
|
@ -5259,18 +5271,11 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
});
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
_pinnedBar->closeClicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
hidePinnedMessage();
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
_pinnedBar->barClicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto id = _pinnedTracker->currentMessageId();
|
||||
if (id.message) {
|
||||
controller()->showSection(
|
||||
HistoryView::PinnedMemento(_history, id.message));
|
||||
//Ui::showPeerHistory(_peer, id.message);
|
||||
Ui::showPeerHistory(_peer, id.message);
|
||||
}
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
|
@ -5291,6 +5296,26 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::refreshPinnedBarButton(bool many) {
|
||||
const auto close = !many;
|
||||
auto button = object_ptr<Ui::IconButton>(
|
||||
this,
|
||||
close ? st::historyReplyCancel : st::historyPinnedShowAll);
|
||||
button->clicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (close) {
|
||||
hidePinnedMessage();
|
||||
} else {
|
||||
const auto id = _pinnedTracker->currentMessageId();
|
||||
if (id.message) {
|
||||
controller()->showSection(
|
||||
HistoryView::PinnedMemento(_history, id.message));
|
||||
}
|
||||
}
|
||||
}, button->lifetime());
|
||||
_pinnedBar->setRightButton(std::move(button));
|
||||
}
|
||||
|
||||
void HistoryWidget::requestMessageData(MsgId msgId) {
|
||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||
messageDataReceived(channel, msgId);
|
||||
|
|
|
@ -481,6 +481,7 @@ private:
|
|||
void updatePinnedViewer();
|
||||
void setupPinnedTracker();
|
||||
void checkPinnedBarState();
|
||||
void refreshPinnedBarButton(bool many);
|
||||
|
||||
void sendInlineResult(
|
||||
not_null<InlineBots::Result*> result,
|
||||
|
|
|
@ -56,6 +56,19 @@ namespace {
|
|||
|
||||
} // namespace
|
||||
|
||||
PinnedMemento::PinnedMemento(
|
||||
not_null<History*> history,
|
||||
MsgId highlightId)
|
||||
: _history(history)
|
||||
, _highlightId(highlightId) {
|
||||
_list.setAroundPosition({
|
||||
.fullId = FullMsgId(
|
||||
history->channelId(),
|
||||
highlightId),
|
||||
.date = TimeId(0),
|
||||
});
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> PinnedMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
|
|
|
@ -148,12 +148,9 @@ private:
|
|||
|
||||
class PinnedMemento : public Window::SectionMemento {
|
||||
public:
|
||||
PinnedMemento(
|
||||
explicit PinnedMemento(
|
||||
not_null<History*> history,
|
||||
MsgId highlightId = 0)
|
||||
: _history(history)
|
||||
, _highlightId(highlightId) {
|
||||
}
|
||||
MsgId highlightId = 0);
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
|
|
|
@ -12,19 +12,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_peer.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "main/main_session.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
namespace{
|
||||
|
||||
constexpr auto kLoadedLimit = 4;
|
||||
constexpr auto kPerPage = 40;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -37,10 +34,7 @@ PinnedTracker::PinnedTracker(not_null<History*> history) : _history(history) {
|
|||
}, _lifetime);
|
||||
}
|
||||
|
||||
PinnedTracker::~PinnedTracker() {
|
||||
_history->owner().histories().cancelRequest(_beforeRequestId);
|
||||
_history->owner().histories().cancelRequest(_afterRequestId);
|
||||
}
|
||||
PinnedTracker::~PinnedTracker() = default;
|
||||
|
||||
rpl::producer<PinnedId> PinnedTracker::shownMessageId() const {
|
||||
return _current.value();
|
||||
|
@ -90,16 +84,6 @@ void PinnedTracker::setupViewer(not_null<Data::PinnedMessages*> data) {
|
|||
const auto empty = snapshot.ids.empty();
|
||||
const auto before = (i - begin(snapshot.ids));
|
||||
const auto after = (end(snapshot.ids) - i);
|
||||
//if (before < kLoadedLimit && !snapshot.skippedBefore) {
|
||||
// load(
|
||||
// Data::LoadDirection::Before,
|
||||
// empty ? _aroundId : snapshot.ids.front());
|
||||
//}
|
||||
//if (after < kLoadedLimit && !snapshot.skippedAfter) {
|
||||
// load(
|
||||
// Data::LoadDirection::After,
|
||||
// empty ? _aroundId : snapshot.ids.back());
|
||||
//}
|
||||
if (snapshot.ids.empty()) {
|
||||
_current = PinnedId();
|
||||
return;
|
||||
|
@ -119,156 +103,5 @@ void PinnedTracker::setupViewer(not_null<Data::PinnedMessages*> data) {
|
|||
}
|
||||
}, _dataLifetime);
|
||||
}
|
||||
//
|
||||
//void PinnedTracker::load(Data::LoadDirection direction, MsgId id) {
|
||||
// const auto requestId = (direction == Data::LoadDirection::Before)
|
||||
// ? &_beforeRequestId
|
||||
// : &_afterRequestId;
|
||||
// const auto aroundId = (direction == Data::LoadDirection::Before)
|
||||
// ? &_beforeId
|
||||
// : &_afterId;
|
||||
// if (*requestId) {
|
||||
// if (*aroundId == id) {
|
||||
// return;
|
||||
// }
|
||||
// _history->owner().histories().cancelRequest(*requestId);
|
||||
// }
|
||||
// *aroundId = id;
|
||||
// const auto send = [=](Fn<void()> finish) {
|
||||
// const auto offsetId = [&] {
|
||||
// switch (direction) {
|
||||
// case Data::LoadDirection::Before: return id;
|
||||
// case Data::LoadDirection::After: return id + 1;
|
||||
// }
|
||||
// Unexpected("Direction in PinnedTracker::load");
|
||||
// }();
|
||||
// const auto addOffset = [&] {
|
||||
// switch (direction) {
|
||||
// case Data::LoadDirection::Before: return 0;
|
||||
// case Data::LoadDirection::After: return -kPerPage;
|
||||
// }
|
||||
// Unexpected("Direction in PinnedTracker::load");
|
||||
// }();
|
||||
// return _history->session().api().request(MTPmessages_Search(
|
||||
// MTP_flags(0),
|
||||
// _history->peer->input,
|
||||
// MTP_string(QString()),
|
||||
// MTP_inputPeerEmpty(),
|
||||
// MTPint(), // top_msg_id
|
||||
// MTP_inputMessagesFilterPinned(),
|
||||
// MTP_int(0),
|
||||
// MTP_int(0),
|
||||
// MTP_int(offsetId),
|
||||
// MTP_int(addOffset),
|
||||
// MTP_int(kPerPage),
|
||||
// MTP_int(0), // max_id
|
||||
// MTP_int(0), // min_id
|
||||
// MTP_int(0) // hash
|
||||
// )).done([=](const MTPmessages_Messages &result) {
|
||||
// *aroundId = 0;
|
||||
// *requestId = 0;
|
||||
// finish();
|
||||
//
|
||||
// apply(direction, id, result);
|
||||
// }).fail([=](const RPCError &error) {
|
||||
// *aroundId = 0;
|
||||
// *requestId = 0;
|
||||
// finish();
|
||||
// }).send();
|
||||
// };
|
||||
// _beforeRequestId = _history->owner().histories().sendRequest(
|
||||
// _history,
|
||||
// Data::Histories::RequestType::History,
|
||||
// send);
|
||||
//}
|
||||
//
|
||||
//void PinnedTracker::apply(
|
||||
// Data::LoadDirection direction,
|
||||
// MsgId aroundId,
|
||||
// const MTPmessages_Messages &result) {
|
||||
// auto noSkipRange = MsgRange{ aroundId, aroundId };
|
||||
// auto fullCount = std::optional<int>();
|
||||
// auto messages = [&] {
|
||||
// switch (result.type()) {
|
||||
// case mtpc_messages_messages: {
|
||||
// auto &d = result.c_messages_messages();
|
||||
// _history->owner().processUsers(d.vusers());
|
||||
// _history->owner().processChats(d.vchats());
|
||||
// fullCount = d.vmessages().v.size();
|
||||
// return &d.vmessages().v;
|
||||
// } break;
|
||||
//
|
||||
// case mtpc_messages_messagesSlice: {
|
||||
// auto &d = result.c_messages_messagesSlice();
|
||||
// _history->owner().processUsers(d.vusers());
|
||||
// _history->owner().processChats(d.vchats());
|
||||
// fullCount = d.vcount().v;
|
||||
// return &d.vmessages().v;
|
||||
// } break;
|
||||
//
|
||||
// case mtpc_messages_channelMessages: {
|
||||
// auto &d = result.c_messages_channelMessages();
|
||||
// if (auto channel = _history->peer->asChannel()) {
|
||||
// channel->ptsReceived(d.vpts().v);
|
||||
// } else {
|
||||
// LOG(("API Error: received messages.channelMessages when "
|
||||
// "no channel was passed! (PinnedTracker::apply)"));
|
||||
// }
|
||||
// _history->owner().processUsers(d.vusers());
|
||||
// _history->owner().processChats(d.vchats());
|
||||
// fullCount = d.vcount().v;
|
||||
// return &d.vmessages().v;
|
||||
// } break;
|
||||
//
|
||||
// case mtpc_messages_messagesNotModified: {
|
||||
// LOG(("API Error: received messages.messagesNotModified! "
|
||||
// "(PinnedTracker::apply)"));
|
||||
// return (const QVector<MTPMessage>*)nullptr;
|
||||
// } break;
|
||||
// }
|
||||
// Unexpected("messages.Messages type in PinnedTracker::apply.");
|
||||
// }();
|
||||
//
|
||||
// if (!messages) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// const auto addType = NewMessageType::Existing;
|
||||
// auto list = std::vector<MsgId>();
|
||||
// list.reserve(messages->size());
|
||||
// for (const auto &message : *messages) {
|
||||
// const auto item = _history->owner().addNewMessage(
|
||||
// message,
|
||||
// MTPDmessage_ClientFlags(),
|
||||
// addType);
|
||||
// if (item) {
|
||||
// const auto itemId = item->id;
|
||||
// if (item->isPinned()) {
|
||||
// list.push_back(itemId);
|
||||
// }
|
||||
// accumulate_min(noSkipRange.from, itemId);
|
||||
// accumulate_max(noSkipRange.till, itemId);
|
||||
// }
|
||||
// }
|
||||
// if (aroundId && list.empty()) {
|
||||
// noSkipRange = [&]() -> MsgRange {
|
||||
// switch (direction) {
|
||||
// case Data::LoadDirection::Before: // All old loaded.
|
||||
// return { 0, noSkipRange.till };
|
||||
// case Data::LoadDirection::Around: // All loaded.
|
||||
// return { 0, ServerMaxMsgId };
|
||||
// case Data::LoadDirection::After: // All new loaded.
|
||||
// return { noSkipRange.from, ServerMaxMsgId };
|
||||
// }
|
||||
// Unexpected("Direction in PinnedTracker::apply.");
|
||||
// }();
|
||||
// }
|
||||
// _history->session().storage().add(Storage::SharedMediaAddSlice(
|
||||
// _history->peer->id,
|
||||
// Storage::SharedMediaType::Pinned,
|
||||
// std::move(list),
|
||||
// noSkipRange,
|
||||
// fullCount));
|
||||
//}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -48,11 +48,6 @@ public:
|
|||
private:
|
||||
void refreshData();
|
||||
void setupViewer(not_null<Data::PinnedMessages*> data);
|
||||
//void load(Data::LoadDirection direction, MsgId id);
|
||||
//void apply(
|
||||
// Data::LoadDirection direction,
|
||||
// MsgId aroundId,
|
||||
// const MTPmessages_Messages &result);
|
||||
|
||||
const not_null<History*> _history;
|
||||
|
||||
|
@ -61,10 +56,6 @@ private:
|
|||
rpl::lifetime _dataLifetime;
|
||||
|
||||
MsgId _aroundId = 0;
|
||||
MsgId _beforeId = 0;
|
||||
MsgId _afterId = 0;
|
||||
MsgId _beforeRequestId = 0;
|
||||
MsgId _afterRequestId = 0;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
|
|
|
@ -111,9 +111,10 @@ RepliesMemento::RepliesMemento(
|
|||
: RepliesMemento(commentsItem->history(), commentsItem->id, commentId) {
|
||||
if (commentId) {
|
||||
_list.setAroundPosition({
|
||||
.fullId = FullMsgId(commentsItem->history()->channelId(), commentId),
|
||||
.fullId = FullMsgId(
|
||||
commentsItem->history()->channelId(),
|
||||
commentId),
|
||||
.date = TimeId(0),
|
||||
|
||||
});
|
||||
} else if (commentsItem->computeRepliesInboxReadTillFull() == MsgId(1)) {
|
||||
_list.setAroundPosition(Data::MinMessagePosition);
|
||||
|
|
|
@ -361,6 +361,10 @@ historyReplyCancel: IconButton {
|
|||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
historyPinnedShowAll: IconButton(historyReplyCancel) {
|
||||
icon: icon {{ "pinned_show_all", historyReplyCancelFg }};
|
||||
iconOver: icon {{ "pinned_show_all", historyReplyCancelFgOver }};
|
||||
}
|
||||
|
||||
msgBotKbDuration: 200;
|
||||
msgBotKbFont: semiboldFont;
|
||||
|
|
|
@ -19,14 +19,8 @@ namespace Ui {
|
|||
|
||||
PinnedBar::PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<MessageBarContent> content,
|
||||
bool withClose)
|
||||
rpl::producer<MessageBarContent> content)
|
||||
: _wrap(parent, object_ptr<RpWidget>(parent))
|
||||
, _close(withClose
|
||||
? std::make_unique<IconButton>(
|
||||
_wrap.entity(),
|
||||
st::historyReplyCancel)
|
||||
: nullptr)
|
||||
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget())) {
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
|
@ -73,7 +67,33 @@ PinnedBar::PinnedBar(
|
|||
}, lifetime());
|
||||
}
|
||||
|
||||
PinnedBar::~PinnedBar() = default;
|
||||
PinnedBar::~PinnedBar() {
|
||||
_rightButton.destroy();
|
||||
}
|
||||
|
||||
void PinnedBar::setRightButton(object_ptr<Ui::RpWidget> button) {
|
||||
_rightButton.destroy();
|
||||
_rightButton = std::move(button);
|
||||
if (_rightButton) {
|
||||
_rightButton->setParent(_wrap.entity());
|
||||
_rightButton->show();
|
||||
}
|
||||
if (_bar) {
|
||||
updateControlsGeometry(_wrap.geometry());
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedBar::updateControlsGeometry(QRect wrapGeometry) {
|
||||
_bar->widget()->resizeToWidth(
|
||||
wrapGeometry.width() - (_rightButton ? _rightButton->width() : 0));
|
||||
const auto hidden = _wrap.isHidden() || !wrapGeometry.height();
|
||||
if (_shadow->isHidden() != hidden) {
|
||||
_shadow->setVisible(!hidden);
|
||||
}
|
||||
if (_rightButton) {
|
||||
_rightButton->moveToRight(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedBar::setShadowGeometryPostprocess(Fn<QRect(QRect)> postprocess) {
|
||||
_shadowGeometryPostprocess = std::move(postprocess);
|
||||
|
@ -97,8 +117,8 @@ void PinnedBar::createControls() {
|
|||
_bar = std::make_unique<MessageBar>(
|
||||
_wrap.entity(),
|
||||
st::defaultMessageBar);
|
||||
if (_close) {
|
||||
_close->raise();
|
||||
if (_rightButton) {
|
||||
_rightButton->raise();
|
||||
}
|
||||
|
||||
// Clicks.
|
||||
|
@ -126,15 +146,7 @@ void PinnedBar::createControls() {
|
|||
_wrap.geometryValue(
|
||||
) | rpl::start_with_next([=](QRect rect) {
|
||||
updateShadowGeometry(rect);
|
||||
_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);
|
||||
}
|
||||
updateControlsGeometry(rect);
|
||||
}, _bar->widget()->lifetime());
|
||||
|
||||
_wrap.shownValue(
|
||||
|
@ -198,12 +210,6 @@ 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(); }));
|
||||
}
|
||||
|
||||
rpl::producer<> PinnedBar::barClicks() const {
|
||||
return _barClicks.events();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ 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 "base/object_ptr.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -14,13 +16,13 @@ struct MessageBarContent;
|
|||
class MessageBar;
|
||||
class IconButton;
|
||||
class PlainShadow;
|
||||
class RpWidget;
|
||||
|
||||
class PinnedBar final {
|
||||
public:
|
||||
PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<Ui::MessageBarContent> content,
|
||||
bool withClose = false);
|
||||
rpl::producer<Ui::MessageBarContent> content);
|
||||
~PinnedBar();
|
||||
|
||||
void show();
|
||||
|
@ -30,11 +32,12 @@ public:
|
|||
|
||||
void setShadowGeometryPostprocess(Fn<QRect(QRect)> postprocess);
|
||||
|
||||
void setRightButton(object_ptr<Ui::RpWidget> button);
|
||||
|
||||
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::producer<> barClicks() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
|
@ -44,10 +47,11 @@ public:
|
|||
private:
|
||||
void createControls();
|
||||
void updateShadowGeometry(QRect wrapGeometry);
|
||||
void updateControlsGeometry(QRect wrapGeometry);
|
||||
|
||||
Ui::SlideWrap<> _wrap;
|
||||
std::unique_ptr<Ui::MessageBar> _bar;
|
||||
std::unique_ptr<Ui::IconButton> _close;
|
||||
object_ptr<Ui::RpWidget> _rightButton = { nullptr };
|
||||
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
rpl::event_stream<> _barClicks;
|
||||
Fn<QRect(QRect)> _shadowGeometryPostprocess;
|
||||
|
|
Loading…
Add table
Reference in a new issue