[Improvement] Allow to send inline result preview

This commit is contained in:
Eric Kotato 2022-09-11 02:44:04 +03:00
parent ea88ef5d12
commit a82748f5a0
12 changed files with 185 additions and 41 deletions

View file

@ -203,6 +203,10 @@
"ktg_filters_hide_edit_toast": "Edit button is hidden.\nYou can enable it back in Kotatogram Settings.", "ktg_filters_hide_edit_toast": "Edit button is hidden.\nYou can enable it back in Kotatogram Settings.",
"ktg_settings_telegram_sites_autologin": "Auto-login on Telegram sites", "ktg_settings_telegram_sites_autologin": "Auto-login on Telegram sites",
"ktg_mute_for_selected_time": "For selected time", "ktg_mute_for_selected_time": "For selected time",
"ktg_send_preview": "Send preview",
"ktg_send_silent_preview": "Send preview silent",
"ktg_reminder_preview": "Remind with preview",
"ktg_schedule_preview": "Send preview scheduled",
"ktg_notifications_mute_seconds": { "ktg_notifications_mute_seconds": {
"zero": "seconds", "zero": "seconds",
"one": "second", "one": "second",

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "chat_helpers/send_context_menu.h" #include "chat_helpers/send_context_menu.h"
#include "kotato/kotato_lang.h"
#include "api/api_common.h" #include "api/api_common.h"
#include "base/event_filter.h" #include "base/event_filter.h"
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
@ -55,6 +56,7 @@ FillMenuResult FillSendMenu(
} }
const auto now = type; const auto now = type;
if (now == Type::Disabled if (now == Type::Disabled
|| now == Type::PreviewOnly
|| (!silent && now == Type::SilentOnly)) { || (!silent && now == Type::SilentOnly)) {
return FillMenuResult::None; return FillMenuResult::None;
} }
@ -76,6 +78,38 @@ FillMenuResult FillSendMenu(
return FillMenuResult::Success; return FillMenuResult::Success;
} }
FillMenuResult FillSendPreviewMenu(
not_null<Ui::PopupMenu*> menu,
Type type,
Fn<void()> defaultSend,
Fn<void()> silent,
Fn<void()> schedule) {
if (!defaultSend && !silent && !schedule) {
return FillMenuResult::None;
}
const auto now = type;
if (now == Type::Disabled) {
return FillMenuResult::None;
}
if (defaultSend) {
menu->addAction(ktr("ktg_send_preview"), defaultSend);
}
if (type != Type::PreviewOnly) {
if (silent && now != Type::Reminder) {
menu->addAction(ktr("ktg_send_silent_preview"), silent);
}
if (schedule && now != Type::SilentOnly) {
menu->addAction(
(now == Type::Reminder
? ktr("ktg_reminder_preview")
: ktr("ktg_schedule_preview")),
schedule);
}
}
return FillMenuResult::Success;
}
void SetupMenuAndShortcuts( void SetupMenuAndShortcuts(
not_null<Ui::RpWidget*> button, not_null<Ui::RpWidget*> button,
Fn<Type()> type, Fn<Type()> type,
@ -109,6 +143,7 @@ void SetupMenuAndShortcuts(
const auto now = type(); const auto now = type();
if (now == Type::Disabled if (now == Type::Disabled
|| now == Type::PreviewOnly
|| (!silent && now == Type::SilentOnly)) { || (!silent && now == Type::SilentOnly)) {
return; return;
} }

View file

@ -25,6 +25,7 @@ enum class Type {
Scheduled, Scheduled,
ScheduledToUser, // For "Send when online". ScheduledToUser, // For "Send when online".
Reminder, Reminder,
PreviewOnly,
}; };
enum class FillMenuResult { enum class FillMenuResult {
@ -44,6 +45,13 @@ FillMenuResult FillSendMenu(
Fn<void()> silent, Fn<void()> silent,
Fn<void()> schedule); Fn<void()> schedule);
FillMenuResult FillSendPreviewMenu(
not_null<Ui::PopupMenu*> menu,
Type type,
Fn<void()> defaultSend,
Fn<void()> silent,
Fn<void()> schedule);
void SetupMenuAndShortcuts( void SetupMenuAndShortcuts(
not_null<Ui::RpWidget*> button, not_null<Ui::RpWidget*> button,
Fn<Type()> type, Fn<Type()> type,

View file

@ -1076,7 +1076,20 @@ void HistoryWidget::initTabbedSelector() {
selector->inlineResultChosen( selector->inlineResultChosen(
) | filter | rpl::start_with_next([=](Selector::InlineChosen data) { ) | filter | rpl::start_with_next([=](Selector::InlineChosen data) {
sendInlineResult(data); if (data.sendPreview) {
const auto request = data.result->openRequest();
if (const auto photo = request.photo()) {
sendExistingPhoto(photo, data.options);
} else if (const auto document = request.document()) {
sendExistingDocument(document, data.options);
}
addRecentBot(data.bot);
clearFieldText();
saveCloudDraft();
} else {
sendInlineResult(data);
}
}, lifetime()); }, lifetime());
selector->contextMenuRequested( selector->contextMenuRequested(
@ -1517,6 +1530,17 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
} else if (const auto document = request.document()) { } else if (const auto document = request.document()) {
controller()->openDocument(document, FullMsgId()); controller()->openDocument(document, FullMsgId());
} }
} else if (result.sendPreview) {
const auto request = result.result->openRequest();
if (const auto photo = request.photo()) {
sendExistingPhoto(photo, result.options);
} else if (const auto document = request.document()) {
sendExistingDocument(document, result.options);
}
addRecentBot(result.bot);
clearFieldText();
saveCloudDraft();
} else { } else {
sendInlineResult(result); sendInlineResult(result);
} }
@ -6160,17 +6184,7 @@ void HistoryWidget::sendInlineResult(InlineBots::ResultSelected result) {
_saveDraftStart = crl::now(); _saveDraftStart = crl::now();
saveDraft(); saveDraft();
auto &bots = cRefRecentInlineBots(); addRecentBot(result.bot);
const auto index = bots.indexOf(result.bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(result.bot);
session().local().writeRecentHashtagsAndBots();
}
hideSelectorControlsAnimated(); hideSelectorControlsAnimated();
@ -7300,6 +7314,20 @@ void HistoryWidget::messageDataReceived(
} }
} }
void HistoryWidget::addRecentBot(not_null<UserData*> bot) {
auto &bots = cRefRecentInlineBots();
const auto index = bots.indexOf(bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(bot);
session().local().writeRecentHashtagsAndBots();
}
}
void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) { void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
_replyEditMsgText.setMarkedText( _replyEditMsgText.setMarkedText(
st::messageTextStyle, st::messageTextStyle,

View file

@ -379,6 +379,8 @@ private:
void requestMessageData(MsgId msgId); void requestMessageData(MsgId msgId);
void messageDataReceived(not_null<PeerData*> peer, MsgId msgId); void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
void addRecentBot(not_null<UserData*> bot);
[[nodiscard]] Api::SendAction prepareSendAction( [[nodiscard]] Api::SendAction prepareSendAction(
Api::SendOptions options) const; Api::SendOptions options) const;
void send(Api::SendOptions options); void send(Api::SendOptions options);

View file

@ -50,6 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/file_utilities.h" #include "core/file_utilities.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_channel.h" #include "data/data_channel.h"
@ -556,7 +557,20 @@ void RepliesWidget::setupComposeControls() {
_composeControls->inlineResultChosen( _composeControls->inlineResultChosen(
) | rpl::start_with_next([=](Selector::InlineChosen chosen) { ) | rpl::start_with_next([=](Selector::InlineChosen chosen) {
sendInlineResult(chosen.result, chosen.bot, chosen.options); if (chosen.sendPreview) {
const auto request = chosen.result->openRequest();
if (const auto photo = request.photo()) {
sendExistingPhoto(photo, chosen.options);
} else if (const auto document = request.document()) {
sendExistingDocument(document, chosen.options);
}
addRecentBot(chosen.bot);
_composeControls->clear();
finishSending();
} else {
sendInlineResult(chosen.result, chosen.bot, chosen.options);
}
}, lifetime()); }, lifetime());
_composeControls->scrollRequests( _composeControls->scrollRequests(
@ -911,6 +925,20 @@ bool RepliesWidget::showSendingFilesError(
return true; return true;
} }
void RepliesWidget::addRecentBot(not_null<UserData*> bot) {
auto &bots = cRefRecentInlineBots();
const auto index = bots.indexOf(bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(bot);
bot->session().local().writeRecentHashtagsAndBots();
}
}
Api::SendAction RepliesWidget::prepareSendAction( Api::SendAction RepliesWidget::prepareSendAction(
Api::SendOptions options) const { Api::SendOptions options) const {
auto result = Api::SendAction(_history, options); auto result = Api::SendAction(_history, options);
@ -1085,9 +1113,15 @@ bool RepliesWidget::sendExistingDocument(
return false; return false;
} }
Api::SendExistingDocument( if (document->hasRemoteLocation()) {
Api::MessageToSend(prepareSendAction(options)), Api::SendExistingDocument(
document); Api::MessageToSend(prepareSendAction(options)),
document);
} else {
Api::SendWebDocument(
Api::MessageToSend(prepareSendAction(options)),
document);
}
_composeControls->cancelReplyMessage(); _composeControls->cancelReplyMessage();
finishSending(); finishSending();
@ -1159,17 +1193,7 @@ void RepliesWidget::sendInlineResult(
//_saveDraftStart = crl::now(); //_saveDraftStart = crl::now();
//onDraftSave(); //onDraftSave();
auto &bots = cRefRecentInlineBots(); addRecentBot(bot);
const auto index = bots.indexOf(bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(bot);
bot->session().local().writeRecentHashtagsAndBots();
}
finishSending(); finishSending();
} }

View file

@ -193,6 +193,8 @@ private:
void clearSelected(); void clearSelected();
void setPinnedVisibility(bool shown); void setPinnedVisibility(bool shown);
void addRecentBot(not_null<UserData*> bot);
[[nodiscard]] Api::SendAction prepareSendAction( [[nodiscard]] Api::SendAction prepareSendAction(
Api::SendOptions options) const; Api::SendOptions options) const;
void send(); void send();

View file

@ -261,7 +261,21 @@ void ScheduledWidget::setupComposeControls() {
_composeControls->inlineResultChosen( _composeControls->inlineResultChosen(
) | rpl::start_with_next([=](Selector::InlineChosen chosen) { ) | rpl::start_with_next([=](Selector::InlineChosen chosen) {
sendInlineResult(chosen.result, chosen.bot); if (chosen.sendPreview) {
const auto request = chosen.result->openRequest();
if (const auto photo = request.photo()) {
sendExistingPhoto(photo);
} else if (const auto document = request.document()) {
sendExistingDocument(document);
}
addRecentBot(chosen.bot);
_composeControls->clear();
_composeControls->hidePanelsAnimated();
_composeControls->focus();
} else {
sendInlineResult(chosen.result, chosen.bot);
}
}, lifetime()); }, lifetime());
_composeControls->scrollRequests( _composeControls->scrollRequests(
@ -518,6 +532,20 @@ bool ScheduledWidget::showSendingFilesError(
return true; return true;
} }
void ScheduledWidget::addRecentBot(not_null<UserData*> bot) {
auto &bots = cRefRecentInlineBots();
const auto index = bots.indexOf(bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(bot);
bot->session().local().writeRecentHashtagsAndBots();
}
}
Api::SendAction ScheduledWidget::prepareSendAction( Api::SendAction ScheduledWidget::prepareSendAction(
Api::SendOptions options) const { Api::SendOptions options) const {
auto result = Api::SendAction(_history, options); auto result = Api::SendAction(_history, options);
@ -759,17 +787,7 @@ void ScheduledWidget::sendInlineResult(
//_saveDraftStart = crl::now(); //_saveDraftStart = crl::now();
//onDraftSave(); //onDraftSave();
auto &bots = cRefRecentInlineBots(); addRecentBot(bot);
const auto index = bots.indexOf(bot);
if (index) {
if (index > 0) {
bots.removeAt(index);
} else if (bots.size() >= RecentInlineBotsLimit) {
bots.resize(RecentInlineBotsLimit - 1);
}
bots.push_front(bot);
bot->session().local().writeRecentHashtagsAndBots();
}
_composeControls->hidePanelsAnimated(); _composeControls->hidePanelsAnimated();
_composeControls->focus(); _composeControls->focus();

View file

@ -158,6 +158,8 @@ private:
void confirmDeleteSelected(); void confirmDeleteSelected();
void clearSelected(); void clearSelected();
void addRecentBot(not_null<UserData*> bot);
[[nodiscard]] Api::SendAction prepareSendAction( [[nodiscard]] Api::SendAction prepareSendAction(
Api::SendOptions options) const; Api::SendOptions options) const;
void send(); void send();

View file

@ -134,6 +134,7 @@ struct ResultSelected {
Api::SendOptions options; Api::SendOptions options;
// Open in OverlayWidget; // Open in OverlayWidget;
bool open = false; bool open = false;
bool sendPreview = false;
}; };
} // namespace InlineBots } // namespace InlineBots

View file

@ -259,7 +259,8 @@ void Inner::mouseReleaseEvent(QMouseEvent *e) {
void Inner::selectInlineResult( void Inner::selectInlineResult(
int index, int index,
Api::SendOptions options, Api::SendOptions options,
bool open) { bool open,
bool sendPreview) {
const auto item = _mosaic.maybeItemAt(index); const auto item = _mosaic.maybeItemAt(index);
if (!item) { if (!item) {
return; return;
@ -272,6 +273,7 @@ void Inner::selectInlineResult(
.bot = _inlineBot, .bot = _inlineBot,
.options = std::move(options), .options = std::move(options),
.open = open, .open = open,
.sendPreview = sendPreview,
}); });
} }
} }
@ -317,8 +319,23 @@ void Inner::contextMenuEvent(QContextMenuEvent *e) {
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send)); SendMenu::DefaultScheduleCallback(this, type, send));
const auto hideViaActions = [&] {
const auto sendPreview = [=, selected = _selected](Api::SendOptions options) {
selectInlineResult(selected, options, false, true);
};
SendMenu::FillSendPreviewMenu(
_menu,
type,
[=] { sendPreview({}); },
SendMenu::DefaultSilentCallback(sendPreview),
SendMenu::DefaultScheduleCallback(this, type, sendPreview));
};
const auto item = _mosaic.itemAt(_selected); const auto item = _mosaic.itemAt(_selected);
if (const auto previewDocument = item->getPreviewDocument()) { if (const auto previewDocument = item->getPreviewDocument()) {
hideViaActions();
auto callback = [&]( auto callback = [&](
const QString &text, const QString &text,
Fn<void()> &&done, Fn<void()> &&done,
@ -326,6 +343,8 @@ void Inner::contextMenuEvent(QContextMenuEvent *e) {
_menu->addAction(text, std::move(done), icon); _menu->addAction(text, std::move(done), icon);
}; };
ChatHelpers::AddGifAction(std::move(callback), previewDocument); ChatHelpers::AddGifAction(std::move(callback), previewDocument);
} else if (const auto previewPhoto = item->getPreviewPhoto()) {
hideViaActions();
} }
if (!_menu->empty()) { if (!_menu->empty()) {

View file

@ -145,7 +145,8 @@ private:
void selectInlineResult( void selectInlineResult(
int index, int index,
Api::SendOptions options, Api::SendOptions options,
bool open); bool open,
bool sendPreview = false);
not_null<Window::SessionController*> _controller; not_null<Window::SessionController*> _controller;
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient; const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;