mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Support topic choosing in ShareBox.
This commit is contained in:
parent
7384cd3463
commit
e6c2aa8021
14 changed files with 273 additions and 117 deletions
|
@ -1141,7 +1141,7 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
showToast(tr::lng_group_invite_copied(tr::now));
|
showToast(tr::lng_group_invite_copied(tr::now));
|
||||||
};
|
};
|
||||||
auto submitCallback = [=](
|
auto submitCallback = [=](
|
||||||
std::vector<not_null<PeerData*>> &&result,
|
std::vector<not_null<Data::Thread*>> &&result,
|
||||||
TextWithTags &&comment,
|
TextWithTags &&comment,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
Data::ForwardOptions) {
|
Data::ForwardOptions) {
|
||||||
|
@ -1150,12 +1150,12 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto error = [&] {
|
const auto error = [&] {
|
||||||
for (const auto peer : result) {
|
for (const auto thread : result) {
|
||||||
const auto error = GetErrorTextForSending(
|
const auto error = GetErrorTextForSending(
|
||||||
peer,
|
thread,
|
||||||
{ .text = &comment });
|
{ .text = &comment });
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
return std::make_pair(error, peer);
|
return std::make_pair(error, thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(QString(), result.front());
|
return std::make_pair(QString(), result.front());
|
||||||
|
@ -1164,7 +1164,7 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
auto text = TextWithEntities();
|
auto text = TextWithEntities();
|
||||||
if (result.size() > 1) {
|
if (result.size() > 1) {
|
||||||
text.append(
|
text.append(
|
||||||
Ui::Text::Bold(error.second->name())
|
Ui::Text::Bold(error.second->chatListName())
|
||||||
).append("\n\n");
|
).append("\n\n");
|
||||||
}
|
}
|
||||||
text.append(error.first);
|
text.append(error.first);
|
||||||
|
@ -1188,10 +1188,9 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
const auto owner = &peer->owner();
|
const auto owner = &peer->owner();
|
||||||
auto &api = peer->session().api();
|
auto &api = peer->session().api();
|
||||||
for (const auto peer : result) {
|
for (const auto thread : result) {
|
||||||
const auto history = owner->history(peer);
|
|
||||||
auto message = Api::MessageToSend(
|
auto message = Api::MessageToSend(
|
||||||
Api::SendAction(history, options));
|
Api::SendAction(thread, options));
|
||||||
message.textWithTags = comment;
|
message.textWithTags = comment;
|
||||||
message.action.clearDraft = false;
|
message.action.clearDraft = false;
|
||||||
api.sendMessage(std::move(message));
|
api.sendMessage(std::move(message));
|
||||||
|
@ -1204,8 +1203,8 @@ object_ptr<Ui::BoxContent> ShareInviteLinkBox(
|
||||||
auto object = Box<ShareBox>(ShareBox::Descriptor{
|
auto object = Box<ShareBox>(ShareBox::Descriptor{
|
||||||
.session = &peer->session(),
|
.session = &peer->session(),
|
||||||
.copyCallback = std::move(copyCallback),
|
.copyCallback = std::move(copyCallback),
|
||||||
.submitCallback = std::move(submitCallback), // #TODO forum share
|
.submitCallback = std::move(submitCallback),
|
||||||
.filterCallback = [](auto peer) { return peer->canWrite(); },
|
.filterCallback = [](auto thread) { return thread->canWrite(); },
|
||||||
});
|
});
|
||||||
*box = Ui::MakeWeak(object.data());
|
*box = Ui::MakeWeak(object.data());
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -35,7 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_context_menu.h" // CopyPostLink.
|
#include "history/view/history_view_context_menu.h" // CopyPostLink.
|
||||||
#include "history/view/history_view_schedule_box.h"
|
#include "history/view/history_view_schedule_box.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_game.h"
|
#include "data/data_game.h"
|
||||||
|
@ -43,6 +43,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
|
#include "data/data_forum.h"
|
||||||
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
@ -57,14 +59,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
class ShareBox::Inner final : public Ui::RpWidget {
|
class ShareBox::Inner final : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
Inner(QWidget *parent, const Descriptor &descriptor);
|
Inner(
|
||||||
|
QWidget *parent,
|
||||||
|
const Descriptor &descriptor,
|
||||||
|
std::shared_ptr<Ui::BoxShow> show);
|
||||||
|
|
||||||
void setPeerSelectedChangedCallback(
|
void setPeerSelectedChangedCallback(
|
||||||
Fn<void(PeerData *peer, bool selected)> callback);
|
Fn<void(not_null<Data::Thread*> thread, bool selected)> callback);
|
||||||
void peerUnselected(not_null<PeerData*> peer);
|
void peerUnselected(not_null<PeerData*> peer);
|
||||||
|
|
||||||
std::vector<not_null<PeerData*>> selected() const;
|
[[nodiscard]] std::vector<not_null<Data::Thread*>> selected() const;
|
||||||
bool hasSelected() const;
|
[[nodiscard]] bool hasSelected() const;
|
||||||
|
|
||||||
void peopleReceived(
|
void peopleReceived(
|
||||||
const QString &query,
|
const QString &query,
|
||||||
|
@ -95,11 +100,13 @@ protected:
|
||||||
private:
|
private:
|
||||||
struct Chat {
|
struct Chat {
|
||||||
Chat(
|
Chat(
|
||||||
PeerData *peer,
|
not_null<PeerData*> peer,
|
||||||
const style::PeerListItem &st,
|
const style::PeerListItem &st,
|
||||||
Fn<void()> updateCallback);
|
Fn<void()> updateCallback);
|
||||||
|
|
||||||
PeerData *peer;
|
not_null<PeerData*> peer;
|
||||||
|
Data::ForumTopic *topic = nullptr;
|
||||||
|
rpl::lifetime topicLifetime;
|
||||||
Ui::RoundImageCheckbox checkbox;
|
Ui::RoundImageCheckbox checkbox;
|
||||||
Ui::Text::String name;
|
Ui::Text::String name;
|
||||||
Ui::Animations::Simple nameActive;
|
Ui::Animations::Simple nameActive;
|
||||||
|
@ -107,11 +114,13 @@ private:
|
||||||
|
|
||||||
void invalidateCache();
|
void invalidateCache();
|
||||||
|
|
||||||
int displayedChatsCount() const;
|
[[nodiscard]] int displayedChatsCount() const;
|
||||||
|
[[nodiscard]] not_null<Data::Thread*> chatThread(
|
||||||
|
not_null<Chat*> chat) const;
|
||||||
|
|
||||||
void paintChat(Painter &p, not_null<Chat*> chat, int index);
|
void paintChat(Painter &p, not_null<Chat*> chat, int index);
|
||||||
void updateChat(not_null<PeerData*> peer);
|
void updateChat(not_null<PeerData*> peer);
|
||||||
void updateChatName(not_null<Chat*> chat, not_null<PeerData*> peer);
|
void updateChatName(not_null<Chat*> chat);
|
||||||
void repaintChat(not_null<PeerData*> peer);
|
void repaintChat(not_null<PeerData*> peer);
|
||||||
int chatIndex(not_null<PeerData*> peer) const;
|
int chatIndex(not_null<PeerData*> peer) const;
|
||||||
void repaintChatAtIndex(int index);
|
void repaintChatAtIndex(int index);
|
||||||
|
@ -119,6 +128,7 @@ private:
|
||||||
|
|
||||||
void loadProfilePhotos(int yFrom);
|
void loadProfilePhotos(int yFrom);
|
||||||
void changeCheckState(Chat *chat);
|
void changeCheckState(Chat *chat);
|
||||||
|
void chooseForumTopic(not_null<Data::Forum*> forum);
|
||||||
enum class ChangeStateWay {
|
enum class ChangeStateWay {
|
||||||
Default,
|
Default,
|
||||||
SkipCallback,
|
SkipCallback,
|
||||||
|
@ -135,6 +145,7 @@ private:
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
const Descriptor &_descriptor;
|
const Descriptor &_descriptor;
|
||||||
|
const std::shared_ptr<Ui::BoxShow> _show;
|
||||||
const style::PeerList &_st;
|
const style::PeerList &_st;
|
||||||
|
|
||||||
float64 _columnSkip = 0.;
|
float64 _columnSkip = 0.;
|
||||||
|
@ -152,9 +163,9 @@ private:
|
||||||
std::vector<not_null<Dialogs::Row*>> _filtered;
|
std::vector<not_null<Dialogs::Row*>> _filtered;
|
||||||
|
|
||||||
std::map<not_null<PeerData*>, std::unique_ptr<Chat>> _dataMap;
|
std::map<not_null<PeerData*>, std::unique_ptr<Chat>> _dataMap;
|
||||||
base::flat_set<not_null<PeerData*>> _selected;
|
base::flat_set<not_null<Data::Thread*>> _selected;
|
||||||
|
|
||||||
Fn<void(PeerData *peer, bool selected)> _peerSelectedChangedCallback;
|
Fn<void(not_null<Data::Thread*>, bool)> _peerSelectedChangedCallback;
|
||||||
|
|
||||||
bool _searching = false;
|
bool _searching = false;
|
||||||
QString _lastQuery;
|
QString _lastQuery;
|
||||||
|
@ -247,7 +258,7 @@ void ShareBox::prepare() {
|
||||||
setTitle(tr::lng_share_title());
|
setTitle(tr::lng_share_title());
|
||||||
|
|
||||||
_inner = setInnerWidget(
|
_inner = setInnerWidget(
|
||||||
object_ptr<Inner>(this, _descriptor),
|
object_ptr<Inner>(this, _descriptor, _show),
|
||||||
getTopScrollSkip(),
|
getTopScrollSkip(),
|
||||||
getBottomScrollSkip());
|
getBottomScrollSkip());
|
||||||
|
|
||||||
|
@ -293,8 +304,10 @@ void ShareBox::prepare() {
|
||||||
scrollTo(request);
|
scrollTo(request);
|
||||||
}, _inner->lifetime());
|
}, _inner->lifetime());
|
||||||
|
|
||||||
_inner->setPeerSelectedChangedCallback([=](PeerData *peer, bool checked) {
|
_inner->setPeerSelectedChangedCallback([=](
|
||||||
innerSelectedChanged(peer, checked);
|
not_null<Data::Thread*> thread,
|
||||||
|
bool checked) {
|
||||||
|
innerSelectedChanged(thread, checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
Ui::Emoji::SuggestionsController::Init(
|
Ui::Emoji::SuggestionsController::Init(
|
||||||
|
@ -442,9 +455,11 @@ void ShareBox::keyPressEvent(QKeyEvent *e) {
|
||||||
|
|
||||||
SendMenu::Type ShareBox::sendMenuType() const {
|
SendMenu::Type ShareBox::sendMenuType() const {
|
||||||
const auto selected = _inner->selected();
|
const auto selected = _inner->selected();
|
||||||
return ranges::all_of(selected, HistoryView::CanScheduleUntilOnline)
|
return ranges::all_of(
|
||||||
|
selected | ranges::views::transform(&Data::Thread::peer),
|
||||||
|
HistoryView::CanScheduleUntilOnline)
|
||||||
? SendMenu::Type::ScheduledToUser
|
? SendMenu::Type::ScheduledToUser
|
||||||
: (selected.size() == 1 && selected.front()->isSelf())
|
: (selected.size() == 1 && selected.front()->peer()->isSelf())
|
||||||
? SendMenu::Type::Reminder
|
? SendMenu::Type::Reminder
|
||||||
: SendMenu::Type::Scheduled;
|
: SendMenu::Type::Scheduled;
|
||||||
}
|
}
|
||||||
|
@ -522,23 +537,51 @@ void ShareBox::applyFilterUpdate(const QString &query) {
|
||||||
_inner->updateFilter(query);
|
_inner->updateFilter(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::addPeerToMultiSelect(PeerData *peer, bool skipAnimation) {
|
PaintRoundImageCallback ForceRoundUserpicCallback(not_null<PeerData*> peer) {
|
||||||
using AddItemWay = Ui::MultiSelect::AddItemWay;
|
auto userpic = std::shared_ptr<Data::CloudImageView>();
|
||||||
auto addItemWay = skipAnimation ? AddItemWay::SkipAnimation : AddItemWay::Default;
|
auto cache = std::make_shared<QImage>();
|
||||||
|
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||||
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
const auto cacheSize = QSize(size, size) * ratio;
|
||||||
|
if (cache->size() != cacheSize) {
|
||||||
|
*cache = QImage(cacheSize, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
cache->setDevicePixelRatio(ratio);
|
||||||
|
}
|
||||||
|
auto q = Painter(cache.get());
|
||||||
|
peer->paintUserpicLeft(q, userpic, 0, 0, outerWidth, size);
|
||||||
|
q.end();
|
||||||
|
|
||||||
|
*cache = Images::Circle(std::move(*cache));
|
||||||
|
p.drawImage(x, y, *cache);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShareBox::addPeerToMultiSelect(not_null<Data::Thread*> thread) {
|
||||||
|
auto addItemWay = Ui::MultiSelect::AddItemWay::Default;
|
||||||
|
const auto peer = thread->peer();
|
||||||
|
const auto topic = thread->asTopic();
|
||||||
_select->addItem(
|
_select->addItem(
|
||||||
peer->id.value,
|
peer->id.value,
|
||||||
peer->isSelf() ? tr::lng_saved_short(tr::now) : peer->shortName(),
|
(topic
|
||||||
|
? topic->title()
|
||||||
|
: peer->isSelf()
|
||||||
|
? tr::lng_saved_short(tr::now)
|
||||||
|
: peer->shortName()),
|
||||||
st::activeButtonBg,
|
st::activeButtonBg,
|
||||||
PaintUserpicCallback(peer, true),
|
(topic
|
||||||
|
? ForceRoundUserpicCallback(peer)
|
||||||
|
: PaintUserpicCallback(peer, true)),
|
||||||
addItemWay);
|
addItemWay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::innerSelectedChanged(PeerData *peer, bool checked) {
|
void ShareBox::innerSelectedChanged(
|
||||||
|
not_null<Data::Thread*> thread,
|
||||||
|
bool checked) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
addPeerToMultiSelect(peer);
|
addPeerToMultiSelect(thread);
|
||||||
_select->clearQuery();
|
_select->clearQuery();
|
||||||
} else {
|
} else {
|
||||||
_select->removeItem(peer->id.value);
|
_select->removeItem(thread->peer()->id.value);
|
||||||
}
|
}
|
||||||
selectedChanged();
|
selectedChanged();
|
||||||
update();
|
update();
|
||||||
|
@ -612,9 +655,13 @@ void ShareBox::scrollAnimationCallback() {
|
||||||
//scrollArea()->scrollToY(scrollTop);
|
//scrollArea()->scrollToY(scrollTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareBox::Inner::Inner(QWidget *parent, const Descriptor &descriptor)
|
ShareBox::Inner::Inner(
|
||||||
|
QWidget *parent,
|
||||||
|
const Descriptor &descriptor,
|
||||||
|
std::shared_ptr<Ui::BoxShow> show)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _descriptor(descriptor)
|
, _descriptor(descriptor)
|
||||||
|
, _show(std::move(show))
|
||||||
, _st(_descriptor.st ? *_descriptor.st : st::shareBoxList)
|
, _st(_descriptor.st ? *_descriptor.st : st::shareBoxList)
|
||||||
, _chatsIndexed(
|
, _chatsIndexed(
|
||||||
std::make_unique<Dialogs::IndexedList>(
|
std::make_unique<Dialogs::IndexedList>(
|
||||||
|
@ -624,14 +671,16 @@ ShareBox::Inner::Inner(QWidget *parent, const Descriptor &descriptor)
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
const auto self = _descriptor.session->user();
|
const auto self = _descriptor.session->user();
|
||||||
if (_descriptor.filterCallback(self)) {
|
const auto selfHistory = self->owner().history(self);
|
||||||
_chatsIndexed->addToEnd(self->owner().history(self));
|
if (_descriptor.filterCallback(selfHistory)) {
|
||||||
|
_chatsIndexed->addToEnd(selfHistory);
|
||||||
}
|
}
|
||||||
const auto addList = [&](not_null<Dialogs::IndexedList*> list) {
|
const auto addList = [&](not_null<Dialogs::IndexedList*> list) {
|
||||||
for (const auto &row : list->all()) {
|
for (const auto &row : list->all()) {
|
||||||
if (const auto history = row->history()) {
|
if (const auto history = row->history()) {
|
||||||
if (!history->peer->isSelf()
|
if (!history->peer->isSelf()
|
||||||
&& _descriptor.filterCallback(history->peer)) {
|
&& (history->asForum()
|
||||||
|
|| _descriptor.filterCallback(history))) {
|
||||||
_chatsIndexed->addToEnd(history);
|
_chatsIndexed->addToEnd(history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,15 +764,16 @@ void ShareBox::Inner::activateSkipPage(int pageHeight, int direction) {
|
||||||
|
|
||||||
void ShareBox::Inner::updateChat(not_null<PeerData*> peer) {
|
void ShareBox::Inner::updateChat(not_null<PeerData*> peer) {
|
||||||
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
|
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
|
||||||
updateChatName(i->second.get(), peer);
|
updateChatName(i->second.get());
|
||||||
repaintChat(peer);
|
repaintChat(peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::updateChatName(
|
void ShareBox::Inner::updateChatName(not_null<Chat*> chat) {
|
||||||
not_null<Chat*> chat,
|
const auto peer = chat->peer;
|
||||||
not_null<PeerData*> peer) {
|
const auto text = chat->topic
|
||||||
const auto text = peer->isSelf()
|
? chat->topic->title()
|
||||||
|
: peer->isSelf()
|
||||||
? tr::lng_saved_messages(tr::now)
|
? tr::lng_saved_messages(tr::now)
|
||||||
: peer->isRepliesChat()
|
: peer->isRepliesChat()
|
||||||
? tr::lng_replies_messages(tr::now)
|
? tr::lng_replies_messages(tr::now)
|
||||||
|
@ -852,7 +902,7 @@ auto ShareBox::Inner::getChat(not_null<Dialogs::Row*> row)
|
||||||
const auto [i, ok] = _dataMap.emplace(
|
const auto [i, ok] = _dataMap.emplace(
|
||||||
peer,
|
peer,
|
||||||
std::make_unique<Chat>(peer, _st.item, [=] { repaintChat(peer); }));
|
std::make_unique<Chat>(peer, _st.item, [=] { repaintChat(peer); }));
|
||||||
updateChatName(i->second.get(), peer);
|
updateChatName(i->second.get());
|
||||||
row->attached = i->second.get();
|
row->attached = i->second.get();
|
||||||
return i->second.get();
|
return i->second.get();
|
||||||
}
|
}
|
||||||
|
@ -896,11 +946,17 @@ void ShareBox::Inner::paintChat(
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareBox::Inner::Chat::Chat(
|
ShareBox::Inner::Chat::Chat(
|
||||||
PeerData *peer,
|
not_null<PeerData*> peer,
|
||||||
const style::PeerListItem &st,
|
const style::PeerListItem &st,
|
||||||
Fn<void()> updateCallback)
|
Fn<void()> updateCallback)
|
||||||
: peer(peer)
|
: peer(peer)
|
||||||
, checkbox(st.checkbox, updateCallback, PaintUserpicCallback(peer, true))
|
, checkbox(
|
||||||
|
st.checkbox,
|
||||||
|
updateCallback,
|
||||||
|
PaintUserpicCallback(peer, true),
|
||||||
|
[=] { return peer->isForum()
|
||||||
|
? ImageRoundRadius::Large
|
||||||
|
: ImageRoundRadius::Ellipse; })
|
||||||
, name(st.checkbox.imageRadius * 2) {
|
, name(st.checkbox.imageRadius * 2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,9 +1078,9 @@ void ShareBox::Inner::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::changeCheckState(Chat *chat) {
|
void ShareBox::Inner::changeCheckState(Chat *chat) {
|
||||||
if (!chat) return;
|
if (!chat) {
|
||||||
|
return;
|
||||||
if (!_filter.isEmpty()) {
|
} else if (!_filter.isEmpty()) {
|
||||||
const auto history = chat->peer->owner().history(chat->peer);
|
const auto history = chat->peer->owner().history(chat->peer);
|
||||||
auto row = _chatsIndexed->getRow(history);
|
auto row = _chatsIndexed->getRow(history);
|
||||||
if (!row) {
|
if (!row) {
|
||||||
|
@ -1036,7 +1092,60 @@ void ShareBox::Inner::changeCheckState(Chat *chat) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changePeerCheckState(chat, !chat->checkbox.checked());
|
const auto checked = chat->checkbox.checked();
|
||||||
|
const auto forum = chat->peer->forum();
|
||||||
|
if (checked || !forum) {
|
||||||
|
changePeerCheckState(chat, !checked);
|
||||||
|
} else {
|
||||||
|
chooseForumTopic(chat->peer->forum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShareBox::Inner::chooseForumTopic(not_null<Data::Forum*> forum) {
|
||||||
|
const auto guard = Ui::MakeWeak(this);
|
||||||
|
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||||
|
auto chosen = [=](not_null<Data::ForumTopic*> topic) {
|
||||||
|
if (const auto strong = *weak) {
|
||||||
|
strong->closeBox();
|
||||||
|
}
|
||||||
|
if (!guard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto row = _chatsIndexed->getRow(topic->owningHistory());
|
||||||
|
if (!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto chat = getChat(row);
|
||||||
|
Assert(!chat->topic);
|
||||||
|
chat->topic = topic;
|
||||||
|
chat->topic->destroyed(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
changePeerCheckState(chat, false);
|
||||||
|
}, chat->topicLifetime);
|
||||||
|
updateChatName(chat);
|
||||||
|
changePeerCheckState(chat, true);
|
||||||
|
};
|
||||||
|
auto initBox = [](not_null<PeerListBox*> box) {
|
||||||
|
box->addButton(tr::lng_cancel(), [box] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
auto box = Box<PeerListBox>(
|
||||||
|
std::make_unique<ChooseTopicBoxController>(
|
||||||
|
forum,
|
||||||
|
std::move(chosen)),
|
||||||
|
[=](not_null<PeerListBox*> box) {
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
|
||||||
|
forum->destroyed(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
box->closeBox();
|
||||||
|
}, box->lifetime());
|
||||||
|
});
|
||||||
|
*weak = box.data();
|
||||||
|
_show->showBox(std::move(box));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::peerUnselected(not_null<PeerData*> peer) {
|
void ShareBox::Inner::peerUnselected(not_null<PeerData*> peer) {
|
||||||
|
@ -1049,7 +1158,7 @@ void ShareBox::Inner::peerUnselected(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareBox::Inner::setPeerSelectedChangedCallback(
|
void ShareBox::Inner::setPeerSelectedChangedCallback(
|
||||||
Fn<void(PeerData *peer, bool selected)> callback) {
|
Fn<void(not_null<Data::Thread*> thread, bool selected)> callback) {
|
||||||
_peerSelectedChangedCallback = std::move(callback);
|
_peerSelectedChangedCallback = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,15 +1167,21 @@ void ShareBox::Inner::changePeerCheckState(
|
||||||
bool checked,
|
bool checked,
|
||||||
ChangeStateWay useCallback) {
|
ChangeStateWay useCallback) {
|
||||||
chat->checkbox.setChecked(checked);
|
chat->checkbox.setChecked(checked);
|
||||||
|
const auto thread = chatThread(chat);
|
||||||
if (checked) {
|
if (checked) {
|
||||||
_selected.insert(chat->peer);
|
_selected.emplace(thread);
|
||||||
setActive(chatIndex(chat->peer));
|
setActive(chatIndex(chat->peer));
|
||||||
} else {
|
} else {
|
||||||
_selected.remove(chat->peer);
|
_selected.remove(thread);
|
||||||
|
if (chat->topic) {
|
||||||
|
chat->topicLifetime.destroy();
|
||||||
|
chat->topic = nullptr;
|
||||||
|
updateChatName(chat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (useCallback != ChangeStateWay::SkipCallback
|
if (useCallback != ChangeStateWay::SkipCallback
|
||||||
&& _peerSelectedChangedCallback) {
|
&& _peerSelectedChangedCallback) {
|
||||||
_peerSelectedChangedCallback(chat->peer, checked);
|
_peerSelectedChangedCallback(thread, checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,9 +1237,11 @@ void ShareBox::Inner::peopleReceived(
|
||||||
const auto feedList = [&](const QVector<MTPPeer> &list) {
|
const auto feedList = [&](const QVector<MTPPeer> &list) {
|
||||||
for (const auto &data : list) {
|
for (const auto &data : list) {
|
||||||
if (const auto peer = _descriptor.session->data().peerLoaded(
|
if (const auto peer = _descriptor.session->data().peerLoaded(
|
||||||
peerFromMTP(data))) {
|
peerFromMTP(data))) {
|
||||||
const auto history = _descriptor.session->data().historyLoaded(peer);
|
const auto history = _descriptor.session->data().history(
|
||||||
if (!_descriptor.filterCallback(peer)) {
|
peer);
|
||||||
|
if (!history->asForum()
|
||||||
|
&& !_descriptor.filterCallback(history)) {
|
||||||
continue;
|
continue;
|
||||||
} else if (history && _chatsIndexed->getRow(history)) {
|
} else if (history && _chatsIndexed->getRow(history)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1136,7 +1253,7 @@ void ShareBox::Inner::peopleReceived(
|
||||||
peer,
|
peer,
|
||||||
_st.item,
|
_st.item,
|
||||||
[=] { repaintChat(peer); }));
|
[=] { repaintChat(peer); }));
|
||||||
updateChatName(d_byUsernameFiltered.back().get(), peer);
|
updateChatName(d_byUsernameFiltered.back().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1158,12 +1275,19 @@ void ShareBox::Inner::refresh() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<not_null<PeerData*>> ShareBox::Inner::selected() const {
|
not_null<Data::Thread*> ShareBox::Inner::chatThread(
|
||||||
auto result = std::vector<not_null<PeerData*>>();
|
not_null<Chat*> chat) const {
|
||||||
|
return chat->topic
|
||||||
|
? (Data::Thread*)chat->topic
|
||||||
|
: chat->peer->owner().history(chat->peer).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<not_null<Data::Thread*>> ShareBox::Inner::selected() const {
|
||||||
|
auto result = std::vector<not_null<Data::Thread*>>();
|
||||||
result.reserve(_dataMap.size());
|
result.reserve(_dataMap.size());
|
||||||
for (const auto &[peer, chat] : _dataMap) {
|
for (const auto &[peer, chat] : _dataMap) {
|
||||||
if (chat->checkbox.checked()) {
|
if (chat->checkbox.checked()) {
|
||||||
result.push_back(peer);
|
result.push_back(chatThread(chat.get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -1279,7 +1403,7 @@ void FastShareMessage(
|
||||||
};
|
};
|
||||||
|
|
||||||
auto submitCallback = [=](
|
auto submitCallback = [=](
|
||||||
std::vector<not_null<PeerData*>> &&result,
|
std::vector<not_null<Data::Thread*>> &&result,
|
||||||
TextWithTags &&comment,
|
TextWithTags &&comment,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
Data::ForwardOptions forwardOptions) {
|
Data::ForwardOptions forwardOptions) {
|
||||||
|
@ -1292,12 +1416,12 @@ void FastShareMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto error = [&] {
|
const auto error = [&] {
|
||||||
for (const auto peer : result) { // #TODO forum share
|
for (const auto thread : result) {
|
||||||
const auto error = GetErrorTextForSending(
|
const auto error = GetErrorTextForSending(
|
||||||
peer,
|
thread,
|
||||||
{ .forward = &items, .text = &comment });
|
{ .forward = &items, .text = &comment });
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
return std::make_pair(error, peer);
|
return std::make_pair(error, thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(QString(), result.front());
|
return std::make_pair(QString(), result.front());
|
||||||
|
@ -1306,7 +1430,7 @@ void FastShareMessage(
|
||||||
auto text = TextWithEntities();
|
auto text = TextWithEntities();
|
||||||
if (result.size() > 1) {
|
if (result.size() > 1) {
|
||||||
text.append(
|
text.append(
|
||||||
Ui::Text::Bold(error.second->name())
|
Ui::Text::Bold(error.second->chatListName())
|
||||||
).append("\n\n");
|
).append("\n\n");
|
||||||
}
|
}
|
||||||
text.append(error.first);
|
text.append(error.first);
|
||||||
|
@ -1316,17 +1440,16 @@ void FastShareMessage(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto commonSendFlags = MTPmessages_ForwardMessages::Flag(0)
|
using Flag = MTPmessages_ForwardMessages::Flag;
|
||||||
| MTPmessages_ForwardMessages::Flag::f_with_my_score
|
const auto commonSendFlags = Flag(0)
|
||||||
| (options.scheduled
|
| Flag::f_with_my_score
|
||||||
? MTPmessages_ForwardMessages::Flag::f_schedule_date
|
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
||||||
: MTPmessages_ForwardMessages::Flag(0))
|
|
||||||
| ((forwardOptions != Data::ForwardOptions::PreserveInfo)
|
| ((forwardOptions != Data::ForwardOptions::PreserveInfo)
|
||||||
? MTPmessages_ForwardMessages::Flag::f_drop_author
|
? Flag::f_drop_author
|
||||||
: MTPmessages_ForwardMessages::Flag(0))
|
: Flag(0))
|
||||||
| ((forwardOptions == Data::ForwardOptions::NoNamesAndCaptions)
|
| ((forwardOptions == Data::ForwardOptions::NoNamesAndCaptions)
|
||||||
? MTPmessages_ForwardMessages::Flag::f_drop_media_captions
|
? Flag::f_drop_media_captions
|
||||||
: MTPmessages_ForwardMessages::Flag(0));
|
: Flag(0));
|
||||||
auto msgIds = QVector<MTPint>();
|
auto msgIds = QVector<MTPint>();
|
||||||
msgIds.reserve(data->msgIds.size());
|
msgIds.reserve(data->msgIds.size());
|
||||||
for (const auto &fullId : data->msgIds) {
|
for (const auto &fullId : data->msgIds) {
|
||||||
|
@ -1342,21 +1465,23 @@ void FastShareMessage(
|
||||||
auto &api = owner->session().api();
|
auto &api = owner->session().api();
|
||||||
auto &histories = owner->histories();
|
auto &histories = owner->histories();
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
const auto requestType = Data::Histories::RequestType::Send;
|
||||||
for (const auto peer : result) {
|
for (const auto thread : result) {
|
||||||
const auto history = owner->history(peer);
|
|
||||||
if (!comment.text.isEmpty()) {
|
if (!comment.text.isEmpty()) {
|
||||||
auto message = Api::MessageToSend(
|
auto message = Api::MessageToSend(
|
||||||
Api::SendAction(history, options));
|
Api::SendAction(thread, options));
|
||||||
message.textWithTags = comment;
|
message.textWithTags = comment;
|
||||||
message.action.clearDraft = false;
|
message.action.clearDraft = false;
|
||||||
api.sendMessage(std::move(message));
|
api.sendMessage(std::move(message));
|
||||||
}
|
}
|
||||||
|
const auto topicRootId = thread->topicRootId();
|
||||||
|
const auto peer = thread->peer();
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||||
auto &api = history->session().api();
|
auto &api = history->session().api();
|
||||||
const auto sendFlags = commonSendFlags
|
const auto sendFlags = commonSendFlags
|
||||||
|
| (topicRootId ? Flag::f_top_msg_id : Flag(0))
|
||||||
| (ShouldSendSilent(peer, options)
|
| (ShouldSendSilent(peer, options)
|
||||||
? MTPmessages_ForwardMessages::Flag::f_silent
|
? Flag::f_silent
|
||||||
: MTPmessages_ForwardMessages::Flag(0));
|
: Flag(0));
|
||||||
history->sendRequestId = api.request(
|
history->sendRequestId = api.request(
|
||||||
MTPmessages_ForwardMessages(
|
MTPmessages_ForwardMessages(
|
||||||
MTP_flags(sendFlags),
|
MTP_flags(sendFlags),
|
||||||
|
@ -1364,7 +1489,7 @@ void FastShareMessage(
|
||||||
MTP_vector<MTPint>(msgIds),
|
MTP_vector<MTPint>(msgIds),
|
||||||
MTP_vector<MTPlong>(generateRandom()),
|
MTP_vector<MTPlong>(generateRandom()),
|
||||||
peer->input,
|
peer->input,
|
||||||
MTPint(), // top_msg_id
|
MTP_int(topicRootId),
|
||||||
MTP_int(options.scheduled),
|
MTP_int(options.scheduled),
|
||||||
MTP_inputPeerEmpty() // send_as
|
MTP_inputPeerEmpty() // send_as
|
||||||
)).done([=](const MTPUpdates &updates, mtpRequestId reqId) {
|
)).done([=](const MTPUpdates &updates, mtpRequestId reqId) {
|
||||||
|
@ -1397,14 +1522,9 @@ void FastShareMessage(
|
||||||
data->requests.insert(history->sendRequestId);
|
data->requests.insert(history->sendRequestId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto filterCallback = [isGame](PeerData *peer) {
|
auto filterCallback = [isGame](not_null<Data::Thread*> thread) {
|
||||||
if (peer->canWrite()) { // #TODO forum share
|
return thread->canWrite()
|
||||||
if (auto channel = peer->asChannel()) {
|
&& (!isGame || !thread->peer()->isBroadcast());
|
||||||
return isGame ? (!channel->isBroadcast()) : true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
auto copyLinkCallback = canCopyLink
|
auto copyLinkCallback = canCopyLink
|
||||||
? Fn<void()>(std::move(copyCallback))
|
? Fn<void()>(std::move(copyCallback))
|
||||||
|
|
|
@ -44,6 +44,7 @@ class IndexedList;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
enum class ForwardOptions;
|
enum class ForwardOptions;
|
||||||
|
class Thread;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -70,11 +71,11 @@ class ShareBox final : public Ui::BoxContent {
|
||||||
public:
|
public:
|
||||||
using CopyCallback = Fn<void()>;
|
using CopyCallback = Fn<void()>;
|
||||||
using SubmitCallback = Fn<void(
|
using SubmitCallback = Fn<void(
|
||||||
std::vector<not_null<PeerData*>>&&,
|
std::vector<not_null<Data::Thread*>>&&,
|
||||||
TextWithTags&&,
|
TextWithTags&&,
|
||||||
Api::SendOptions,
|
Api::SendOptions,
|
||||||
Data::ForwardOptions option)>;
|
Data::ForwardOptions option)>;
|
||||||
using FilterCallback = Fn<bool(PeerData*)>;
|
using FilterCallback = Fn<bool(not_null<Data::Thread*>)>;
|
||||||
|
|
||||||
struct Descriptor {
|
struct Descriptor {
|
||||||
not_null<Main::Session*> session;
|
not_null<Main::Session*> session;
|
||||||
|
@ -125,8 +126,8 @@ private:
|
||||||
int contentHeight() const;
|
int contentHeight() const;
|
||||||
void updateScrollSkips();
|
void updateScrollSkips();
|
||||||
|
|
||||||
void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false);
|
void addPeerToMultiSelect(not_null<Data::Thread*> thread);
|
||||||
void innerSelectedChanged(PeerData *peer, bool checked);
|
void innerSelectedChanged(not_null<Data::Thread*> thread, bool checked);
|
||||||
|
|
||||||
void peopleDone(
|
void peopleDone(
|
||||||
const MTPcontacts_Found &result,
|
const MTPcontacts_Found &result,
|
||||||
|
|
|
@ -133,7 +133,7 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
showToast(tr::lng_group_invite_copied(tr::now));
|
showToast(tr::lng_group_invite_copied(tr::now));
|
||||||
};
|
};
|
||||||
auto submitCallback = [=](
|
auto submitCallback = [=](
|
||||||
std::vector<not_null<PeerData*>> &&result,
|
std::vector<not_null<Data::Thread*>> &&result,
|
||||||
TextWithTags &&comment,
|
TextWithTags &&comment,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
Data::ForwardOptions) {
|
Data::ForwardOptions) {
|
||||||
|
@ -142,12 +142,12 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto error = [&] {
|
const auto error = [&] {
|
||||||
for (const auto peer : result) { // #TODO forum share
|
for (const auto thread : result) {
|
||||||
const auto error = GetErrorTextForSending(
|
const auto error = GetErrorTextForSending(
|
||||||
peer,
|
thread,
|
||||||
{ .text = &comment });
|
{ .text = &comment });
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
return std::make_pair(error, peer);
|
return std::make_pair(error, thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(QString(), result.front());
|
return std::make_pair(QString(), result.front());
|
||||||
|
@ -156,7 +156,7 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
auto text = TextWithEntities();
|
auto text = TextWithEntities();
|
||||||
if (result.size() > 1) {
|
if (result.size() > 1) {
|
||||||
text.append(
|
text.append(
|
||||||
Ui::Text::Bold(error.second->name())
|
Ui::Text::Bold(error.second->chatListName())
|
||||||
).append("\n\n");
|
).append("\n\n");
|
||||||
}
|
}
|
||||||
text.append(error.first);
|
text.append(error.first);
|
||||||
|
@ -182,10 +182,9 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
const auto owner = &peer->owner();
|
const auto owner = &peer->owner();
|
||||||
auto &api = peer->session().api();
|
auto &api = peer->session().api();
|
||||||
for (const auto peer : result) {
|
for (const auto thread : result) {
|
||||||
const auto history = owner->history(peer);
|
|
||||||
auto message = Api::MessageToSend(
|
auto message = Api::MessageToSend(
|
||||||
Api::SendAction(history, options));
|
Api::SendAction(thread, options));
|
||||||
message.textWithTags = comment;
|
message.textWithTags = comment;
|
||||||
message.action.clearDraft = false;
|
message.action.clearDraft = false;
|
||||||
api.sendMessage(std::move(message));
|
api.sendMessage(std::move(message));
|
||||||
|
@ -195,8 +194,8 @@ object_ptr<ShareBox> ShareInviteLinkBox(
|
||||||
}
|
}
|
||||||
showToast(tr::lng_share_done(tr::now));
|
showToast(tr::lng_share_done(tr::now));
|
||||||
};
|
};
|
||||||
auto filterCallback = [](PeerData *peer) {
|
auto filterCallback = [](not_null<Data::Thread*> thread) {
|
||||||
return peer->canWrite(); // #TODO forum share
|
return thread->canWrite(); // #TODO forum share
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto scheduleStyle = [&] {
|
const auto scheduleStyle = [&] {
|
||||||
|
|
|
@ -178,6 +178,13 @@ QString GetErrorTextForSending(
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GetErrorTextForSending(
|
||||||
|
not_null<Data::Thread*> thread,
|
||||||
|
SendingErrorRequest request) {
|
||||||
|
request.topicRootId = thread->topicRootId();
|
||||||
|
return GetErrorTextForSending(thread->peer(), std::move(request));
|
||||||
|
}
|
||||||
|
|
||||||
void RequestDependentMessageData(
|
void RequestDependentMessageData(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct SendOptions;
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
class Thread;
|
||||||
struct SponsoredFrom;
|
struct SponsoredFrom;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
@ -50,6 +51,9 @@ struct SendingErrorRequest {
|
||||||
[[nodiscard]] QString GetErrorTextForSending(
|
[[nodiscard]] QString GetErrorTextForSending(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SendingErrorRequest request);
|
SendingErrorRequest request);
|
||||||
|
[[nodiscard]] QString GetErrorTextForSending(
|
||||||
|
not_null<Data::Thread*> thread,
|
||||||
|
SendingErrorRequest request);
|
||||||
|
|
||||||
[[nodiscard]] TextWithEntities DropCustomEmoji(TextWithEntities text);
|
[[nodiscard]] TextWithEntities DropCustomEmoji(TextWithEntities text);
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ void ForwardPanel::updateTexts() {
|
||||||
}).text;
|
}).text;
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
const auto dropCustomEmoji = !history->session().premium()
|
const auto dropCustomEmoji = !history->session().premium()
|
||||||
&& !_to->owningHistory()->peer->isSelf()
|
&& !_to->peer()->isSelf()
|
||||||
&& (item->computeDropForwardedInfo() || !keepNames);
|
&& (item->computeDropForwardedInfo() || !keepNames);
|
||||||
if (dropCustomEmoji) {
|
if (dropCustomEmoji) {
|
||||||
text = DropCustomEmoji(std::move(text));
|
text = DropCustomEmoji(std::move(text));
|
||||||
|
|
|
@ -64,7 +64,7 @@ PinnedMemento::PinnedMemento(
|
||||||
: _thread(thread)
|
: _thread(thread)
|
||||||
, _highlightId(highlightId) {
|
, _highlightId(highlightId) {
|
||||||
_list.setAroundPosition({
|
_list.setAroundPosition({
|
||||||
.fullId = FullMsgId(_thread->owningHistory()->peer->id, highlightId),
|
.fullId = FullMsgId(_thread->peer()->id, highlightId),
|
||||||
.date = TimeId(0),
|
.date = TimeId(0),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ PinnedWidget::PinnedWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<Data::Thread*> thread)
|
not_null<Data::Thread*> thread)
|
||||||
: Window::SectionWidget(parent, controller, thread->owningHistory()->peer)
|
: Window::SectionWidget(parent, controller, thread->peer())
|
||||||
, _thread(thread->migrateToOrMe())
|
, _thread(thread->migrateToOrMe())
|
||||||
, _history(thread->owningHistory())
|
, _history(thread->owningHistory())
|
||||||
, _migratedPeer(thread->asHistory()
|
, _migratedPeer(thread->asHistory()
|
||||||
|
@ -116,7 +116,7 @@ PinnedWidget::PinnedWidget(
|
||||||
|
|
||||||
Window::ChatThemeValueFromPeer(
|
Window::ChatThemeValueFromPeer(
|
||||||
controller,
|
controller,
|
||||||
thread->owningHistory()->peer
|
thread->peer()
|
||||||
) | rpl::start_with_next([=](std::shared_ptr<Ui::ChatTheme> &&theme) {
|
) | rpl::start_with_next([=](std::shared_ptr<Ui::ChatTheme> &&theme) {
|
||||||
_theme = std::move(theme);
|
_theme = std::move(theme);
|
||||||
controller->setChatStyleTheme(_theme);
|
controller->setChatStyleTheme(_theme);
|
||||||
|
|
|
@ -79,7 +79,7 @@ void PinnedTracker::refreshViewer() {
|
||||||
}
|
}
|
||||||
_dataLifetime.destroy();
|
_dataLifetime.destroy();
|
||||||
_viewerAroundId = _aroundId;
|
_viewerAroundId = _aroundId;
|
||||||
const auto peer = _thread->owningHistory()->peer;
|
const auto peer = _thread->peer();
|
||||||
SharedMediaMergedViewer(
|
SharedMediaMergedViewer(
|
||||||
&peer->session(),
|
&peer->session(),
|
||||||
SharedMediaMergedKey(
|
SharedMediaMergedKey(
|
||||||
|
|
|
@ -141,7 +141,7 @@ void ShowChooseBox(
|
||||||
callback(thread);
|
callback(thread);
|
||||||
};
|
};
|
||||||
auto filter = [=](not_null<Data::Thread*> thread) -> bool {
|
auto filter = [=](not_null<Data::Thread*> thread) -> bool {
|
||||||
const auto peer = thread->owningHistory()->peer;
|
const auto peer = thread->peer();
|
||||||
if (!thread->canWrite()) {
|
if (!thread->canWrite()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (const auto user = peer->asUser()) {
|
} else if (const auto user = peer->asUser()) {
|
||||||
|
|
|
@ -607,7 +607,7 @@ bool MainWidget::sendPaths(not_null<Data::Thread*> thread) {
|
||||||
Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant()));
|
Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant()));
|
||||||
return false;
|
return false;
|
||||||
} else if (const auto error = Data::RestrictionError(
|
} else if (const auto error = Data::RestrictionError(
|
||||||
thread->owningHistory()->peer,
|
thread->peer(),
|
||||||
ChatRestriction::SendMedia)) {
|
ChatRestriction::SendMedia)) {
|
||||||
Ui::show(Ui::MakeInformBox(*error));
|
Ui::show(Ui::MakeInformBox(*error));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
#include "ui/image/image_prepare.h"
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
|
@ -355,10 +356,15 @@ void RoundCheckbox::prepareInactiveCache() {
|
||||||
_inactiveCacheFg = Ui::PixmapFromImage(std::move(cacheFg));
|
_inactiveCacheFg = Ui::PixmapFromImage(std::move(cacheFg));
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundImageCheckbox::RoundImageCheckbox(const style::RoundImageCheckbox &st, Fn<void()> updateCallback, PaintRoundImage &&paintRoundImage)
|
RoundImageCheckbox::RoundImageCheckbox(
|
||||||
|
const style::RoundImageCheckbox &st,
|
||||||
|
Fn<void()> updateCallback,
|
||||||
|
PaintRoundImage &&paintRoundImage,
|
||||||
|
Fn<ImageRoundRadius()> roundingRadius)
|
||||||
: _st(st)
|
: _st(st)
|
||||||
, _updateCallback(updateCallback)
|
, _updateCallback(updateCallback)
|
||||||
, _paintRoundImage(std::move(paintRoundImage))
|
, _paintRoundImage(std::move(paintRoundImage))
|
||||||
|
, _roundingRadius(std::move(roundingRadius))
|
||||||
, _check(_st.check, _updateCallback) {
|
, _check(_st.check, _updateCallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,6 +389,9 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectionLevel > 0) {
|
if (selectionLevel > 0) {
|
||||||
|
const auto radius = _roundingRadius
|
||||||
|
? _roundingRadius()
|
||||||
|
: ImageRoundRadius::Ellipse;
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.setOpacity(std::clamp(selectionLevel, 0., 1.));
|
p.setOpacity(std::clamp(selectionLevel, 0., 1.));
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
|
@ -390,7 +399,18 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
|
||||||
_fgOverride ? (*_fgOverride) : _st.selectFg->b,
|
_fgOverride ? (*_fgOverride) : _st.selectFg->b,
|
||||||
_st.selectWidth);
|
_st.selectWidth);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
p.drawEllipse(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth));
|
const auto rect = style::rtlrect(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
_st.imageRadius * 2,
|
||||||
|
_st.imageRadius * 2,
|
||||||
|
outerWidth);
|
||||||
|
if (radius == ImageRoundRadius::Ellipse) {
|
||||||
|
p.drawEllipse(rect);
|
||||||
|
} else {
|
||||||
|
const auto pxRadius = st::roundRadiusLarge;
|
||||||
|
p.drawRoundedRect(rect, pxRadius, pxRadius);
|
||||||
|
}
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
if (_st.check.size > 0) {
|
if (_st.check.size > 0) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
class Painter;
|
class Painter;
|
||||||
|
enum class ImageRoundRadius;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
@ -47,7 +48,11 @@ private:
|
||||||
class RoundImageCheckbox {
|
class RoundImageCheckbox {
|
||||||
public:
|
public:
|
||||||
using PaintRoundImage = Fn<void(Painter &p, int x, int y, int outerWidth, int size)>;
|
using PaintRoundImage = Fn<void(Painter &p, int x, int y, int outerWidth, int size)>;
|
||||||
RoundImageCheckbox(const style::RoundImageCheckbox &st, Fn<void()> updateCallback, PaintRoundImage &&paintRoundImage);
|
RoundImageCheckbox(
|
||||||
|
const style::RoundImageCheckbox &st,
|
||||||
|
Fn<void()> updateCallback,
|
||||||
|
PaintRoundImage &&paintRoundImage,
|
||||||
|
Fn<ImageRoundRadius()> roundingRadius = nullptr);
|
||||||
|
|
||||||
void paint(Painter &p, int x, int y, int outerWidth) const;
|
void paint(Painter &p, int x, int y, int outerWidth) const;
|
||||||
float64 checkedAnimationRatio() const;
|
float64 checkedAnimationRatio() const;
|
||||||
|
@ -71,6 +76,7 @@ private:
|
||||||
const style::RoundImageCheckbox &_st;
|
const style::RoundImageCheckbox &_st;
|
||||||
Fn<void()> _updateCallback;
|
Fn<void()> _updateCallback;
|
||||||
PaintRoundImage _paintRoundImage;
|
PaintRoundImage _paintRoundImage;
|
||||||
|
Fn<ImageRoundRadius()> _roundingRadius;
|
||||||
|
|
||||||
QPixmap _wideCache;
|
QPixmap _wideCache;
|
||||||
Ui::Animations::Simple _selection;
|
Ui::Animations::Simple _selection;
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ void PeerMenuShareContactBox(
|
||||||
// There is no async to make weak from controller.
|
// There is no async to make weak from controller.
|
||||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||||
auto callback = [=](not_null<Data::Thread*> thread) {
|
auto callback = [=](not_null<Data::Thread*> thread) {
|
||||||
const auto peer = thread->owningHistory()->peer;
|
const auto peer = thread->peer();
|
||||||
if (!thread->canWrite()) {
|
if (!thread->canWrite()) {
|
||||||
navigation->parentController()->show(
|
navigation->parentController()->show(
|
||||||
Ui::MakeInformBox(tr::lng_forward_share_cant()),
|
Ui::MakeInformBox(tr::lng_forward_share_cant()),
|
||||||
|
@ -1544,7 +1544,7 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
||||||
weak,
|
weak,
|
||||||
navigation
|
navigation
|
||||||
](not_null<Data::Thread*> thread) mutable {
|
](not_null<Data::Thread*> thread) mutable {
|
||||||
const auto peer = thread->owningHistory()->peer;
|
const auto peer = thread->peer();
|
||||||
const auto content = navigation->parentController()->content();
|
const auto content = navigation->parentController()->content();
|
||||||
if (peer->isSelf()
|
if (peer->isSelf()
|
||||||
&& !draft.ids.empty()
|
&& !draft.ids.empty()
|
||||||
|
@ -1604,7 +1604,7 @@ QPointer<Ui::BoxContent> ShowShareGameBox(
|
||||||
ShowAtUnreadMsgId,
|
ShowAtUnreadMsgId,
|
||||||
SectionShow::Way::ClearStack);
|
SectionShow::Way::ClearStack);
|
||||||
});
|
});
|
||||||
const auto confirmText = thread->owningHistory()->peer->isUser()
|
const auto confirmText = thread->peer()->isUser()
|
||||||
? tr::lng_bot_sure_share_game(
|
? tr::lng_bot_sure_share_game(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_user,
|
lt_user,
|
||||||
|
@ -1621,7 +1621,7 @@ QPointer<Ui::BoxContent> ShowShareGameBox(
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
};
|
};
|
||||||
auto filter = [](not_null<Data::Thread*> thread) {
|
auto filter = [](not_null<Data::Thread*> thread) {
|
||||||
const auto peer = thread->owningHistory()->peer;
|
const auto peer = thread->peer();
|
||||||
return (thread->canWrite() || thread->asForum())
|
return (thread->canWrite() || thread->asForum())
|
||||||
&& !peer->amRestricted(ChatRestriction::SendGames)
|
&& !peer->amRestricted(ChatRestriction::SendGames)
|
||||||
&& !peer->isSelf();
|
&& !peer->isSelf();
|
||||||
|
|
Loading…
Add table
Reference in a new issue