mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 07:33:52 +02:00
Show "Join" button for pinned call links.
This commit is contained in:
parent
fb25d90b48
commit
ee7a2b564b
4 changed files with 160 additions and 99 deletions
|
@ -7651,12 +7651,12 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
}
|
||||
return (count > 1);
|
||||
}) | rpl::distinct_until_changed();
|
||||
auto markupRefreshed = HistoryView::PinnedBarItemWithReplyMarkup(
|
||||
auto customButtonItem = HistoryView::PinnedBarItemWithCustomButton(
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId());
|
||||
rpl::combine(
|
||||
rpl::duplicate(pinnedRefreshed),
|
||||
rpl::duplicate(markupRefreshed)
|
||||
rpl::duplicate(customButtonItem)
|
||||
) | rpl::start_with_next([=](bool many, HistoryItem *item) {
|
||||
refreshPinnedBarButton(many, item);
|
||||
}, _pinnedBar->lifetime());
|
||||
|
@ -7667,7 +7667,7 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
_pinnedTracker->shownMessageId(),
|
||||
[bar = _pinnedBar.get()] { bar->customEmojiRepaint(); }),
|
||||
std::move(pinnedRefreshed),
|
||||
std::move(markupRefreshed)
|
||||
std::move(customButtonItem)
|
||||
) | rpl::map([=](Ui::MessageBarContent &&content, bool, HistoryItem*) {
|
||||
const auto id = (!content.title.isEmpty() || !content.text.empty())
|
||||
? _pinnedTracker->currentMessageId().message
|
||||
|
@ -7805,58 +7805,31 @@ void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) {
|
|||
? id.message.msg
|
||||
: (id.message.msg - ServerMaxMsgId))));
|
||||
};
|
||||
if (const auto replyMarkup = item ? item->inlineReplyMarkup() : nullptr) {
|
||||
const auto &rows = replyMarkup->data.rows;
|
||||
if ((rows.size() == 1) && (rows.front().size() == 1)) {
|
||||
const auto text = rows.front().front().text;
|
||||
if (!text.isEmpty()) {
|
||||
const auto &st = st::historyPinnedBotButton;
|
||||
auto button = object_ptr<Ui::RoundButton>(
|
||||
this,
|
||||
rpl::never<QString>(),
|
||||
st);
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button.data(),
|
||||
text,
|
||||
st::historyPinnedBotLabel);
|
||||
if (label->width() > st::historyPinnedBotButtonMaxWidth) {
|
||||
label->resizeToWidth(st::historyPinnedBotButtonMaxWidth);
|
||||
}
|
||||
button->setFullWidth(label->width()
|
||||
+ st.padding.left()
|
||||
+ st.padding.right()
|
||||
+ st.height);
|
||||
label->moveToLeft(
|
||||
st.padding.left() + st.height / 2,
|
||||
(button->height() - label->height()) / 2);
|
||||
label->setTextColorOverride(st.textFg->c);
|
||||
label->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
button->setTextTransform(
|
||||
Ui::RoundButton::TextTransform::NoTransform);
|
||||
button->setFullRadius(true);
|
||||
button->setClickedCallback([=] {
|
||||
Api::ActivateBotCommand(
|
||||
_list->prepareClickHandlerContext(item->fullId()),
|
||||
0,
|
||||
0);
|
||||
});
|
||||
struct State {
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto state = button->lifetime().make_state<State>();
|
||||
_pinnedBar->contextMenuRequested(
|
||||
) | rpl::start_with_next([=, raw = button.data()] {
|
||||
state->menu = base::make_unique_q<Ui::PopupMenu>(raw);
|
||||
state->menu->addAction(
|
||||
tr::lng_settings_events_pinned(tr::now),
|
||||
openSection);
|
||||
state->menu->popup(QCursor::pos());
|
||||
}, button->lifetime());
|
||||
_pinnedBar->setRightButton(std::move(button));
|
||||
return;
|
||||
}
|
||||
const auto context = [copy = _list](FullMsgId itemId) {
|
||||
if (const auto raw = copy.data()) {
|
||||
return raw->prepareClickHandlerContext(itemId);
|
||||
}
|
||||
return ClickHandlerContext();
|
||||
};
|
||||
auto customButton = CreatePinnedBarCustomButton(this, item, context);
|
||||
if (customButton) {
|
||||
struct State {
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto buttonRaw = customButton.data();
|
||||
const auto state = buttonRaw->lifetime().make_state<State>();
|
||||
_pinnedBar->contextMenuRequested(
|
||||
) | rpl::start_with_next([=] {
|
||||
state->menu = base::make_unique_q<Ui::PopupMenu>(buttonRaw);
|
||||
state->menu->addAction(
|
||||
tr::lng_settings_events_pinned(tr::now),
|
||||
openSection);
|
||||
state->menu->popup(QCursor::pos());
|
||||
}, buttonRaw->lifetime());
|
||||
_pinnedBar->setRightButton(std::move(customButton));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto close = !many;
|
||||
auto button = object_ptr<Ui::IconButton>(
|
||||
this,
|
||||
|
|
|
@ -7,17 +7,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "history/view/history_view_pinned_bar.h"
|
||||
|
||||
#include "api/api_bot.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 "data/data_web_page.h"
|
||||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/basic_click_handlers.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
|
@ -153,6 +160,45 @@ auto WithPinnedTitle(not_null<Main::Session*> session, PinnedId id) {
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RoundButton> MakePinnedBarCustomButton(
|
||||
not_null<QWidget*> parent,
|
||||
const QString &buttonText,
|
||||
Fn<void()> clickCallback) {
|
||||
const auto &stButton = st::historyPinnedBotButton;
|
||||
const auto &stLabel = st::historyPinnedBotLabel;
|
||||
|
||||
auto button = object_ptr<Ui::RoundButton>(
|
||||
parent,
|
||||
rpl::never<QString>(), // Text is handled by the inner label.
|
||||
stButton);
|
||||
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button.data(),
|
||||
buttonText,
|
||||
stLabel);
|
||||
|
||||
if (label->width() > st::historyPinnedBotButtonMaxWidth) {
|
||||
label->resizeToWidth(st::historyPinnedBotButtonMaxWidth);
|
||||
}
|
||||
button->setFullWidth(label->width()
|
||||
+ stButton.padding.left()
|
||||
+ stButton.padding.right()
|
||||
+ stButton.height); // stButton.height is likely for icon spacing.
|
||||
|
||||
label->moveToLeft(
|
||||
stButton.padding.left() + stButton.height / 2,
|
||||
(button->height() - label->height()) / 2);
|
||||
|
||||
label->setTextColorOverride(stButton.textFg->c); // Use button's text color for label.
|
||||
label->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
button->setFullRadius(true);
|
||||
button->setClickedCallback(std::move(clickCallback));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
rpl::producer<Ui::MessageBarContent> MessageBarContentByItemId(
|
||||
|
@ -178,7 +224,7 @@ rpl::producer<Ui::MessageBarContent> PinnedBarContent(
|
|||
}) | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
||||
rpl::producer<HistoryItem*> PinnedBarItemWithCustomButton(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedId> id) {
|
||||
return rpl::make_producer<HistoryItem*>([=,
|
||||
|
@ -187,7 +233,7 @@ rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
|||
consumer.put_next(nullptr);
|
||||
|
||||
struct State {
|
||||
bool hasReplyMarkup = false;
|
||||
bool hasCustomButton = false;
|
||||
base::has_weak_ptr guard;
|
||||
rpl::lifetime lifetime;
|
||||
FullMsgId resolvedId;
|
||||
|
@ -196,10 +242,17 @@ rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
|||
|
||||
const auto pushUnique = [=](not_null<HistoryItem*> item) {
|
||||
const auto replyMarkup = item->inlineReplyMarkup();
|
||||
if (!state->hasReplyMarkup && !replyMarkup) {
|
||||
const auto media = item->media();
|
||||
const auto page = media ? media->webpage() : nullptr;
|
||||
const auto possiblyHasCustomButton = replyMarkup
|
||||
|| (page
|
||||
&& (page->type == WebPageType::VoiceChat
|
||||
|| page->type == WebPageType::Livestream
|
||||
|| page->type == WebPageType::ConferenceCall));
|
||||
if (!state->hasCustomButton && !possiblyHasCustomButton) {
|
||||
return;
|
||||
}
|
||||
state->hasReplyMarkup = (replyMarkup != nullptr);
|
||||
state->hasCustomButton = possiblyHasCustomButton;
|
||||
consumer.put_next(item.get());
|
||||
};
|
||||
|
||||
|
@ -217,12 +270,14 @@ rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
|||
using Update = Data::MessageUpdate;
|
||||
session->changes().messageUpdates(
|
||||
item,
|
||||
Update::Flag::ReplyMarkup | Update::Flag::Destroyed
|
||||
(Update::Flag::ReplyMarkup
|
||||
| Update::Flag::Edited
|
||||
| Update::Flag::Destroyed)
|
||||
) | rpl::start_with_next([=](const Update &update) {
|
||||
if (update.flags & Update::Flag::Destroyed) {
|
||||
state->lifetime.destroy();
|
||||
invalidate_weak_ptrs(&state->guard);
|
||||
state->hasReplyMarkup = false;
|
||||
state->hasCustomButton = false;
|
||||
consumer.put_next(nullptr);
|
||||
} else {
|
||||
pushUnique(update.item);
|
||||
|
@ -248,4 +303,42 @@ rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
|||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RoundButton> CreatePinnedBarCustomButton(
|
||||
not_null<QWidget*> parent,
|
||||
HistoryItem *item,
|
||||
Fn<ClickHandlerContext(FullMsgId)> context) {
|
||||
if (!item) {
|
||||
return nullptr;
|
||||
} else if (const auto replyMarkup = item->inlineReplyMarkup()) {
|
||||
const auto &rows = replyMarkup->data.rows;
|
||||
if ((rows.size() == 1) && (rows.front().size() == 1)) {
|
||||
const auto text = rows.front().front().text;
|
||||
if (!text.isEmpty()) {
|
||||
const auto contextId = item->fullId();
|
||||
const auto callback = [=] {
|
||||
Api::ActivateBotCommand(context(contextId), 0, 0);
|
||||
};
|
||||
return MakePinnedBarCustomButton(parent, text, callback);
|
||||
}
|
||||
}
|
||||
} else if (const auto media = item->media()) {
|
||||
if (const auto page = media->webpage()) {
|
||||
if (page->type == WebPageType::VoiceChat
|
||||
|| page->type == WebPageType::Livestream
|
||||
|| page->type == WebPageType::ConferenceCall) {
|
||||
const auto url = page->url;
|
||||
const auto contextId = item->fullId();
|
||||
const auto callback = [=] {
|
||||
UrlClickHandler::Open(
|
||||
url,
|
||||
QVariant::fromValue(context(contextId)));
|
||||
};
|
||||
const auto text = tr::lng_group_call_join(tr::now);
|
||||
return MakePinnedBarCustomButton(parent, text, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -7,10 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/object_ptr.h"
|
||||
#include "ui/chat/message_bar.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
struct ClickHandlerContext;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
@ -18,6 +21,7 @@ class Session;
|
|||
namespace Ui {
|
||||
class IconButton;
|
||||
class PlainShadow;
|
||||
class RoundButton;
|
||||
struct MessageBarContent;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -51,8 +55,13 @@ struct PinnedId {
|
|||
rpl::producer<PinnedId> id,
|
||||
Fn<void()> repaint);
|
||||
|
||||
[[nodiscard]] rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
||||
[[nodiscard]] rpl::producer<HistoryItem*> PinnedBarItemWithCustomButton(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedId> id);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RoundButton> CreatePinnedBarCustomButton(
|
||||
not_null<QWidget*> parent,
|
||||
HistoryItem *item,
|
||||
Fn<ClickHandlerContext(FullMsgId)> context);
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -1838,12 +1838,12 @@ void RepliesWidget::checkPinnedBarState() {
|
|||
}
|
||||
return (count > 1);
|
||||
}) | rpl::distinct_until_changed();
|
||||
auto markupRefreshed = HistoryView::PinnedBarItemWithReplyMarkup(
|
||||
auto customButtonItem = HistoryView::PinnedBarItemWithCustomButton(
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId());
|
||||
rpl::combine(
|
||||
rpl::duplicate(pinnedRefreshed),
|
||||
rpl::duplicate(markupRefreshed)
|
||||
rpl::duplicate(customButtonItem)
|
||||
) | rpl::start_with_next([=](bool many, HistoryItem *item) {
|
||||
refreshPinnedBarButton(many, item);
|
||||
}, _pinnedBar->lifetime());
|
||||
|
@ -1854,7 +1854,7 @@ void RepliesWidget::checkPinnedBarState() {
|
|||
_pinnedTracker->shownMessageId(),
|
||||
[bar = _pinnedBar.get()] { bar->customEmojiRepaint(); }),
|
||||
std::move(pinnedRefreshed),
|
||||
std::move(markupRefreshed),
|
||||
std::move(customButtonItem),
|
||||
_rootVisible.value()
|
||||
) | rpl::map([=](Ui::MessageBarContent &&content, auto, auto, bool show) {
|
||||
const auto shown = !content.title.isEmpty() && !content.text.empty();
|
||||
|
@ -1935,43 +1935,29 @@ void RepliesWidget::refreshPinnedBarButton(bool many, HistoryItem *item) {
|
|||
controller()->showSection(
|
||||
std::make_shared<PinnedMemento>(_topic, id.message.msg));
|
||||
};
|
||||
if (const auto replyMarkup = item ? item->inlineReplyMarkup() : nullptr) {
|
||||
const auto &rows = replyMarkup->data.rows;
|
||||
if ((rows.size() == 1) && (rows.front().size() == 1)) {
|
||||
const auto text = rows.front().front().text;
|
||||
if (!text.isEmpty()) {
|
||||
auto button = object_ptr<Ui::RoundButton>(
|
||||
this,
|
||||
rpl::single(text),
|
||||
st::historyPinnedBotButton);
|
||||
button->setTextTransform(
|
||||
Ui::RoundButton::TextTransform::NoTransform);
|
||||
button->setFullRadius(true);
|
||||
button->setClickedCallback([=] {
|
||||
Api::ActivateBotCommand(
|
||||
_inner->prepareClickHandlerContext(item->fullId()),
|
||||
0,
|
||||
0);
|
||||
});
|
||||
if (button->width() > st::historyPinnedBotButtonMaxWidth) {
|
||||
button->setFullWidth(st::historyPinnedBotButtonMaxWidth);
|
||||
}
|
||||
struct State {
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto state = button->lifetime().make_state<State>();
|
||||
_pinnedBar->contextMenuRequested(
|
||||
) | rpl::start_with_next([=, raw = button.data()] {
|
||||
state->menu = base::make_unique_q<Ui::PopupMenu>(raw);
|
||||
state->menu->addAction(
|
||||
tr::lng_settings_events_pinned(tr::now),
|
||||
openSection);
|
||||
state->menu->popup(QCursor::pos());
|
||||
}, button->lifetime());
|
||||
_pinnedBar->setRightButton(std::move(button));
|
||||
return;
|
||||
}
|
||||
const auto context = [copy = _inner](FullMsgId itemId) {
|
||||
if (const auto raw = copy.data()) {
|
||||
return raw->prepareClickHandlerContext(itemId);
|
||||
}
|
||||
return ClickHandlerContext();
|
||||
};
|
||||
auto customButton = CreatePinnedBarCustomButton(this, item, context);
|
||||
if (customButton) {
|
||||
struct State {
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto buttonRaw = customButton.data();
|
||||
const auto state = buttonRaw->lifetime().make_state<State>();
|
||||
_pinnedBar->contextMenuRequested(
|
||||
) | rpl::start_with_next([=] {
|
||||
state->menu = base::make_unique_q<Ui::PopupMenu>(buttonRaw);
|
||||
state->menu->addAction(
|
||||
tr::lng_settings_events_pinned(tr::now),
|
||||
openSection);
|
||||
state->menu->popup(QCursor::pos());
|
||||
}, buttonRaw->lifetime());
|
||||
_pinnedBar->setRightButton(std::move(customButton));
|
||||
return;
|
||||
}
|
||||
const auto close = !many;
|
||||
auto button = object_ptr<Ui::IconButton>(
|
||||
|
|
Loading…
Add table
Reference in a new issue