mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-09-06 20:13:12 +02:00
Start suggesting changes to messages by editing.
This commit is contained in:
parent
498116c3f6
commit
dc19f2e76c
10 changed files with 496 additions and 138 deletions
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_media.h"
|
#include "api/api_media.h"
|
||||||
#include "api/api_text_entities.h"
|
#include "api/api_text_entities.h"
|
||||||
|
#include "base/random.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "data/business/data_shortcut_messages.h"
|
#include "data/business/data_shortcut_messages.h"
|
||||||
#include "data/components/scheduled_messages.h"
|
#include "data/components/scheduled_messages.h"
|
||||||
|
@ -20,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_web_page.h"
|
#include "data/data_web_page.h"
|
||||||
#include "history/view/controls/history_view_compose_media_edit_manager.h"
|
#include "history/view/controls/history_view_compose_media_edit_manager.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "history/history_item_components.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "mtproto/mtproto_response.h"
|
#include "mtproto/mtproto_response.h"
|
||||||
|
@ -46,6 +48,230 @@ template <typename T>
|
||||||
constexpr auto ErrorWithoutId
|
constexpr auto ErrorWithoutId
|
||||||
= is_callable_plain_v<T, QString>;
|
= is_callable_plain_v<T, QString>;
|
||||||
|
|
||||||
|
template <typename DoneCallback, typename FailCallback>
|
||||||
|
mtpRequestId SuggestMessage(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const TextWithEntities &textWithEntities,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
|
SendOptions options,
|
||||||
|
DoneCallback &&done,
|
||||||
|
FailCallback &&fail) {
|
||||||
|
Expects(options.suggest.exists);
|
||||||
|
Expects(!options.scheduled);
|
||||||
|
|
||||||
|
const auto session = &item->history()->session();
|
||||||
|
const auto api = &session->api();
|
||||||
|
|
||||||
|
const auto text = textWithEntities.text;
|
||||||
|
const auto sentEntities = EntitiesToMTP(
|
||||||
|
session,
|
||||||
|
textWithEntities.entities,
|
||||||
|
ConvertOption::SkipLocal);
|
||||||
|
|
||||||
|
const auto emptyFlag = MTPmessages_SendMessage::Flag(0);
|
||||||
|
auto replyTo = FullReplyTo{
|
||||||
|
.messageId = item->fullId(),
|
||||||
|
.monoforumPeerId = (item->history()->amMonoforumAdmin()
|
||||||
|
? item->sublistPeerId()
|
||||||
|
: PeerId()),
|
||||||
|
};
|
||||||
|
const auto flags = emptyFlag
|
||||||
|
| MTPmessages_SendMessage::Flag::f_reply_to
|
||||||
|
| MTPmessages_SendMessage::Flag::f_suggested_post
|
||||||
|
| (webpage.removed
|
||||||
|
? MTPmessages_SendMessage::Flag::f_no_webpage
|
||||||
|
: emptyFlag)
|
||||||
|
| (((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||||
|
|| options.invertCaption)
|
||||||
|
? MTPmessages_SendMessage::Flag::f_invert_media
|
||||||
|
: emptyFlag)
|
||||||
|
| (!sentEntities.v.isEmpty()
|
||||||
|
? MTPmessages_SendMessage::Flag::f_entities
|
||||||
|
: emptyFlag)
|
||||||
|
| (options.starsApproved
|
||||||
|
? MTPmessages_SendMessage::Flag::f_allow_paid_stars
|
||||||
|
: emptyFlag);
|
||||||
|
const auto randomId = base::RandomValue<uint64>();
|
||||||
|
return api->request(MTPmessages_SendMessage(
|
||||||
|
MTP_flags(flags),
|
||||||
|
item->history()->peer->input,
|
||||||
|
ReplyToForMTP(item->history(), replyTo),
|
||||||
|
MTP_string(text),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
sentEntities,
|
||||||
|
MTPint(), // schedule_date
|
||||||
|
MTPInputPeer(), // send_as
|
||||||
|
MTPInputQuickReplyShortcut(), // quick_reply_shortcut
|
||||||
|
MTPlong(), // effect
|
||||||
|
MTP_long(options.starsApproved),
|
||||||
|
Api::SuggestToMTP(options.suggest)
|
||||||
|
)).done([=](
|
||||||
|
const MTPUpdates &result,
|
||||||
|
[[maybe_unused]] mtpRequestId requestId) {
|
||||||
|
const auto apply = [=] { api->applyUpdates(result); };
|
||||||
|
|
||||||
|
if constexpr (WithId<DoneCallback>) {
|
||||||
|
done(apply, requestId);
|
||||||
|
} else if constexpr (WithoutId<DoneCallback>) {
|
||||||
|
done(apply);
|
||||||
|
} else if constexpr (WithoutCallback<DoneCallback>) {
|
||||||
|
done();
|
||||||
|
apply();
|
||||||
|
} else {
|
||||||
|
t_bad_callback(done);
|
||||||
|
}
|
||||||
|
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||||
|
if constexpr (ErrorWithId<FailCallback>) {
|
||||||
|
fail(error.type(), requestId);
|
||||||
|
} else if constexpr (ErrorWithoutId<FailCallback>) {
|
||||||
|
fail(error.type());
|
||||||
|
} else if constexpr (WithoutCallback<FailCallback>) {
|
||||||
|
fail();
|
||||||
|
} else {
|
||||||
|
t_bad_callback(fail);
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DoneCallback, typename FailCallback>
|
||||||
|
mtpRequestId SuggestMedia(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const TextWithEntities &textWithEntities,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
|
SendOptions options,
|
||||||
|
DoneCallback &&done,
|
||||||
|
FailCallback &&fail,
|
||||||
|
std::optional<MTPInputMedia> inputMedia) {
|
||||||
|
Expects(options.suggest.exists);
|
||||||
|
Expects(!options.scheduled);
|
||||||
|
|
||||||
|
const auto session = &item->history()->session();
|
||||||
|
const auto api = &session->api();
|
||||||
|
|
||||||
|
const auto text = textWithEntities.text;
|
||||||
|
const auto sentEntities = EntitiesToMTP(
|
||||||
|
session,
|
||||||
|
textWithEntities.entities,
|
||||||
|
ConvertOption::SkipLocal);
|
||||||
|
|
||||||
|
const auto updateRecentStickers = inputMedia
|
||||||
|
? Api::HasAttachedStickers(*inputMedia)
|
||||||
|
: false;
|
||||||
|
|
||||||
|
const auto emptyFlag = MTPmessages_SendMedia::Flag(0);
|
||||||
|
auto replyTo = FullReplyTo{
|
||||||
|
.messageId = item->fullId(),
|
||||||
|
.monoforumPeerId = (item->history()->amMonoforumAdmin()
|
||||||
|
? item->sublistPeerId()
|
||||||
|
: PeerId()),
|
||||||
|
};
|
||||||
|
const auto flags = emptyFlag
|
||||||
|
| MTPmessages_SendMedia::Flag::f_reply_to
|
||||||
|
| MTPmessages_SendMedia::Flag::f_suggested_post
|
||||||
|
| (((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||||
|
|| options.invertCaption)
|
||||||
|
? MTPmessages_SendMedia::Flag::f_invert_media
|
||||||
|
: emptyFlag)
|
||||||
|
| (!sentEntities.v.isEmpty()
|
||||||
|
? MTPmessages_SendMedia::Flag::f_entities
|
||||||
|
: emptyFlag)
|
||||||
|
| (options.starsApproved
|
||||||
|
? MTPmessages_SendMedia::Flag::f_allow_paid_stars
|
||||||
|
: emptyFlag);
|
||||||
|
const auto randomId = base::RandomValue<uint64>();
|
||||||
|
return api->request(MTPmessages_SendMedia(
|
||||||
|
MTP_flags(flags),
|
||||||
|
item->history()->peer->input,
|
||||||
|
ReplyToForMTP(item->history(), replyTo),
|
||||||
|
inputMedia.value_or(Data::WebPageForMTP(webpage, text.isEmpty())),
|
||||||
|
MTP_string(text),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
sentEntities,
|
||||||
|
MTPint(), // schedule_date
|
||||||
|
MTPInputPeer(), // send_as
|
||||||
|
MTPInputQuickReplyShortcut(), // quick_reply_shortcut
|
||||||
|
MTPlong(), // effect
|
||||||
|
MTP_long(options.starsApproved),
|
||||||
|
Api::SuggestToMTP(options.suggest)
|
||||||
|
)).done([=](
|
||||||
|
const MTPUpdates &result,
|
||||||
|
[[maybe_unused]] mtpRequestId requestId) {
|
||||||
|
const auto apply = [=] { api->applyUpdates(result); };
|
||||||
|
|
||||||
|
if constexpr (WithId<DoneCallback>) {
|
||||||
|
done(apply, requestId);
|
||||||
|
} else if constexpr (WithoutId<DoneCallback>) {
|
||||||
|
done(apply);
|
||||||
|
} else if constexpr (WithoutCallback<DoneCallback>) {
|
||||||
|
done();
|
||||||
|
apply();
|
||||||
|
} else {
|
||||||
|
t_bad_callback(done);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateRecentStickers) {
|
||||||
|
api->requestSpecialStickersForce(false, false, true);
|
||||||
|
}
|
||||||
|
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||||
|
if constexpr (ErrorWithId<FailCallback>) {
|
||||||
|
fail(error.type(), requestId);
|
||||||
|
} else if constexpr (ErrorWithoutId<FailCallback>) {
|
||||||
|
fail(error.type());
|
||||||
|
} else if constexpr (WithoutCallback<FailCallback>) {
|
||||||
|
fail();
|
||||||
|
} else {
|
||||||
|
t_bad_callback(fail);
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename DoneCallback, typename FailCallback>
|
||||||
|
mtpRequestId SuggestMessageOrMedia(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const TextWithEntities &textWithEntities,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
|
SendOptions options,
|
||||||
|
DoneCallback &&done,
|
||||||
|
FailCallback &&fail,
|
||||||
|
std::optional<MTPInputMedia> inputMedia) {
|
||||||
|
const auto wasMedia = item->media();
|
||||||
|
if (!inputMedia && wasMedia && wasMedia->allowsEditCaption()) {
|
||||||
|
if (const auto photo = wasMedia->photo()) {
|
||||||
|
inputMedia = MTP_inputMediaPhoto(
|
||||||
|
MTP_flags(0),
|
||||||
|
photo->mtpInput(),
|
||||||
|
MTPint()); // ttl_seconds
|
||||||
|
} else if (const auto document = wasMedia->document()) {
|
||||||
|
inputMedia = MTP_inputMediaDocument(
|
||||||
|
MTP_flags(0),
|
||||||
|
document->mtpInput(),
|
||||||
|
MTPInputPhoto(), // video_cover
|
||||||
|
MTPint(), // video_timestamp
|
||||||
|
MTPint(), // ttl_seconds
|
||||||
|
MTPstring()); // query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inputMedia || (!webpage.removed && !webpage.url.isEmpty())) {
|
||||||
|
return SuggestMedia(
|
||||||
|
item,
|
||||||
|
textWithEntities,
|
||||||
|
webpage,
|
||||||
|
options,
|
||||||
|
std::move(done),
|
||||||
|
std::move(fail),
|
||||||
|
inputMedia);
|
||||||
|
}
|
||||||
|
return SuggestMessage(
|
||||||
|
item,
|
||||||
|
textWithEntities,
|
||||||
|
webpage,
|
||||||
|
options,
|
||||||
|
std::move(done),
|
||||||
|
std::move(fail));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename DoneCallback, typename FailCallback>
|
template <typename DoneCallback, typename FailCallback>
|
||||||
mtpRequestId EditMessage(
|
mtpRequestId EditMessage(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
|
@ -55,6 +281,18 @@ mtpRequestId EditMessage(
|
||||||
DoneCallback &&done,
|
DoneCallback &&done,
|
||||||
FailCallback &&fail,
|
FailCallback &&fail,
|
||||||
std::optional<MTPInputMedia> inputMedia = std::nullopt) {
|
std::optional<MTPInputMedia> inputMedia = std::nullopt) {
|
||||||
|
if (item->computeSuggestionActions()
|
||||||
|
== SuggestionActions::AcceptAndDecline) {
|
||||||
|
return SuggestMessageOrMedia(
|
||||||
|
item,
|
||||||
|
textWithEntities,
|
||||||
|
webpage,
|
||||||
|
options,
|
||||||
|
std::move(done),
|
||||||
|
std::move(fail),
|
||||||
|
inputMedia);
|
||||||
|
}
|
||||||
|
|
||||||
const auto session = &item->history()->session();
|
const auto session = &item->history()->session();
|
||||||
const auto api = &session->api();
|
const auto api = &session->api();
|
||||||
|
|
||||||
|
@ -71,31 +309,31 @@ mtpRequestId EditMessage(
|
||||||
|
|
||||||
const auto emptyFlag = MTPmessages_EditMessage::Flag(0);
|
const auto emptyFlag = MTPmessages_EditMessage::Flag(0);
|
||||||
const auto flags = emptyFlag
|
const auto flags = emptyFlag
|
||||||
| ((!text.isEmpty() || media)
|
| ((!text.isEmpty() || media)
|
||||||
? MTPmessages_EditMessage::Flag::f_message
|
? MTPmessages_EditMessage::Flag::f_message
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| ((media && inputMedia.has_value())
|
| ((media && inputMedia.has_value())
|
||||||
? MTPmessages_EditMessage::Flag::f_media
|
? MTPmessages_EditMessage::Flag::f_media
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (webpage.removed
|
| (webpage.removed
|
||||||
? MTPmessages_EditMessage::Flag::f_no_webpage
|
? MTPmessages_EditMessage::Flag::f_no_webpage
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| ((!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)
|
|| options.invertCaption)
|
||||||
? MTPmessages_EditMessage::Flag::f_invert_media
|
? MTPmessages_EditMessage::Flag::f_invert_media
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (!sentEntities.v.isEmpty()
|
| (!sentEntities.v.isEmpty()
|
||||||
? MTPmessages_EditMessage::Flag::f_entities
|
? MTPmessages_EditMessage::Flag::f_entities
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (options.scheduled
|
| (options.scheduled
|
||||||
? MTPmessages_EditMessage::Flag::f_schedule_date
|
? MTPmessages_EditMessage::Flag::f_schedule_date
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (item->isBusinessShortcut()
|
| (item->isBusinessShortcut()
|
||||||
? MTPmessages_EditMessage::Flag::f_quick_reply_shortcut_id
|
? MTPmessages_EditMessage::Flag::f_quick_reply_shortcut_id
|
||||||
: emptyFlag);
|
: emptyFlag);
|
||||||
|
|
||||||
const auto id = item->isScheduled()
|
const auto id = item->isScheduled()
|
||||||
? session->scheduledMessages().lookupId(item)
|
? session->scheduledMessages().lookupId(item)
|
||||||
|
|
|
@ -9,8 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "chat_helpers/message_field.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "data/data_changes.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "history/view/history_view_suggest_options.h"
|
#include "history/view/history_view_suggest_options.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
|
@ -134,9 +137,8 @@ void RequestApprovalDate(
|
||||||
using namespace HistoryView;
|
using namespace HistoryView;
|
||||||
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
||||||
.session = &controller->session(),
|
.session = &controller->session(),
|
||||||
.title = tr::lng_suggest_options_date(),
|
|
||||||
.submit = tr::lng_settings_save(),
|
|
||||||
.done = done,
|
.done = done,
|
||||||
|
.mode = SuggestMode::New,
|
||||||
});
|
});
|
||||||
*weak = dateBox.data();
|
*weak = dateBox.data();
|
||||||
controller->uiShow()->show(std::move(dateBox));
|
controller->uiShow()->show(std::move(dateBox));
|
||||||
|
@ -266,10 +268,9 @@ void SuggestApprovalDate(
|
||||||
using namespace HistoryView;
|
using namespace HistoryView;
|
||||||
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
||||||
.session = &controller->session(),
|
.session = &controller->session(),
|
||||||
.title = tr::lng_suggest_menu_edit_time(),
|
|
||||||
.submit = tr::lng_profile_suggest_button(),
|
|
||||||
.done = done,
|
.done = done,
|
||||||
.value = suggestion->date,
|
.value = suggestion->date,
|
||||||
|
.mode = SuggestMode::Change,
|
||||||
});
|
});
|
||||||
*weak = dateBox.data();
|
*weak = dateBox.data();
|
||||||
controller->uiShow()->show(std::move(dateBox));
|
controller->uiShow()->show(std::move(dateBox));
|
||||||
|
@ -311,6 +312,7 @@ void SuggestApprovalPrice(
|
||||||
.stars = uint32(suggestion->stars),
|
.stars = uint32(suggestion->stars),
|
||||||
.date = suggestion->date,
|
.date = suggestion->date,
|
||||||
},
|
},
|
||||||
|
.mode = SuggestMode::Change,
|
||||||
});
|
});
|
||||||
*weak = dateBox.data();
|
*weak = dateBox.data();
|
||||||
controller->uiShow()->show(std::move(dateBox));
|
controller->uiShow()->show(std::move(dateBox));
|
||||||
|
@ -373,9 +375,47 @@ std::shared_ptr<ClickHandler> SuggestChangesClickHandler(
|
||||||
const auto menu = Ui::CreateChild<Ui::PopupMenu>(
|
const auto menu = Ui::CreateChild<Ui::PopupMenu>(
|
||||||
window->widget(),
|
window->widget(),
|
||||||
st::popupMenuWithIcons);
|
st::popupMenuWithIcons);
|
||||||
menu->addAction(tr::lng_suggest_menu_edit_message(tr::now), [=] {
|
if (HistoryView::CanEditSuggestedMessage(item)) {
|
||||||
|
menu->addAction(tr::lng_suggest_menu_edit_message(tr::now), [=] {
|
||||||
}, &st::menuIconEdit);
|
const auto item = session->data().message(id);
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||||
|
if (!suggestion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto history = item->history();
|
||||||
|
const auto editData = PrepareEditText(item);
|
||||||
|
const auto cursor = MessageCursor{
|
||||||
|
int(editData.text.size()),
|
||||||
|
int(editData.text.size()),
|
||||||
|
Ui::kQFixedMax
|
||||||
|
};
|
||||||
|
const auto monoforumPeerId = history->amMonoforumAdmin()
|
||||||
|
? item->sublistPeerId()
|
||||||
|
: PeerId();
|
||||||
|
const auto previewDraft = Data::WebPageDraft::FromItem(item);
|
||||||
|
history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
||||||
|
editData,
|
||||||
|
FullReplyTo{
|
||||||
|
.messageId = FullMsgId(history->peer->id, item->id),
|
||||||
|
.monoforumPeerId = monoforumPeerId,
|
||||||
|
},
|
||||||
|
SuggestPostOptions{
|
||||||
|
.exists = 1,
|
||||||
|
.stars = uint32(suggestion->stars),
|
||||||
|
.date = suggestion->date,
|
||||||
|
},
|
||||||
|
cursor,
|
||||||
|
previewDraft));
|
||||||
|
history->session().changes().entryUpdated(
|
||||||
|
(monoforumPeerId
|
||||||
|
? item->savedSublist()
|
||||||
|
: (Data::Thread*)history.get()),
|
||||||
|
Data::EntryUpdate::Flag::LocalDraftSet);
|
||||||
|
}, &st::menuIconEdit);
|
||||||
|
}
|
||||||
menu->addAction(tr::lng_suggest_menu_edit_price(tr::now), [=] {
|
menu->addAction(tr::lng_suggest_menu_edit_price(tr::now), [=] {
|
||||||
if (const auto item = session->data().message(id)) {
|
if (const auto item = session->data().message(id)) {
|
||||||
SuggestApprovalPrice(window, item);
|
SuggestApprovalPrice(window, item);
|
||||||
|
|
|
@ -2410,6 +2410,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
highlightId);
|
highlightId);
|
||||||
}, &st::menuIconViewReplies);
|
}, &st::menuIconViewReplies);
|
||||||
}
|
}
|
||||||
|
_menu->addAction(u"Add Offer"_q, [=] {
|
||||||
|
|
||||||
|
}, &st::menuIconDiscussion);
|
||||||
const auto t = base::unixtime::now();
|
const auto t = base::unixtime::now();
|
||||||
const auto editItem = (albumPartItem && albumPartItem->allowsEdit(t))
|
const auto editItem = (albumPartItem && albumPartItem->allowsEdit(t))
|
||||||
? albumPartItem
|
? albumPartItem
|
||||||
|
|
|
@ -544,6 +544,13 @@ public:
|
||||||
[[nodiscard]] bool canUpdateDate() const;
|
[[nodiscard]] bool canUpdateDate() const;
|
||||||
void customEmojiRepaint();
|
void customEmojiRepaint();
|
||||||
|
|
||||||
|
[[nodiscard]] SuggestionActions computeSuggestionActions() const;
|
||||||
|
[[nodiscard]] SuggestionActions computeSuggestionActions(
|
||||||
|
const HistoryMessageSuggestedPost *suggest) const;
|
||||||
|
[[nodiscard]] SuggestionActions computeSuggestionActions(
|
||||||
|
bool accepted,
|
||||||
|
bool rejected) const;
|
||||||
|
|
||||||
[[nodiscard]] bool needsUpdateForVideoQualities(const MTPMessage &data);
|
[[nodiscard]] bool needsUpdateForVideoQualities(const MTPMessage &data);
|
||||||
|
|
||||||
[[nodiscard]] TimeId ttlDestroyAt() const {
|
[[nodiscard]] TimeId ttlDestroyAt() const {
|
||||||
|
@ -582,12 +589,6 @@ private:
|
||||||
void setReplyMarkup(
|
void setReplyMarkup(
|
||||||
HistoryMessageMarkupData &&markup,
|
HistoryMessageMarkupData &&markup,
|
||||||
bool ignoreSuggestButtons = false);
|
bool ignoreSuggestButtons = false);
|
||||||
[[nodiscard]] SuggestionActions computeSuggestionActions() const;
|
|
||||||
[[nodiscard]] SuggestionActions computeSuggestionActions(
|
|
||||||
const HistoryMessageSuggestedPost *suggest) const;
|
|
||||||
[[nodiscard]] SuggestionActions computeSuggestionActions(
|
|
||||||
bool accepted,
|
|
||||||
bool rejected) const;
|
|
||||||
void updateSuggestControls(const HistoryMessageSuggestedPost *suggest);
|
void updateSuggestControls(const HistoryMessageSuggestedPost *suggest);
|
||||||
|
|
||||||
void changeReplyToTopCounter(
|
void changeReplyToTopCounter(
|
||||||
|
|
|
@ -2269,6 +2269,12 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
if (!_replyEditMsg) {
|
if (!_replyEditMsg) {
|
||||||
requestMessageData(_editMsgId);
|
requestMessageData(_editMsgId);
|
||||||
}
|
}
|
||||||
|
if (editDraft && editDraft->suggest) {
|
||||||
|
using namespace HistoryView;
|
||||||
|
applySuggestOptions(editDraft->suggest, SuggestMode::Change);
|
||||||
|
} else {
|
||||||
|
cancelSuggestPost();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto draft = _history->localDraft(MsgId(), PeerId());
|
const auto draft = _history->localDraft(MsgId(), PeerId());
|
||||||
_processingReplyTo = draft ? draft->reply : FullReplyTo();
|
_processingReplyTo = draft ? draft->reply : FullReplyTo();
|
||||||
|
@ -2276,7 +2282,8 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
_processingReplyItem = session().data().message(
|
_processingReplyItem = session().data().message(
|
||||||
_processingReplyTo.messageId);
|
_processingReplyTo.messageId);
|
||||||
} else if (draft && draft->suggest) {
|
} else if (draft && draft->suggest) {
|
||||||
applySuggestOptions(draft->suggest);
|
using namespace HistoryView;
|
||||||
|
applySuggestOptions(draft->suggest, SuggestMode::New);
|
||||||
}
|
}
|
||||||
processReply();
|
processReply();
|
||||||
}
|
}
|
||||||
|
@ -2352,7 +2359,9 @@ void HistoryWidget::showHistory(
|
||||||
if (_peer->id == peerId) {
|
if (_peer->id == peerId) {
|
||||||
updateForwarding();
|
updateForwarding();
|
||||||
|
|
||||||
if (showAtMsgId == ShowAtUnreadMsgId
|
if (params.reapplyLocalDraft) {
|
||||||
|
return;
|
||||||
|
} else if (showAtMsgId == ShowAtUnreadMsgId
|
||||||
&& insideJumpToEndInsteadOfToUnread()) {
|
&& insideJumpToEndInsteadOfToUnread()) {
|
||||||
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
||||||
"Jumping to end instead of unread."
|
"Jumping to end instead of unread."
|
||||||
|
@ -3164,14 +3173,17 @@ void HistoryWidget::refreshSendGiftToggle() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::applySuggestOptions(SuggestPostOptions suggest) {
|
void HistoryWidget::applySuggestOptions(
|
||||||
|
SuggestPostOptions suggest,
|
||||||
|
HistoryView::SuggestMode mode) {
|
||||||
Expects(suggest.exists);
|
Expects(suggest.exists);
|
||||||
|
|
||||||
using namespace HistoryView;
|
using namespace HistoryView;
|
||||||
_suggestOptions = std::make_unique<SuggestOptions>(
|
_suggestOptions = std::make_unique<SuggestOptions>(
|
||||||
controller(),
|
controller(),
|
||||||
_peer,
|
_peer,
|
||||||
suggest);
|
suggest,
|
||||||
|
mode);
|
||||||
_suggestOptions->updates() | rpl::start_with_next([=] {
|
_suggestOptions->updates() | rpl::start_with_next([=] {
|
||||||
updateField();
|
updateField();
|
||||||
saveDraftWithTextNow();
|
saveDraftWithTextNow();
|
||||||
|
@ -3193,7 +3205,8 @@ void HistoryWidget::refreshSuggestPostToggle() {
|
||||||
_toggleSuggestPost.create(this, st::historySuggestPostToggle);
|
_toggleSuggestPost.create(this, st::historySuggestPostToggle);
|
||||||
_toggleSuggestPost->setVisible(!_suggestOptions);
|
_toggleSuggestPost->setVisible(!_suggestOptions);
|
||||||
_toggleSuggestPost->addClickHandler([=] {
|
_toggleSuggestPost->addClickHandler([=] {
|
||||||
applySuggestOptions({ .exists = 1 });
|
using namespace HistoryView;
|
||||||
|
applySuggestOptions({ .exists = 1 }, SuggestMode::New);
|
||||||
cancelReply();
|
cancelReply();
|
||||||
_processingReplyTo = FullReplyTo();
|
_processingReplyTo = FullReplyTo();
|
||||||
_processingReplyItem = nullptr;
|
_processingReplyItem = nullptr;
|
||||||
|
@ -4419,7 +4432,7 @@ TextWithEntities HistoryWidget::prepareTextForEditMsg() const {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::saveEditMsg() {
|
void HistoryWidget::saveEditMessage(Api::SendOptions options) {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
if (_saveEditMsgRequestId) {
|
if (_saveEditMsgRequestId) {
|
||||||
|
@ -4442,9 +4455,11 @@ void HistoryWidget::saveEditMsg() {
|
||||||
|| webPageDraft.url.isEmpty()
|
|| webPageDraft.url.isEmpty()
|
||||||
|| !webPageDraft.manual)
|
|| !webPageDraft.manual)
|
||||||
&& !hasMediaWithCaption) {
|
&& !hasMediaWithCaption) {
|
||||||
const auto suggestModerateActions = false;
|
if (item->computeSuggestionActions() == SuggestionActions::None) {
|
||||||
controller()->show(
|
const auto suggestModerateActions = false;
|
||||||
Box<DeleteMessagesBox>(item, suggestModerateActions));
|
controller()->show(
|
||||||
|
Box<DeleteMessagesBox>(item, suggestModerateActions));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const auto maxCaptionSize = !hasMediaWithCaption
|
const auto maxCaptionSize = !hasMediaWithCaption
|
||||||
|
@ -4506,11 +4521,27 @@ void HistoryWidget::saveEditMsg() {
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
options.invertCaption = _mediaEditManager.invertCaption();
|
||||||
|
options.suggest = suggestOptions();
|
||||||
|
|
||||||
|
const auto withPaymentApproved = [=](int approved) {
|
||||||
|
auto copy = options;
|
||||||
|
copy.starsApproved = approved;
|
||||||
|
saveEditMessage(copy);
|
||||||
|
};
|
||||||
|
const auto checked = checkSendPayment(
|
||||||
|
1 + int(_forwardPanel->items().size()),
|
||||||
|
options.starsApproved,
|
||||||
|
withPaymentApproved);
|
||||||
|
if (!checked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_saveEditMsgRequestId = Api::EditTextMessage(
|
_saveEditMsgRequestId = Api::EditTextMessage(
|
||||||
item,
|
item,
|
||||||
sending,
|
sending,
|
||||||
webPageDraft,
|
webPageDraft,
|
||||||
{ .invertCaption = _mediaEditManager.invertCaption() },
|
options,
|
||||||
done,
|
done,
|
||||||
fail,
|
fail,
|
||||||
_mediaEditManager.spoilered());
|
_mediaEditManager.spoilered());
|
||||||
|
@ -4611,7 +4642,7 @@ void HistoryWidget::send(Api::SendOptions options) {
|
||||||
if (!_history) {
|
if (!_history) {
|
||||||
return;
|
return;
|
||||||
} else if (_editMsgId) {
|
} else if (_editMsgId) {
|
||||||
saveEditMsg();
|
saveEditMessage({});
|
||||||
return;
|
return;
|
||||||
} else if (!options.scheduled && showSlowmodeError()) {
|
} else if (!options.scheduled && showSlowmodeError()) {
|
||||||
return;
|
return;
|
||||||
|
@ -7386,10 +7417,14 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
} else if (_previewDrawPreview) {
|
} else if (_previewDrawPreview) {
|
||||||
editDraftOptions();
|
editDraftOptions();
|
||||||
} else if (_editMsgId) {
|
} else if (_editMsgId) {
|
||||||
controller()->showPeerHistory(
|
if (_suggestOptions) {
|
||||||
_peer,
|
_suggestOptions->edit();
|
||||||
Window::SectionShow::Way::Forward,
|
} else {
|
||||||
_editMsgId);
|
controller()->showPeerHistory(
|
||||||
|
_peer,
|
||||||
|
Window::SectionShow::Way::Forward,
|
||||||
|
_editMsgId);
|
||||||
|
}
|
||||||
} else if (_replyTo
|
} else if (_replyTo
|
||||||
&& ((e->modifiers() & Qt::ControlModifier)
|
&& ((e->modifiers() & Qt::ControlModifier)
|
||||||
|| (e->button() != Qt::LeftButton))) {
|
|| (e->button() != Qt::LeftButton))) {
|
||||||
|
@ -8834,6 +8869,7 @@ void HistoryWidget::cancelEdit() {
|
||||||
_replyEditMsg = nullptr;
|
_replyEditMsg = nullptr;
|
||||||
setEditMsgId(0);
|
setEditMsgId(0);
|
||||||
_history->clearLocalEditDraft(MsgId(), PeerId());
|
_history->clearLocalEditDraft(MsgId(), PeerId());
|
||||||
|
cancelSuggestPost();
|
||||||
applyDraft();
|
applyDraft();
|
||||||
|
|
||||||
if (_saveEditMsgRequestId) {
|
if (_saveEditMsgRequestId) {
|
||||||
|
@ -9367,14 +9403,18 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
const auto paused = p.inactive();
|
const auto paused = p.inactive();
|
||||||
const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler);
|
const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler);
|
||||||
auto replyLeft = st::historyReplySkip;
|
auto replyLeft = st::historyReplySkip;
|
||||||
(_editMsgId
|
if (_suggestOptions) {
|
||||||
? st::historyEditIcon
|
_suggestOptions->paintIcon(p, 0, backy, width());
|
||||||
: (_replyTo && !_replyTo.quote.empty())
|
} else {
|
||||||
? st::historyQuoteIcon
|
(_editMsgId
|
||||||
: st::historyReplyIcon).paint(
|
? st::historyEditIcon
|
||||||
p,
|
: (_replyTo && !_replyTo.quote.empty())
|
||||||
st::historyReplyIconPosition + QPoint(0, backy),
|
? st::historyQuoteIcon
|
||||||
width());
|
: st::historyReplyIcon).paint(
|
||||||
|
p,
|
||||||
|
st::historyReplyIconPosition + QPoint(0, backy),
|
||||||
|
width());
|
||||||
|
}
|
||||||
if (drawMsgText) {
|
if (drawMsgText) {
|
||||||
if (hasPreview) {
|
if (hasPreview) {
|
||||||
if (preview) {
|
if (preview) {
|
||||||
|
@ -9412,37 +9452,41 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
}
|
}
|
||||||
replyLeft += st::historyReplyPreview + st::msgReplyBarSkip;
|
replyLeft += st::historyReplyPreview + st::msgReplyBarSkip;
|
||||||
}
|
}
|
||||||
p.setPen(st::historyReplyNameFg);
|
if (_suggestOptions) {
|
||||||
if (_editMsgId) {
|
_suggestOptions->paintLines(p, replyLeft, backy, width());
|
||||||
paintEditHeader(p, rect, replyLeft, backy);
|
|
||||||
} else {
|
} else {
|
||||||
_replyToName.drawElided(
|
p.setPen(st::historyReplyNameFg);
|
||||||
p,
|
if (_editMsgId) {
|
||||||
replyLeft,
|
paintEditHeader(p, rect, replyLeft, backy);
|
||||||
backy + st::msgReplyPadding.top(),
|
} else {
|
||||||
width()
|
_replyToName.drawElided(
|
||||||
|
p,
|
||||||
|
replyLeft,
|
||||||
|
backy + st::msgReplyPadding.top(),
|
||||||
|
width()
|
||||||
|
- replyLeft
|
||||||
|
- _fieldBarCancel->width()
|
||||||
|
- st::msgReplyPadding.right());
|
||||||
|
}
|
||||||
|
p.setPen(st::historyComposeAreaFg);
|
||||||
|
_replyEditMsgText.draw(p, {
|
||||||
|
.position = QPoint(
|
||||||
|
replyLeft,
|
||||||
|
st::msgReplyPadding.top()
|
||||||
|
+ st::msgServiceNameFont->height
|
||||||
|
+ backy),
|
||||||
|
.availableWidth = width()
|
||||||
- replyLeft
|
- replyLeft
|
||||||
- _fieldBarCancel->width()
|
- _fieldBarCancel->width()
|
||||||
- st::msgReplyPadding.right());
|
- st::msgReplyPadding.right(),
|
||||||
|
.palette = &st::historyComposeAreaPalette,
|
||||||
|
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
||||||
|
.now = now,
|
||||||
|
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
|
||||||
|
.pausedSpoiler = pausedSpoiler,
|
||||||
|
.elisionLines = 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
p.setPen(st::historyComposeAreaFg);
|
|
||||||
_replyEditMsgText.draw(p, {
|
|
||||||
.position = QPoint(
|
|
||||||
replyLeft,
|
|
||||||
st::msgReplyPadding.top()
|
|
||||||
+ st::msgServiceNameFont->height
|
|
||||||
+ backy),
|
|
||||||
.availableWidth = width()
|
|
||||||
- replyLeft
|
|
||||||
- _fieldBarCancel->width()
|
|
||||||
- st::msgReplyPadding.right(),
|
|
||||||
.palette = &st::historyComposeAreaPalette,
|
|
||||||
.spoiler = Ui::Text::DefaultSpoilerCache(),
|
|
||||||
.now = now,
|
|
||||||
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
|
|
||||||
.pausedSpoiler = pausedSpoiler,
|
|
||||||
.elisionLines = 1,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
p.setFont(st::msgDateFont);
|
p.setFont(st::msgDateFont);
|
||||||
p.setPen(st::historyComposeAreaFgService);
|
p.setPen(st::historyComposeAreaFgService);
|
||||||
|
|
|
@ -110,6 +110,7 @@ class ComposeSearch;
|
||||||
class SubsectionTabs;
|
class SubsectionTabs;
|
||||||
struct SelectedQuote;
|
struct SelectedQuote;
|
||||||
class SuggestOptions;
|
class SuggestOptions;
|
||||||
|
enum class SuggestMode;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
namespace HistoryView::Controls {
|
namespace HistoryView::Controls {
|
||||||
|
@ -589,7 +590,7 @@ private:
|
||||||
void createUnreadBarAndResize();
|
void createUnreadBarAndResize();
|
||||||
|
|
||||||
[[nodiscard]] TextWithEntities prepareTextForEditMsg() const;
|
[[nodiscard]] TextWithEntities prepareTextForEditMsg() const;
|
||||||
void saveEditMsg();
|
void saveEditMessage(Api::SendOptions options = {});
|
||||||
|
|
||||||
void setupPreview();
|
void setupPreview();
|
||||||
void editDraftOptions();
|
void editDraftOptions();
|
||||||
|
@ -682,7 +683,9 @@ private:
|
||||||
void refreshScheduledToggle();
|
void refreshScheduledToggle();
|
||||||
void refreshSendGiftToggle();
|
void refreshSendGiftToggle();
|
||||||
void refreshSuggestPostToggle();
|
void refreshSuggestPostToggle();
|
||||||
void applySuggestOptions(SuggestPostOptions suggest);
|
void applySuggestOptions(
|
||||||
|
SuggestPostOptions suggest,
|
||||||
|
HistoryView::SuggestMode mode);
|
||||||
void setupSendAsToggle();
|
void setupSendAsToggle();
|
||||||
void refreshSendAsToggle();
|
void refreshSendAsToggle();
|
||||||
void refreshAttachBotsMenu();
|
void refreshAttachBotsMenu();
|
||||||
|
|
|
@ -2381,13 +2381,14 @@ bool ChatWidget::showInternal(
|
||||||
const Window::SectionShow ¶ms) {
|
const Window::SectionShow ¶ms) {
|
||||||
if (auto logMemento = dynamic_cast<ChatMemento*>(memento.get())) {
|
if (auto logMemento = dynamic_cast<ChatMemento*>(memento.get())) {
|
||||||
if (logMemento->id() == _id) {
|
if (logMemento->id() == _id) {
|
||||||
restoreState(logMemento);
|
|
||||||
if (!logMemento->highlightId()) {
|
|
||||||
showAtPosition(Data::UnreadMessagePosition);
|
|
||||||
}
|
|
||||||
if (params.reapplyLocalDraft) {
|
if (params.reapplyLocalDraft) {
|
||||||
_composeControls->applyDraft(
|
_composeControls->applyDraft(
|
||||||
ComposeControls::FieldHistoryAction::NewEntry);
|
ComposeControls::FieldHistoryAction::NewEntry);
|
||||||
|
} else {
|
||||||
|
restoreState(logMemento);
|
||||||
|
if (!logMemento->highlightId()) {
|
||||||
|
showAtPosition(Data::UnreadMessagePosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_media_types.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_app_config.h"
|
#include "main/main_app_config.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -36,8 +38,12 @@ void ChooseSuggestTimeBox(
|
||||||
? std::clamp(args.value, now + min, now + max)
|
? std::clamp(args.value, now + min, now + max)
|
||||||
: (now + 86400);
|
: (now + 86400);
|
||||||
Ui::ChooseDateTimeBox(box, {
|
Ui::ChooseDateTimeBox(box, {
|
||||||
.title = std::move(args.title),
|
.title = ((args.mode == SuggestMode::New)
|
||||||
.submit = std::move(args.submit),
|
? tr::lng_suggest_options_date()
|
||||||
|
: tr::lng_suggest_menu_edit_time()),
|
||||||
|
.submit = ((args.mode == SuggestMode::New)
|
||||||
|
? tr::lng_settings_save()
|
||||||
|
: tr::lng_suggest_options_update()),
|
||||||
.done = std::move(args.done),
|
.done = std::move(args.done),
|
||||||
.min = [=] { return now + min; },
|
.min = [=] { return now + min; },
|
||||||
.time = value,
|
.time = value,
|
||||||
|
@ -56,7 +62,9 @@ void ChooseSuggestPriceBox(
|
||||||
|
|
||||||
const auto limit = args.session->appConfig().suggestedPostStarsMax();
|
const auto limit = args.session->appConfig().suggestedPostStarsMax();
|
||||||
|
|
||||||
box->setTitle(tr::lng_suggest_options_title());
|
box->setTitle((args.mode == SuggestMode::New)
|
||||||
|
? tr::lng_suggest_options_title()
|
||||||
|
: tr::lng_suggest_options_change());
|
||||||
|
|
||||||
const auto container = box->verticalLayout();
|
const auto container = box->verticalLayout();
|
||||||
|
|
||||||
|
@ -117,10 +125,9 @@ void ChooseSuggestPriceBox(
|
||||||
};
|
};
|
||||||
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
|
||||||
.session = args.session,
|
.session = args.session,
|
||||||
.title = tr::lng_suggest_options_date(),
|
|
||||||
.submit = tr::lng_settings_save(),
|
|
||||||
.done = done,
|
.done = done,
|
||||||
.value = state->date.current(),
|
.value = state->date.current(),
|
||||||
|
.mode = args.mode,
|
||||||
});
|
});
|
||||||
*weak = dateBox.data();
|
*weak = dateBox.data();
|
||||||
box->uiShow()->show(std::move(dateBox));
|
box->uiShow()->show(std::move(dateBox));
|
||||||
|
@ -150,25 +157,38 @@ void ChooseSuggestPriceBox(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanEditSuggestedMessage(not_null<HistoryItem*> item) {
|
||||||
|
const auto media = item->media();
|
||||||
|
return !media || media->allowsEditCaption();
|
||||||
|
}
|
||||||
|
|
||||||
SuggestOptions::SuggestOptions(
|
SuggestOptions::SuggestOptions(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SuggestPostOptions values)
|
SuggestPostOptions values,
|
||||||
|
SuggestMode mode)
|
||||||
: _controller(controller)
|
: _controller(controller)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
|
, _mode(mode)
|
||||||
, _values(values) {
|
, _values(values) {
|
||||||
updateTexts();
|
updateTexts();
|
||||||
}
|
}
|
||||||
|
|
||||||
SuggestOptions::~SuggestOptions() = default;
|
SuggestOptions::~SuggestOptions() = default;
|
||||||
|
|
||||||
void SuggestOptions::paintBar(QPainter &p, int x, int y, int outerWidth) {
|
void SuggestOptions::paintIcon(QPainter &p, int x, int y, int outerWidth) {
|
||||||
st::historyDirectMessage.icon.paint(
|
st::historyDirectMessage.icon.paint(
|
||||||
p,
|
p,
|
||||||
QPoint(x, y) + st::historySuggestIconPosition,
|
QPoint(x, y) + st::historySuggestIconPosition,
|
||||||
outerWidth);
|
outerWidth);
|
||||||
|
}
|
||||||
|
|
||||||
x += st::historyReplySkip;
|
void SuggestOptions::paintBar(QPainter &p, int x, int y, int outerWidth) {
|
||||||
|
paintIcon(p, x, y, outerWidth);
|
||||||
|
paintLines(p, x + st::historyReplySkip, y, outerWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuggestOptions::paintLines(QPainter &p, int x, int y, int outerWidth) {
|
||||||
auto available = outerWidth
|
auto available = outerWidth
|
||||||
- x
|
- x
|
||||||
- st::historyReplyCancel.width
|
- st::historyReplyCancel.width
|
||||||
|
@ -207,7 +227,9 @@ void SuggestOptions::edit() {
|
||||||
void SuggestOptions::updateTexts() {
|
void SuggestOptions::updateTexts() {
|
||||||
_title.setText(
|
_title.setText(
|
||||||
st::semiboldTextStyle,
|
st::semiboldTextStyle,
|
||||||
tr::lng_suggest_bar_title(tr::now));
|
((_mode == SuggestMode::New)
|
||||||
|
? tr::lng_suggest_bar_title(tr::now)
|
||||||
|
: tr::lng_suggest_options_change(tr::now)));
|
||||||
_text.setMarkedText(st::defaultTextStyle, composeText());
|
_text.setMarkedText(st::defaultTextStyle, composeText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,16 @@ class SessionController;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
enum class SuggestMode {
|
||||||
|
New,
|
||||||
|
Change,
|
||||||
|
};
|
||||||
|
|
||||||
struct SuggestTimeBoxArgs {
|
struct SuggestTimeBoxArgs {
|
||||||
not_null<Main::Session*> session;
|
not_null<Main::Session*> session;
|
||||||
rpl::producer<QString> title;
|
|
||||||
rpl::producer<QString> submit;
|
|
||||||
Fn<void(TimeId)> done;
|
Fn<void(TimeId)> done;
|
||||||
TimeId value = 0;
|
TimeId value = 0;
|
||||||
|
SuggestMode mode = SuggestMode::New;
|
||||||
};
|
};
|
||||||
void ChooseSuggestTimeBox(
|
void ChooseSuggestTimeBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
|
@ -39,22 +43,29 @@ struct SuggestPriceBoxArgs {
|
||||||
bool updating = false;
|
bool updating = false;
|
||||||
Fn<void(SuggestPostOptions)> done;
|
Fn<void(SuggestPostOptions)> done;
|
||||||
SuggestPostOptions value;
|
SuggestPostOptions value;
|
||||||
|
SuggestMode mode = SuggestMode::New;
|
||||||
};
|
};
|
||||||
void ChooseSuggestPriceBox(
|
void ChooseSuggestPriceBox(
|
||||||
not_null<Ui::GenericBox*> box,
|
not_null<Ui::GenericBox*> box,
|
||||||
SuggestPriceBoxArgs &&args);
|
SuggestPriceBoxArgs &&args);
|
||||||
|
|
||||||
|
[[nodiscard]] bool CanEditSuggestedMessage(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
class SuggestOptions final {
|
class SuggestOptions final {
|
||||||
public:
|
public:
|
||||||
SuggestOptions(
|
SuggestOptions(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SuggestPostOptions values);
|
SuggestPostOptions values,
|
||||||
|
SuggestMode mode);
|
||||||
~SuggestOptions();
|
~SuggestOptions();
|
||||||
|
|
||||||
void paintBar(QPainter &p, int x, int y, int outerWidth);
|
void paintBar(QPainter &p, int x, int y, int outerWidth);
|
||||||
void edit();
|
void edit();
|
||||||
|
|
||||||
|
void paintIcon(QPainter &p, int x, int y, int outerWidth);
|
||||||
|
void paintLines(QPainter &p, int x, int y, int outerWidth);
|
||||||
|
|
||||||
[[nodiscard]] SuggestPostOptions values() const;
|
[[nodiscard]] SuggestPostOptions values() const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> updates() const;
|
[[nodiscard]] rpl::producer<> updates() const;
|
||||||
|
@ -68,6 +79,7 @@ private:
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
|
const SuggestMode _mode = SuggestMode::New;
|
||||||
|
|
||||||
Ui::Text::String _title;
|
Ui::Text::String _title;
|
||||||
Ui::Text::String _text;
|
Ui::Text::String _text;
|
||||||
|
|
|
@ -316,38 +316,32 @@ auto GenerateSuggestRequestMedia(
|
||||||
style::al_top);
|
style::al_top);
|
||||||
|
|
||||||
auto entries = std::vector<AttributeTable::Entry>();
|
auto entries = std::vector<AttributeTable::Entry>();
|
||||||
if (!changes || changes->price) {
|
entries.push_back({
|
||||||
entries.push_back({
|
((changes && changes->price)
|
||||||
(changes
|
? tr::lng_suggest_change_price_label
|
||||||
? tr::lng_suggest_change_price_label
|
: tr::lng_suggest_action_price_label)(tr::now),
|
||||||
: tr::lng_suggest_action_price_label)(tr::now),
|
Ui::Text::Bold(suggest->stars
|
||||||
Ui::Text::Bold(suggest->stars
|
? tr::lng_prize_credits_amount(
|
||||||
? tr::lng_prize_credits_amount(
|
tr::now,
|
||||||
tr::now,
|
lt_count,
|
||||||
lt_count,
|
suggest->stars)
|
||||||
suggest->stars)
|
: tr::lng_suggest_action_price_free(tr::now)),
|
||||||
: tr::lng_suggest_action_price_free(tr::now)),
|
});
|
||||||
});
|
entries.push_back({
|
||||||
}
|
((changes && changes->date)
|
||||||
if (!changes || changes->date) {
|
? tr::lng_suggest_change_time_label
|
||||||
entries.push_back({
|
: tr::lng_suggest_action_time_label)(tr::now),
|
||||||
(changes
|
Ui::Text::Bold(suggest->date
|
||||||
? tr::lng_suggest_change_time_label
|
? Ui::FormatDateTime(base::unixtime::parse(suggest->date))
|
||||||
: tr::lng_suggest_action_time_label)(tr::now),
|
: tr::lng_suggest_action_time_any(tr::now)),
|
||||||
Ui::Text::Bold(suggest->date
|
});
|
||||||
? Ui::FormatDateTime(base::unixtime::parse(suggest->date))
|
push(std::make_unique<AttributeTable>(
|
||||||
: tr::lng_suggest_action_time_any(tr::now)),
|
std::move(entries),
|
||||||
});
|
((changes && changes->message)
|
||||||
}
|
? st::chatSuggestTableMiddleMargin
|
||||||
if (!entries.empty()) {
|
: st::chatSuggestTableLastMargin),
|
||||||
push(std::make_unique<AttributeTable>(
|
fadedFg,
|
||||||
std::move(entries),
|
normalFg));
|
||||||
((changes && changes->message)
|
|
||||||
? st::chatSuggestTableMiddleMargin
|
|
||||||
: st::chatSuggestTableLastMargin),
|
|
||||||
fadedFg,
|
|
||||||
normalFg));
|
|
||||||
}
|
|
||||||
if (changes && changes->message) {
|
if (changes && changes->message) {
|
||||||
push(std::make_unique<TextPartColored>(
|
push(std::make_unique<TextPartColored>(
|
||||||
tr::lng_suggest_change_text_label(
|
tr::lng_suggest_change_text_label(
|
||||||
|
|
Loading…
Add table
Reference in a new issue