mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 13:17:08 +02:00
Make nice share message from miniapp.
This commit is contained in:
parent
7bf78b3317
commit
2fed657940
7 changed files with 188 additions and 48 deletions
|
@ -1065,6 +1065,11 @@ std::unique_ptr<PeerListRow> ChooseTopicBoxController::createSearchRow(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ChooseTopicBoxController::MakeRow(
|
||||
not_null<Data::ForumTopic*> topic) {
|
||||
return std::make_unique<Row>(topic);
|
||||
}
|
||||
|
||||
auto ChooseTopicBoxController::createRow(not_null<Data::ForumTopic*> topic)
|
||||
-> std::unique_ptr<Row> {
|
||||
const auto skip = _filter && !_filter(topic);
|
||||
|
|
|
@ -335,6 +335,9 @@ public:
|
|||
void loadMoreRows() override;
|
||||
std::unique_ptr<PeerListRow> createSearchRow(PeerListRowId id) override;
|
||||
|
||||
[[nodiscard]] static std::unique_ptr<PeerListRow> MakeRow(
|
||||
not_null<Data::ForumTopic*> topic);
|
||||
|
||||
private:
|
||||
class Row final : public PeerListRow {
|
||||
public:
|
||||
|
|
|
@ -12,12 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "boxes/gift_premium_box.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/share_box.h"
|
||||
#include "core/application.h"
|
||||
#include "core/ui_integration.h" // Core::MarkedTextContext.
|
||||
#include "data/components/credits.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
|
@ -51,6 +53,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_credits.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_giveaway.h"
|
||||
#include "styles/style_info.h"
|
||||
#include "styles/style_layers.h" // st::boxDividerLabel.
|
||||
|
@ -264,8 +267,9 @@ private:
|
|||
class SingleRowController final : public PeerListController {
|
||||
public:
|
||||
SingleRowController(
|
||||
not_null<PeerData*> peer,
|
||||
rpl::producer<QString> status);
|
||||
not_null<Data::Thread*> thread,
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked);
|
||||
|
||||
void prepare() override;
|
||||
void loadMoreRows() override;
|
||||
|
@ -273,8 +277,10 @@ public:
|
|||
Main::Session &session() const override;
|
||||
|
||||
private:
|
||||
const not_null<PeerData*> _peer;
|
||||
const not_null<Main::Session*> _session;
|
||||
const base::weak_ptr<Data::Thread> _thread;
|
||||
rpl::producer<QString> _status;
|
||||
Fn<void()> _clicked;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
@ -1144,36 +1150,59 @@ int Controller::descriptionTopSkipMin() const {
|
|||
}
|
||||
|
||||
SingleRowController::SingleRowController(
|
||||
not_null<PeerData*> peer,
|
||||
rpl::producer<QString> status)
|
||||
: _peer(peer)
|
||||
, _status(std::move(status)) {
|
||||
not_null<Data::Thread*> thread,
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked)
|
||||
: _session(&thread->session())
|
||||
, _thread(thread)
|
||||
, _status(std::move(status))
|
||||
, _clicked(std::move(clicked)) {
|
||||
}
|
||||
|
||||
void SingleRowController::prepare() {
|
||||
auto row = std::make_unique<PeerListRow>(_peer);
|
||||
|
||||
const auto strong = _thread.get();
|
||||
if (!strong) {
|
||||
return;
|
||||
}
|
||||
const auto topic = strong->asTopic();
|
||||
auto row = topic
|
||||
? ChooseTopicBoxController::MakeRow(topic)
|
||||
: std::make_unique<PeerListRow>(strong->peer());
|
||||
const auto raw = row.get();
|
||||
std::move(
|
||||
_status
|
||||
) | rpl::start_with_next([=](const QString &status) {
|
||||
raw->setCustomStatus(status);
|
||||
delegate()->peerListUpdateRow(raw);
|
||||
}, _lifetime);
|
||||
|
||||
if (_status) {
|
||||
std::move(
|
||||
_status
|
||||
) | rpl::start_with_next([=](const QString &status) {
|
||||
raw->setCustomStatus(status);
|
||||
delegate()->peerListUpdateRow(raw);
|
||||
}, _lifetime);
|
||||
}
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
delegate()->peerListRefreshRows();
|
||||
|
||||
if (topic) {
|
||||
topic->destroyed() | rpl::start_with_next([=] {
|
||||
while (delegate()->peerListFullRowsCount()) {
|
||||
delegate()->peerListRemoveRow(delegate()->peerListRowAt(0));
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
void SingleRowController::loadMoreRows() {
|
||||
}
|
||||
|
||||
void SingleRowController::rowClicked(not_null<PeerListRow*> row) {
|
||||
ShowPeerInfoSync(row->peer());
|
||||
if (const auto onstack = _clicked) {
|
||||
onstack();
|
||||
} else {
|
||||
ShowPeerInfoSync(row->peer());
|
||||
}
|
||||
}
|
||||
|
||||
Main::Session &SingleRowController::session() const {
|
||||
return _peer->session();
|
||||
return *_session;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -1186,14 +1215,29 @@ bool IsExpiredLink(const Api::InviteLink &data, TimeId now) {
|
|||
void AddSinglePeerRow(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<PeerData*> peer,
|
||||
rpl::producer<QString> status) {
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked) {
|
||||
AddSinglePeerRow(
|
||||
container,
|
||||
peer->owner().history(peer),
|
||||
std::move(status),
|
||||
std::move(clicked));
|
||||
}
|
||||
|
||||
void AddSinglePeerRow(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Data::Thread*> thread,
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked) {
|
||||
const auto delegate = container->lifetime().make_state<
|
||||
PeerListContentDelegateSimple
|
||||
>();
|
||||
const auto controller = container->lifetime().make_state<
|
||||
SingleRowController
|
||||
>(peer, std::move(status));
|
||||
controller->setStyleOverrides(&st::peerListSingleRow);
|
||||
>(thread, std::move(status), std::move(clicked));
|
||||
controller->setStyleOverrides(thread->asTopic()
|
||||
? &st::chooseTopicList
|
||||
: &st::peerListSingleRow);
|
||||
const auto content = container->add(object_ptr<PeerListContent>(
|
||||
container,
|
||||
controller));
|
||||
|
|
|
@ -16,6 +16,10 @@ namespace Api {
|
|||
struct InviteLink;
|
||||
} // namespace Api
|
||||
|
||||
namespace Data {
|
||||
class Thread;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
@ -31,7 +35,14 @@ class BoxContent;
|
|||
void AddSinglePeerRow(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<PeerData*> peer,
|
||||
rpl::producer<QString> status);
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked = nullptr);
|
||||
|
||||
void AddSinglePeerRow(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Data::Thread*> thread,
|
||||
rpl::producer<QString> status,
|
||||
Fn<void()> clicked = nullptr);
|
||||
|
||||
void AddPermanentLinkBlock(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_common.h"
|
||||
#include "api/api_sending.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "base/random.h"
|
||||
#include "base/timer_rpl.h"
|
||||
|
@ -60,6 +61,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
|
@ -1786,29 +1788,23 @@ void WebViewInstance::botSendPreparedMessage(
|
|||
});
|
||||
struct State {
|
||||
QPointer<Ui::BoxContent> preview;
|
||||
rpl::event_stream<not_null<Data::Thread*>> recipient;
|
||||
bool sent = false;
|
||||
};
|
||||
const auto state = std::make_shared<State>();
|
||||
auto box = Box(PreparedPreviewBox, item, [=] {
|
||||
auto recipient = state->recipient.events();
|
||||
auto box = Box(PreparedPreviewBox, item, std::move(recipient), [=] {
|
||||
if (state->sent) {
|
||||
return;
|
||||
}
|
||||
const auto chosen = [=](not_null<Data::Thread*> thread) {
|
||||
auto action = Api::SendAction(thread);
|
||||
const auto done = [=](bool success) {
|
||||
if (success) {
|
||||
callback(QString());
|
||||
} else {
|
||||
callback(u"MESSAGE_SEND_FAILED"_q);
|
||||
}
|
||||
};
|
||||
bot->session().api().sendInlineResult(
|
||||
bot,
|
||||
parsed.get(),
|
||||
action,
|
||||
std::nullopt,
|
||||
done);
|
||||
state->sent = true;
|
||||
if (const auto strong = state->preview.data()) {
|
||||
strong->closeBox();
|
||||
if (!Data::CanSend(thread, ChatRestriction::SendInline)) {
|
||||
panel->showToast({
|
||||
tr::lng_restricted_send_inline_all(tr::now),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
state->recipient.fire_copy(thread);
|
||||
return true;
|
||||
};
|
||||
auto box = Window::PrepareChooseRecipientBox(
|
||||
|
@ -1818,6 +1814,36 @@ void WebViewInstance::botSendPreparedMessage(
|
|||
nullptr,
|
||||
types);
|
||||
panel->showBox(std::move(box));
|
||||
}, [=](not_null<Data::Thread*> thread) {
|
||||
if (state->sent) {
|
||||
return;
|
||||
}
|
||||
state->sent = true;
|
||||
const auto weak = state->preview;
|
||||
const auto done = [=](bool success) {
|
||||
if (success) {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->showToast({ tr::lng_share_done(tr::now) });
|
||||
}
|
||||
base::call_delayed(Ui::Toast::kDefaultDuration, [weak] {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
});
|
||||
callback(QString());
|
||||
} else {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
callback(u"MESSAGE_SEND_FAILED"_q);
|
||||
}
|
||||
};
|
||||
bot->session().api().sendInlineResult(
|
||||
bot,
|
||||
parsed.get(),
|
||||
Api::SendAction(thread),
|
||||
std::nullopt,
|
||||
done);
|
||||
});
|
||||
box->boxClosing() | rpl::start_with_next([=] {
|
||||
if (!state->sent) {
|
||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "inline_bots/inline_bot_confirm_prepared.h"
|
||||
|
||||
#include "boxes/peers/edit_peer_invite_link.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "history/admin_log/history_admin_log_item.h"
|
||||
|
@ -19,11 +21,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/chat/chat_theme.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
namespace InlineBots {
|
||||
namespace {
|
||||
|
@ -168,22 +172,63 @@ void PreviewWrap::paintEvent(QPaintEvent *e) {
|
|||
_item->draw(p, context);
|
||||
}
|
||||
|
||||
} // namesace
|
||||
} // namespace
|
||||
|
||||
void PreparedPreviewBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<HistoryItem*> item,
|
||||
Fn<void()> share) {
|
||||
rpl::producer<not_null<Data::Thread*>> recipient,
|
||||
Fn<void()> choose,
|
||||
Fn<void(not_null<Data::Thread*>)> send) {
|
||||
box->setTitle(tr::lng_bot_share_prepared_title());
|
||||
const auto container = box->verticalLayout();
|
||||
container->add(object_ptr<PreviewWrap>(container, item));
|
||||
const auto bot = item->viaBot();
|
||||
const auto name = bot ? bot->name() : u"Bot"_q;
|
||||
Ui::AddDividerText(
|
||||
container,
|
||||
tr::lng_bot_share_prepared_about(lt_bot, rpl::single(name))),
|
||||
box->addButton(tr::lng_bot_share_prepared_button(), share);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
const auto info = container->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::DividerLabel>>(
|
||||
container,
|
||||
object_ptr<Ui::DividerLabel>(
|
||||
container,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
tr::lng_bot_share_prepared_about(lt_bot, rpl::single(name)),
|
||||
st::boxDividerLabel),
|
||||
st::defaultBoxDividerLabelPadding,
|
||||
RectPart::Top | RectPart::Bottom)));
|
||||
const auto row = container->add(object_ptr<Ui::VerticalLayout>(
|
||||
container));
|
||||
|
||||
const auto reset = [=] {
|
||||
info->show(anim::type::instant);
|
||||
while (row->count()) {
|
||||
delete row->widgetAt(0);
|
||||
}
|
||||
box->addButton(tr::lng_bot_share_prepared_button(), choose);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
};
|
||||
reset();
|
||||
|
||||
const auto lifetime = box->lifetime().make_state<rpl::lifetime>();
|
||||
std::move(
|
||||
recipient
|
||||
) | rpl::start_with_next([=](not_null<Data::Thread*> thread) {
|
||||
info->hide(anim::type::instant);
|
||||
while (row->count()) {
|
||||
delete row->widgetAt(0);
|
||||
}
|
||||
AddSkip(row);
|
||||
AddSinglePeerRow(row, thread, nullptr, choose);
|
||||
if (const auto topic = thread->asTopic()) {
|
||||
*lifetime = topic->destroyed() | rpl::start_with_next(reset);
|
||||
} else {
|
||||
*lifetime = rpl::lifetime();
|
||||
}
|
||||
row->resizeToWidth(container->width());
|
||||
box->clearButtons();
|
||||
box->addButton(tr::lng_send_button(), [=] { send(thread); });
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}, info->lifetime());
|
||||
|
||||
item->history()->owner().itemRemoved(
|
||||
) | rpl::start_with_next([=](not_null<const HistoryItem*> removed) {
|
||||
|
|
|
@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Data {
|
||||
class Thread;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class GenericBox;
|
||||
} // namespace Ui
|
||||
|
@ -16,6 +20,8 @@ namespace InlineBots {
|
|||
void PreparedPreviewBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<HistoryItem*> item,
|
||||
Fn<void()> share);
|
||||
rpl::producer<not_null<Data::Thread*>> recipient,
|
||||
Fn<void()> choose,
|
||||
Fn<void(not_null<Data::Thread*>)> sent);
|
||||
|
||||
} // namespace InlineBots
|
||||
|
|
Loading…
Add table
Reference in a new issue