mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow sending photo/video captions above media.
This commit is contained in:
parent
924d80ecba
commit
67f7816088
15 changed files with 182 additions and 46 deletions
|
@ -251,6 +251,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_caption_limit2#other" = "Make the caption shorter or subscribe to **Telegram Premium** to double the limit to **{count}** characters.";
|
"lng_caption_limit2#other" = "Make the caption shorter or subscribe to **Telegram Premium** to double the limit to **{count}** characters.";
|
||||||
"lng_caption_limit_reached#one" = "You've reached the media caption limit. Please make the caption shorter by {count} character.";
|
"lng_caption_limit_reached#one" = "You've reached the media caption limit. Please make the caption shorter by {count} character.";
|
||||||
"lng_caption_limit_reached#other" = "You've reached the media caption limit. Please make the caption shorter by {count} characters.";
|
"lng_caption_limit_reached#other" = "You've reached the media caption limit. Please make the caption shorter by {count} characters.";
|
||||||
|
"lng_caption_move_up" = "Move Caption Up";
|
||||||
|
"lng_caption_move_down" = "Move Caption Down";
|
||||||
|
|
||||||
"lng_file_size_limit_title" = "File Too Large";
|
"lng_file_size_limit_title" = "File Too Large";
|
||||||
"lng_file_size_limit#one" = "{count} Gb";
|
"lng_file_size_limit#one" = "{count} Gb";
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct SendOptions {
|
||||||
EffectId effectId = 0;
|
EffectId effectId = 0;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
bool handleSupportSwitch = false;
|
bool handleSupportSwitch = false;
|
||||||
|
bool invertCaption = false;
|
||||||
bool hideViaBot = false;
|
bool hideViaBot = false;
|
||||||
crl::time ttlSeconds = 0;
|
crl::time ttlSeconds = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,7 +81,8 @@ mtpRequestId EditMessage(
|
||||||
| ((!webpage.removed && !webpage.url.isEmpty())
|
| ((!webpage.removed && !webpage.url.isEmpty())
|
||||||
? MTPmessages_EditMessage::Flag::f_media
|
? MTPmessages_EditMessage::Flag::f_media
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| ((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
| (((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||||
|
|| options.invertCaption)
|
||||||
? MTPmessages_EditMessage::Flag::f_invert_media
|
? MTPmessages_EditMessage::Flag::f_invert_media
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (!sentEntities.v.isEmpty()
|
| (!sentEntities.v.isEmpty()
|
||||||
|
|
|
@ -136,6 +136,10 @@ void SendExistingMedia(
|
||||||
if (action.options.effectId) {
|
if (action.options.effectId) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||||
}
|
}
|
||||||
|
if (action.options.invertCaption) {
|
||||||
|
flags |= MessageFlag::InvertMedia;
|
||||||
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
|
}
|
||||||
|
|
||||||
session->data().registerMessageRandomId(randomId, newId);
|
session->data().registerMessageRandomId(randomId, newId);
|
||||||
|
|
||||||
|
@ -314,6 +318,10 @@ bool SendDice(MessageToSend &message) {
|
||||||
if (action.options.effectId) {
|
if (action.options.effectId) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||||
}
|
}
|
||||||
|
if (action.options.invertCaption) {
|
||||||
|
flags |= MessageFlag::InvertMedia;
|
||||||
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
|
}
|
||||||
|
|
||||||
session->data().registerMessageRandomId(randomId, newId);
|
session->data().registerMessageRandomId(randomId, newId);
|
||||||
|
|
||||||
|
@ -440,6 +448,9 @@ void SendConfirmedFile(
|
||||||
flags |= MessageFlag::MediaIsUnread;
|
flags |= MessageFlag::MediaIsUnread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (file->to.options.invertCaption) {
|
||||||
|
flags |= MessageFlag::InvertMedia;
|
||||||
|
}
|
||||||
|
|
||||||
const auto messageFromId = file->to.options.sendAs
|
const auto messageFromId = file->to.options.sendAs
|
||||||
? file->to.options.sendAs->id
|
? file->to.options.sendAs->id
|
||||||
|
|
|
@ -3772,7 +3772,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
const auto anonymousPost = peer->amAnonymous();
|
const auto anonymousPost = peer->amAnonymous();
|
||||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||||
FillMessagePostFlags(action, peer, flags);
|
FillMessagePostFlags(action, peer, flags);
|
||||||
if (exactWebPage && !ignoreWebPage && message.webPage.invert) {
|
if ((exactWebPage && !ignoreWebPage && message.webPage.invert)
|
||||||
|
|| action.options.invertCaption) {
|
||||||
flags |= MessageFlag::InvertMedia;
|
flags |= MessageFlag::InvertMedia;
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
|
||||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
|
@ -4170,7 +4171,8 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
||||||
| (options.sendAs ? Flag::f_send_as : Flag(0))
|
| (options.sendAs ? Flag::f_send_as : Flag(0))
|
||||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||||
| (options.effectId ? Flag::f_effect : Flag(0));
|
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||||
|
| (options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||||
|
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
|
@ -4280,7 +4282,8 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||||
| (album->options.shortcutId
|
| (album->options.shortcutId
|
||||||
? Flag::f_quick_reply_shortcut
|
? Flag::f_quick_reply_shortcut
|
||||||
: Flag(0))
|
: Flag(0))
|
||||||
| (album->options.effectId ? Flag::f_effect : Flag(0));
|
| (album->options.effectId ? Flag::f_effect : Flag(0))
|
||||||
|
| (album->options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
histories.sendPreparedMessage(
|
histories.sendPreparedMessage(
|
||||||
|
|
|
@ -350,9 +350,8 @@ SendFilesBox::SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor)
|
||||||
, _titleHeight(st::boxTitleHeight)
|
, _titleHeight(st::boxTitleHeight)
|
||||||
, _list(std::move(descriptor.list))
|
, _list(std::move(descriptor.list))
|
||||||
, _limits(descriptor.limits)
|
, _limits(descriptor.limits)
|
||||||
, _sendMenuDetails(descriptor.sendMenuDetails
|
, _sendMenuDetails(prepareSendMenuDetails(descriptor))
|
||||||
? descriptor.sendMenuDetails
|
, _sendMenuCallback(prepareSendMenuCallback())
|
||||||
: [] { return SendMenu::Details(); })
|
|
||||||
, _captionToPeer(descriptor.captionToPeer)
|
, _captionToPeer(descriptor.captionToPeer)
|
||||||
, _check(std::move(descriptor.check))
|
, _check(std::move(descriptor.check))
|
||||||
, _confirmedCallback(std::move(descriptor.confirmed))
|
, _confirmedCallback(std::move(descriptor.confirmed))
|
||||||
|
@ -366,6 +365,50 @@ SendFilesBox::SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor)
|
||||||
enqueueNextPrepare();
|
enqueueNextPrepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fn<SendMenu::Details()> SendFilesBox::prepareSendMenuDetails(
|
||||||
|
const SendFilesBoxDescriptor &descriptor) {
|
||||||
|
auto initial = descriptor.sendMenuDetails;
|
||||||
|
return crl::guard(this, [=] {
|
||||||
|
auto result = initial ? initial() : SendMenu::Details();
|
||||||
|
result.spoiler = !hasSpoilerMenu()
|
||||||
|
? SendMenu::SpoilerState::None
|
||||||
|
: allWithSpoilers()
|
||||||
|
? SendMenu::SpoilerState::Enabled
|
||||||
|
: SendMenu::SpoilerState::Possible;
|
||||||
|
const auto way = _sendWay.current();
|
||||||
|
const auto canMoveCaption = _list.canMoveCaption(
|
||||||
|
way.groupFiles() && way.sendImagesAsPhotos(),
|
||||||
|
way.sendImagesAsPhotos()
|
||||||
|
) && _caption && !_caption->getLastText().isEmpty();
|
||||||
|
result.caption = !canMoveCaption
|
||||||
|
? SendMenu::CaptionState::None
|
||||||
|
: _invertCaption
|
||||||
|
? SendMenu::CaptionState::Above
|
||||||
|
: SendMenu::CaptionState::Below;
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SendFilesBox::prepareSendMenuCallback()
|
||||||
|
-> Fn<void(MenuAction, MenuDetails)> {
|
||||||
|
return crl::guard(this, [=](MenuAction action, MenuDetails details) {
|
||||||
|
using Type = SendMenu::ActionType;
|
||||||
|
switch (action.type) {
|
||||||
|
case Type::CaptionDown: _invertCaption = false; break;
|
||||||
|
case Type::CaptionUp: _invertCaption = true; break;
|
||||||
|
case Type::SpoilerOn: toggleSpoilers(true); break;
|
||||||
|
case Type::SpoilerOff: toggleSpoilers(false); break;
|
||||||
|
default:
|
||||||
|
SendMenu::DefaultCallback(
|
||||||
|
_show,
|
||||||
|
sendCallback())(
|
||||||
|
action,
|
||||||
|
details);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SendFilesBox::initPreview() {
|
void SendFilesBox::initPreview() {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
|
@ -533,7 +576,7 @@ void SendFilesBox::refreshButtons() {
|
||||||
_send,
|
_send,
|
||||||
_show,
|
_show,
|
||||||
_sendMenuDetails,
|
_sendMenuDetails,
|
||||||
SendMenu::DefaultCallback(_show, sendCallback()));
|
_sendMenuCallback);
|
||||||
}
|
}
|
||||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||||
_addFile = addLeftButton(
|
_addFile = addLeftButton(
|
||||||
|
@ -545,8 +588,10 @@ void SendFilesBox::refreshButtons() {
|
||||||
addMenuButton();
|
addMenuButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendFilesBox::hasSendMenu() const {
|
bool SendFilesBox::hasSendMenu(const SendMenu::Details &details) const {
|
||||||
return (_sendMenuDetails().type != SendMenu::Type::Disabled);
|
return (details.type != SendMenu::Type::Disabled)
|
||||||
|
|| (details.spoiler != SendMenu::SpoilerState::None)
|
||||||
|
|| (details.caption != SendMenu::CaptionState::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendFilesBox::hasSpoilerMenu() const {
|
bool SendFilesBox::hasSpoilerMenu() const {
|
||||||
|
@ -583,7 +628,8 @@ void SendFilesBox::toggleSpoilers(bool enabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::addMenuButton() {
|
void SendFilesBox::addMenuButton() {
|
||||||
if (!hasSendMenu() && !hasSpoilerMenu()) {
|
const auto details = _sendMenuDetails();
|
||||||
|
if (!hasSendMenu(details)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,31 +638,16 @@ void SendFilesBox::addMenuButton() {
|
||||||
const auto &tabbed = _st.tabbed;
|
const auto &tabbed = _st.tabbed;
|
||||||
const auto &icons = tabbed.icons;
|
const auto &icons = tabbed.icons;
|
||||||
_menu = base::make_unique_q<Ui::PopupMenu>(top, tabbed.menu);
|
_menu = base::make_unique_q<Ui::PopupMenu>(top, tabbed.menu);
|
||||||
if (hasSpoilerMenu()) {
|
SendMenu::FillSendMenu(
|
||||||
const auto spoilered = allWithSpoilers();
|
_menu.get(),
|
||||||
_menu->addAction(
|
_show,
|
||||||
(spoilered
|
_sendMenuDetails(),
|
||||||
? tr::lng_context_disable_spoiler(tr::now)
|
_sendMenuCallback,
|
||||||
: tr::lng_context_spoiler_effect(tr::now)),
|
&_st.tabbed.icons,
|
||||||
[=] { toggleSpoilers(!spoilered); },
|
QCursor::pos());
|
||||||
spoilered ? &icons.menuSpoilerOff : &icons.menuSpoiler);
|
|
||||||
if (hasSendMenu()) {
|
|
||||||
_menu->addSeparator(&tabbed.expandedSeparator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasSendMenu()) {
|
|
||||||
SendMenu::FillSendMenu(
|
|
||||||
_menu.get(),
|
|
||||||
_show,
|
|
||||||
_sendMenuDetails(),
|
|
||||||
SendMenu::DefaultCallback(_show, sendCallback()),
|
|
||||||
&_st.tabbed.icons,
|
|
||||||
QCursor::pos());
|
|
||||||
}
|
|
||||||
_menu->popup(QCursor::pos());
|
_menu->popup(QCursor::pos());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::initSendWay() {
|
void SendFilesBox::initSendWay() {
|
||||||
|
@ -658,9 +689,7 @@ void SendFilesBox::initSendWay() {
|
||||||
for (auto &block : _blocks) {
|
for (auto &block : _blocks) {
|
||||||
block.setSendWay(value);
|
block.setSendWay(value);
|
||||||
}
|
}
|
||||||
if (!hasSendMenu()) {
|
refreshButtons();
|
||||||
refreshButtons();
|
|
||||||
}
|
|
||||||
if (was != hidden()) {
|
if (was != hidden()) {
|
||||||
updateBoxSize();
|
updateBoxSize();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
@ -872,9 +901,7 @@ void SendFilesBox::pushBlock(int from, int till) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::refreshControls(bool initial) {
|
void SendFilesBox::refreshControls(bool initial) {
|
||||||
if (initial || !hasSendMenu()) {
|
refreshButtons();
|
||||||
refreshButtons();
|
|
||||||
}
|
|
||||||
refreshTitleText();
|
refreshTitleText();
|
||||||
updateSendWayControls();
|
updateSendWayControls();
|
||||||
updateCaptionPlaceholder();
|
updateCaptionPlaceholder();
|
||||||
|
@ -1426,9 +1453,12 @@ void SendFilesBox::send(
|
||||||
if ((_sendType == Api::SendType::Scheduled
|
if ((_sendType == Api::SendType::Scheduled
|
||||||
|| _sendType == Api::SendType::ScheduledToUser)
|
|| _sendType == Api::SendType::ScheduledToUser)
|
||||||
&& !options.scheduled) {
|
&& !options.scheduled) {
|
||||||
|
auto child = _sendMenuDetails();
|
||||||
|
child.spoiler = SendMenu::SpoilerState::None;
|
||||||
|
child.caption = SendMenu::CaptionState::None;
|
||||||
return SendMenu::DefaultCallback(_show, sendCallback())(
|
return SendMenu::DefaultCallback(_show, sendCallback())(
|
||||||
{ .type = SendMenu::ActionType::Schedule },
|
{ .type = SendMenu::ActionType::Schedule },
|
||||||
_sendMenuDetails());
|
child);
|
||||||
}
|
}
|
||||||
if (_preparing) {
|
if (_preparing) {
|
||||||
_whenReadySend = [=] {
|
_whenReadySend = [=] {
|
||||||
|
@ -1453,6 +1483,7 @@ void SendFilesBox::send(
|
||||||
auto caption = (_caption && !_caption->isHidden())
|
auto caption = (_caption && !_caption->isHidden())
|
||||||
? _caption->getTextWithAppliedMarkdown()
|
? _caption->getTextWithAppliedMarkdown()
|
||||||
: TextWithTags();
|
: TextWithTags();
|
||||||
|
options.invertCaption = _invertCaption;
|
||||||
if (!validateLength(caption.text)) {
|
if (!validateLength(caption.text)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ class SessionController;
|
||||||
|
|
||||||
namespace SendMenu {
|
namespace SendMenu {
|
||||||
struct Details;
|
struct Details;
|
||||||
|
struct Action;
|
||||||
} // namespace SendMenu
|
} // namespace SendMenu
|
||||||
|
|
||||||
namespace HistoryView::Controls {
|
namespace HistoryView::Controls {
|
||||||
|
@ -136,6 +137,9 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using MenuAction = SendMenu::Action;
|
||||||
|
using MenuDetails = SendMenu::Details;
|
||||||
|
|
||||||
class Block final {
|
class Block final {
|
||||||
public:
|
public:
|
||||||
Block(
|
Block(
|
||||||
|
@ -173,7 +177,7 @@ private:
|
||||||
|
|
||||||
void initSendWay();
|
void initSendWay();
|
||||||
void initPreview();
|
void initPreview();
|
||||||
[[nodiscard]] bool hasSendMenu() const;
|
[[nodiscard]] bool hasSendMenu(const MenuDetails &details) const;
|
||||||
[[nodiscard]] bool hasSpoilerMenu() const;
|
[[nodiscard]] bool hasSpoilerMenu() const;
|
||||||
[[nodiscard]] bool allWithSpoilers();
|
[[nodiscard]] bool allWithSpoilers();
|
||||||
[[nodiscard]] bool checkWithWay(
|
[[nodiscard]] bool checkWithWay(
|
||||||
|
@ -225,6 +229,11 @@ private:
|
||||||
|
|
||||||
void checkCharsLimitation();
|
void checkCharsLimitation();
|
||||||
|
|
||||||
|
[[nodiscard]] Fn<MenuDetails()> prepareSendMenuDetails(
|
||||||
|
const SendFilesBoxDescriptor &descriptor);
|
||||||
|
[[nodiscard]] auto prepareSendMenuCallback()
|
||||||
|
-> Fn<void(MenuAction, MenuDetails)>;
|
||||||
|
|
||||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||||
const style::ComposeControls &_st;
|
const style::ComposeControls &_st;
|
||||||
const Api::SendType _sendType = Api::SendType();
|
const Api::SendType _sendType = Api::SendType();
|
||||||
|
@ -236,12 +245,14 @@ private:
|
||||||
std::optional<int> _removingIndex;
|
std::optional<int> _removingIndex;
|
||||||
|
|
||||||
SendFilesLimits _limits = {};
|
SendFilesLimits _limits = {};
|
||||||
Fn<SendMenu::Details()> _sendMenuDetails = nullptr;
|
Fn<MenuDetails()> _sendMenuDetails;
|
||||||
|
Fn<void(MenuAction, MenuDetails)> _sendMenuCallback;
|
||||||
PeerData *_captionToPeer = nullptr;
|
PeerData *_captionToPeer = nullptr;
|
||||||
SendFilesCheck _check;
|
SendFilesCheck _check;
|
||||||
SendFilesConfirmed _confirmedCallback;
|
SendFilesConfirmed _confirmedCallback;
|
||||||
Fn<void()> _cancelledCallback;
|
Fn<void()> _cancelledCallback;
|
||||||
bool _confirmed = false;
|
bool _confirmed = false;
|
||||||
|
bool _invertCaption = false;
|
||||||
|
|
||||||
object_ptr<Ui::InputField> _caption = { nullptr };
|
object_ptr<Ui::InputField> _caption = { nullptr };
|
||||||
TextWithTags _prefilledCaptionText;
|
TextWithTags _prefilledCaptionText;
|
||||||
|
|
|
@ -69,6 +69,8 @@ ComposeIcons {
|
||||||
menuWhenOnline: icon;
|
menuWhenOnline: icon;
|
||||||
menuSpoiler: icon;
|
menuSpoiler: icon;
|
||||||
menuSpoilerOff: icon;
|
menuSpoilerOff: icon;
|
||||||
|
menuBelow: icon;
|
||||||
|
menuAbove: icon;
|
||||||
|
|
||||||
stripBubble: icon;
|
stripBubble: icon;
|
||||||
stripExpandPanel: icon;
|
stripExpandPanel: icon;
|
||||||
|
@ -606,6 +608,8 @@ defaultComposeIcons: ComposeIcons {
|
||||||
menuWhenOnline: menuIconWhenOnline;
|
menuWhenOnline: menuIconWhenOnline;
|
||||||
menuSpoiler: menuIconSpoiler;
|
menuSpoiler: menuIconSpoiler;
|
||||||
menuSpoilerOff: menuIconSpoilerOff;
|
menuSpoilerOff: menuIconSpoilerOff;
|
||||||
|
menuBelow: menuIconBelow;
|
||||||
|
menuAbove: menuIconAbove;
|
||||||
|
|
||||||
stripBubble: icon{
|
stripBubble: icon{
|
||||||
{ "chat/reactions_bubble_shadow", windowShadowFg },
|
{ "chat/reactions_bubble_shadow", windowShadowFg },
|
||||||
|
|
|
@ -1104,6 +1104,7 @@ void Reactions::defaultUpdated() {
|
||||||
}
|
}
|
||||||
refreshMyTags();
|
refreshMyTags();
|
||||||
refreshTags();
|
refreshTags();
|
||||||
|
refreshEffects();
|
||||||
_defaultUpdated.fire({});
|
_defaultUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,9 @@ namespace Media::Stories {
|
||||||
if (options.effectId) {
|
if (options.effectId) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||||
}
|
}
|
||||||
|
if (options.invertCaption) {
|
||||||
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
|
}
|
||||||
const auto done = [=] {
|
const auto done = [=] {
|
||||||
if (!--state->requests) {
|
if (!--state->requests) {
|
||||||
if (show->valid()) {
|
if (show->valid()) {
|
||||||
|
|
|
@ -636,6 +636,8 @@ storiesEmojiPan: EmojiPan(defaultEmojiPan) {
|
||||||
menuWhenOnline: icon {{ "menu/send_when_online", storiesComposeWhiteText }};
|
menuWhenOnline: icon {{ "menu/send_when_online", storiesComposeWhiteText }};
|
||||||
menuSpoiler: icon {{ "menu/spoiler_on", storiesComposeWhiteText }};
|
menuSpoiler: icon {{ "menu/spoiler_on", storiesComposeWhiteText }};
|
||||||
menuSpoilerOff: icon {{ "menu/spoiler_off", storiesComposeWhiteText }};
|
menuSpoilerOff: icon {{ "menu/spoiler_off", storiesComposeWhiteText }};
|
||||||
|
menuBelow: icon {{ "menu/link_below", storiesComposeWhiteText }};
|
||||||
|
menuAbove: icon {{ "menu/link_above", storiesComposeWhiteText }};
|
||||||
|
|
||||||
stripBubble: icon{
|
stripBubble: icon{
|
||||||
{ "chat/reactions_bubble_shadow", windowShadowFg },
|
{ "chat/reactions_bubble_shadow", windowShadowFg },
|
||||||
|
|
|
@ -615,13 +615,47 @@ FillMenuResult FillSendMenu(
|
||||||
const style::ComposeIcons *iconsOverride,
|
const style::ComposeIcons *iconsOverride,
|
||||||
std::optional<QPoint> desiredPositionOverride) {
|
std::optional<QPoint> desiredPositionOverride) {
|
||||||
const auto type = details.type;
|
const auto type = details.type;
|
||||||
if (type == Type::Disabled || !action) {
|
const auto empty = (type == Type::Disabled)
|
||||||
|
&& (details.spoiler == SpoilerState::None)
|
||||||
|
&& (details.caption == CaptionState::None);
|
||||||
|
if (empty || !action) {
|
||||||
return FillMenuResult::Skipped;
|
return FillMenuResult::Skipped;
|
||||||
}
|
}
|
||||||
const auto &icons = iconsOverride
|
const auto &icons = iconsOverride
|
||||||
? *iconsOverride
|
? *iconsOverride
|
||||||
: st::defaultComposeIcons;
|
: st::defaultComposeIcons;
|
||||||
|
|
||||||
|
auto toggles = false;
|
||||||
|
if (details.spoiler != SpoilerState::None) {
|
||||||
|
const auto spoilered = (details.spoiler == SpoilerState::Enabled);
|
||||||
|
menu->addAction(
|
||||||
|
(spoilered
|
||||||
|
? tr::lng_context_disable_spoiler(tr::now)
|
||||||
|
: tr::lng_context_spoiler_effect(tr::now)),
|
||||||
|
[=] { action({ .type = spoilered
|
||||||
|
? ActionType::SpoilerOff
|
||||||
|
: ActionType::SpoilerOn
|
||||||
|
}, details); },
|
||||||
|
spoilered ? &icons.menuSpoilerOff : &icons.menuSpoiler);
|
||||||
|
toggles = true;
|
||||||
|
}
|
||||||
|
if (details.caption != CaptionState::None) {
|
||||||
|
const auto above = (details.caption == CaptionState::Above);
|
||||||
|
menu->addAction(
|
||||||
|
(above
|
||||||
|
? tr::lng_caption_move_down(tr::now)
|
||||||
|
: tr::lng_caption_move_up(tr::now)),
|
||||||
|
[=] { action({ .type = above
|
||||||
|
? ActionType::CaptionDown
|
||||||
|
: ActionType::CaptionUp
|
||||||
|
}, details); },
|
||||||
|
above ? &icons.menuBelow : &icons.menuAbove);
|
||||||
|
toggles = true;
|
||||||
|
}
|
||||||
|
if (toggles && type != Type::Disabled) {
|
||||||
|
menu->addSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
if (type != Type::Reminder) {
|
if (type != Type::Reminder) {
|
||||||
menu->addAction(
|
menu->addAction(
|
||||||
tr::lng_send_silent_message(tr::now),
|
tr::lng_send_silent_message(tr::now),
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Thread;
|
||||||
|
|
||||||
namespace SendMenu {
|
namespace SendMenu {
|
||||||
|
|
||||||
enum class Type {
|
enum class Type : uchar {
|
||||||
Disabled,
|
Disabled,
|
||||||
SilentOnly,
|
SilentOnly,
|
||||||
Scheduled,
|
Scheduled,
|
||||||
|
@ -37,20 +37,38 @@ enum class Type {
|
||||||
Reminder,
|
Reminder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SpoilerState : uchar {
|
||||||
|
None,
|
||||||
|
Enabled,
|
||||||
|
Possible,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CaptionState : uchar {
|
||||||
|
None,
|
||||||
|
Below,
|
||||||
|
Above,
|
||||||
|
};
|
||||||
|
|
||||||
struct Details {
|
struct Details {
|
||||||
Type type = Type::Disabled;
|
Type type = Type::Disabled;
|
||||||
|
SpoilerState spoiler = SpoilerState::None;
|
||||||
|
CaptionState caption = CaptionState::None;
|
||||||
bool effectAllowed = false;
|
bool effectAllowed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FillMenuResult {
|
enum class FillMenuResult : uchar {
|
||||||
Prepared,
|
Prepared,
|
||||||
Skipped,
|
Skipped,
|
||||||
Failed,
|
Failed,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ActionType {
|
enum class ActionType : uchar {
|
||||||
Send,
|
Send,
|
||||||
Schedule,
|
Schedule,
|
||||||
|
SpoilerOn,
|
||||||
|
SpoilerOff,
|
||||||
|
CaptionUp,
|
||||||
|
CaptionDown,
|
||||||
};
|
};
|
||||||
struct Action {
|
struct Action {
|
||||||
using Type = ActionType;
|
using Type = ActionType;
|
||||||
|
|
|
@ -184,6 +184,17 @@ bool PreparedList::canAddCaption(bool sendingAlbum, bool compress) const {
|
||||||
return !hasFiles && !hasMusic && !hasNotGrouped;
|
return !hasFiles && !hasMusic && !hasNotGrouped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PreparedList::canMoveCaption(bool sendingAlbum, bool compress) const {
|
||||||
|
if (!canAddCaption(sendingAlbum, compress)) {
|
||||||
|
return false;
|
||||||
|
} else if (files.size() != 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto &file = files.front();
|
||||||
|
return (file.type == PreparedFile::Type::Video)
|
||||||
|
|| (file.type == PreparedFile::Type::Photo && compress);
|
||||||
|
}
|
||||||
|
|
||||||
bool PreparedList::hasGroupOption(bool slowmode) const {
|
bool PreparedList::hasGroupOption(bool slowmode) const {
|
||||||
if (slowmode || files.size() < 2) {
|
if (slowmode || files.size() < 2) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -112,6 +112,9 @@ struct PreparedList {
|
||||||
void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false);
|
void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false);
|
||||||
|
|
||||||
[[nodiscard]] bool canAddCaption(bool sendingAlbum, bool compress) const;
|
[[nodiscard]] bool canAddCaption(bool sendingAlbum, bool compress) const;
|
||||||
|
[[nodiscard]] bool canMoveCaption(
|
||||||
|
bool sendingAlbum,
|
||||||
|
bool compress) const;
|
||||||
[[nodiscard]] bool canBeSentInSlowmode() const;
|
[[nodiscard]] bool canBeSentInSlowmode() const;
|
||||||
[[nodiscard]] bool canBeSentInSlowmodeWith(
|
[[nodiscard]] bool canBeSentInSlowmodeWith(
|
||||||
const PreparedList &other) const;
|
const PreparedList &other) const;
|
||||||
|
|
Loading…
Add table
Reference in a new issue