mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
PoC suggested accept/decline.
This commit is contained in:
parent
e4a4be1f53
commit
cb987c1baf
21 changed files with 390 additions and 45 deletions
|
@ -176,6 +176,8 @@ PRIVATE
|
|||
api/api_statistics_data_deserialize.h
|
||||
api/api_statistics_sender.cpp
|
||||
api/api_statistics_sender.h
|
||||
api/api_suggest_post.cpp
|
||||
api/api_suggest_post.h
|
||||
api/api_text_entities.cpp
|
||||
api/api_text_entities.h
|
||||
api/api_todo_lists.cpp
|
||||
|
|
|
@ -638,6 +638,7 @@ void SendConfirmedFile(
|
|||
edition.useSameMarkup = true;
|
||||
edition.useSameReplies = true;
|
||||
edition.useSameReactions = true;
|
||||
edition.useSameSuggest = true;
|
||||
edition.savePreviousMedia = true;
|
||||
itemToEdit->applyEdition(std::move(edition));
|
||||
} else {
|
||||
|
|
199
Telegram/SourceFiles/api/api_suggest_post.cpp
Normal file
199
Telegram/SourceFiles/api/api_suggest_post.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_suggest_post.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "ui/boxes/choose_date_time.h"
|
||||
#include "window/window_session_controller.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
void SendApproval(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item,
|
||||
TimeId scheduleDate = 0) {
|
||||
using Flag = MTPmessages_ToggleSuggestedPostApproval::Flag;
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (!suggestion
|
||||
|| suggestion->accepted
|
||||
|| suggestion->rejected
|
||||
|| suggestion->requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto id = item->fullId();
|
||||
const auto weak = base::make_weak(controller);
|
||||
const auto session = &controller->session();
|
||||
const auto finish = [=] {
|
||||
if (const auto item = session->data().message(id)) {
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (suggestion) {
|
||||
suggestion->requestId = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
suggestion->requestId = session->api().request(
|
||||
MTPmessages_ToggleSuggestedPostApproval(
|
||||
MTP_flags(scheduleDate ? Flag::f_schedule_date : Flag()),
|
||||
item->history()->peer->input,
|
||||
MTP_int(item->id.bare),
|
||||
MTP_int(scheduleDate),
|
||||
MTPstring()) // reject_comment
|
||||
).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
finish();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (const auto window = weak.get()) {
|
||||
window->showToast(error.type());
|
||||
}
|
||||
finish();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void SendDecline(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item,
|
||||
const QString &comment) {
|
||||
using Flag = MTPmessages_ToggleSuggestedPostApproval::Flag;
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (!suggestion
|
||||
|| suggestion->accepted
|
||||
|| suggestion->rejected
|
||||
|| suggestion->requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto id = item->fullId();
|
||||
const auto weak = base::make_weak(controller);
|
||||
const auto session = &controller->session();
|
||||
const auto finish = [=] {
|
||||
if (const auto item = session->data().message(id)) {
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (suggestion) {
|
||||
suggestion->requestId = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
suggestion->requestId = session->api().request(
|
||||
MTPmessages_ToggleSuggestedPostApproval(
|
||||
MTP_flags(Flag::f_reject
|
||||
| (comment.isEmpty() ? Flag() : Flag::f_reject_comment)),
|
||||
item->history()->peer->input,
|
||||
MTP_int(item->id.bare),
|
||||
MTPint(), // schedule_date
|
||||
MTP_string(comment))
|
||||
).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
finish();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (const auto window = weak.get()) {
|
||||
window->showToast(error.type());
|
||||
}
|
||||
finish();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void RequestApprovalDate(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
const auto done = [=](TimeId result) {
|
||||
SendApproval(controller, item, result);
|
||||
if (const auto strong = weak->data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
auto dateBox = Box(Ui::ChooseDateTimeBox, Ui::ChooseDateTimeBoxArgs{
|
||||
.title = tr::lng_suggest_options_date(),
|
||||
.submit = tr::lng_settings_save(),
|
||||
.done = done,
|
||||
.min = [] { return base::unixtime::now() + 1; },
|
||||
.time = (base::unixtime::now() + 86400),
|
||||
});
|
||||
*weak = dateBox.data();
|
||||
controller->uiShow()->show(std::move(dateBox));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<ClickHandler> AcceptClickHandler(
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto session = &item->history()->session();
|
||||
const auto id = item->fullId();
|
||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
const auto controller = my.sessionWindow.get();
|
||||
if (!controller || &controller->session() != session) {
|
||||
return;
|
||||
}
|
||||
const auto item = session->data().message(id);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (!suggestion) {
|
||||
return;
|
||||
} else if (!suggestion->date) {
|
||||
RequestApprovalDate(controller, item);
|
||||
} else {
|
||||
SendApproval(controller, item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<ClickHandler> DeclineClickHandler(
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto session = &item->history()->session();
|
||||
const auto id = item->fullId();
|
||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
const auto controller = my.sessionWindow.get();
|
||||
if (!controller || &controller->session() != session) {
|
||||
return;
|
||||
}
|
||||
const auto item = session->data().message(id);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
|
||||
if (!suggestion) {
|
||||
return;
|
||||
} else {
|
||||
SendDecline(controller, item, "sorry, bro..");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<ClickHandler> SuggestChangesClickHandler(
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto session = &item->history()->session();
|
||||
const auto id = item->fullId();
|
||||
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
const auto window = my.sessionWindow.get();
|
||||
if (!window || &window->session() != session) {
|
||||
return;
|
||||
}
|
||||
const auto item = session->data().message(id);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Api
|
21
Telegram/SourceFiles/api/api_suggest_post.h
Normal file
21
Telegram/SourceFiles/api/api_suggest_post.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class ClickHandler;
|
||||
|
||||
namespace Api {
|
||||
|
||||
[[nodiscard]] std::shared_ptr<ClickHandler> AcceptClickHandler(
|
||||
not_null<HistoryItem*> item);
|
||||
[[nodiscard]] std::shared_ptr<ClickHandler> DeclineClickHandler(
|
||||
not_null<HistoryItem*> item);
|
||||
[[nodiscard]] std::shared_ptr<ClickHandler> SuggestChangesClickHandler(
|
||||
not_null<HistoryItem*> item);
|
||||
|
||||
} // namespace Api
|
|
@ -2154,6 +2154,9 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
if (!textWithTags.tags.isEmpty()) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
||||
}
|
||||
if (cloudDraft->suggest) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_suggested_post;
|
||||
}
|
||||
auto entities = Api::EntitiesToMTP(
|
||||
_session,
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "menu/menu_ttl_validator.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
@ -32,6 +33,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kPaidShowLive = 86400;
|
||||
|
||||
} // namespace
|
||||
|
||||
DeleteMessagesBox::DeleteMessagesBox(
|
||||
QWidget*,
|
||||
not_null<HistoryItem*> item,
|
||||
|
@ -492,7 +499,41 @@ void DeleteMessagesBox::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
bool DeleteMessagesBox::hasPaidSuggestedPosts() const {
|
||||
const auto now = base::unixtime::now();
|
||||
for (const auto &id : _ids) {
|
||||
if (const auto item = _session->data().message(id)) {
|
||||
if (item->isPaidSuggestedPost()) {
|
||||
const auto date = item->date();
|
||||
if (now < date || now - date <= kPaidShowLive) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeleteMessagesBox::deleteAndClear() {
|
||||
if (hasPaidSuggestedPosts() && !_confirmedDeletePaidSuggestedPosts) {
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
const auto callback = [=](Fn<void()> close) {
|
||||
close();
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->_confirmedDeletePaidSuggestedPosts = true;
|
||||
strong->deleteAndClear();
|
||||
}
|
||||
};
|
||||
AssertIsDebug();
|
||||
uiShow()->show(Ui::MakeConfirmBox({
|
||||
.text = u"You won't receive Stars for this post if you delete it now. The post must remain visible for at least 24 hours after it was published."_q,
|
||||
.confirmed = callback,
|
||||
.confirmText = u"Delete Anyway"_q,
|
||||
.confirmStyle = &st::attentionBoxButton,
|
||||
.title = u"Stars will be lost"_q,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
if (_revoke
|
||||
&& _revokeRemember
|
||||
&& _revokeRemember->toggled()
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
[[nodiscard]] bool hasScheduledMessages() const;
|
||||
[[nodiscard]] std::optional<RevokeConfig> revokeText(
|
||||
not_null<PeerData*> peer) const;
|
||||
[[nodiscard]] bool hasPaidSuggestedPosts() const;
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
|
@ -82,6 +83,7 @@ private:
|
|||
object_ptr<Ui::LinkButton> _autoDeleteSettings = { nullptr };
|
||||
|
||||
int _fullHeight = 0;
|
||||
bool _confirmedDeletePaidSuggestedPosts = false;
|
||||
|
||||
Fn<void()> _deleteConfirmedCallback;
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ Draft::Draft(
|
|||
mtpRequestId saveRequestId)
|
||||
: textWithTags(textWithTags)
|
||||
, reply(std::move(reply))
|
||||
, suggest(suggest)
|
||||
, cursor(cursor)
|
||||
, webpage(webpage)
|
||||
, saveRequestId(saveRequestId) {
|
||||
|
@ -69,6 +70,7 @@ Draft::Draft(
|
|||
mtpRequestId saveRequestId)
|
||||
: textWithTags(field->getTextWithTags())
|
||||
, reply(std::move(reply))
|
||||
, suggest(suggest)
|
||||
, cursor(field)
|
||||
, webpage(webpage) {
|
||||
}
|
||||
|
|
|
@ -257,6 +257,7 @@ using HistoryDrafts = base::flat_map<DraftKey, std::unique_ptr<Draft>>;
|
|||
}
|
||||
return (a->textWithTags == b->textWithTags)
|
||||
&& (a->reply == b->reply)
|
||||
&& (a->suggest == b->suggest)
|
||||
&& (a->webpage == b->webpage);
|
||||
}
|
||||
|
||||
|
|
|
@ -353,6 +353,8 @@ enum class MessageFlag : uint64 {
|
|||
ReactionsAllowed = (1ULL << 50),
|
||||
|
||||
HideDisplayDate = (1ULL << 51),
|
||||
|
||||
PaidSuggestedPost = (1ULL << 52),
|
||||
};
|
||||
inline constexpr bool is_flag_type(MessageFlag) { return true; }
|
||||
using MessageFlags = base::flags<MessageFlag>;
|
||||
|
|
|
@ -1593,6 +1593,10 @@ bool HistoryItem::isEditingMedia() const {
|
|||
return Has<HistoryMessageSavedMediaData>();
|
||||
}
|
||||
|
||||
bool HistoryItem::isPaidSuggestedPost() const {
|
||||
return _flags & MessageFlag::PaidSuggestedPost;
|
||||
}
|
||||
|
||||
void HistoryItem::clearSavedMedia() {
|
||||
RemoveComponents(HistoryMessageSavedMediaData::Bit());
|
||||
}
|
||||
|
@ -1887,6 +1891,21 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!edition.useSameSuggest) {
|
||||
if (edition.suggest.exists) {
|
||||
if (!Has<HistoryMessageSuggestedPost>()) {
|
||||
AddComponents(HistoryMessageSuggestedPost::Bit());
|
||||
}
|
||||
auto suggest = Get<HistoryMessageSuggestedPost>();
|
||||
suggest->stars = edition.suggest.stars;
|
||||
suggest->date = edition.suggest.date;
|
||||
suggest->accepted = edition.suggest.accepted;
|
||||
suggest->rejected = edition.suggest.rejected;
|
||||
} else {
|
||||
RemoveComponents(HistoryMessageSuggestedPost::Bit());
|
||||
}
|
||||
}
|
||||
|
||||
applyTTL(edition.ttl);
|
||||
setFactcheck(FromMTP(this, edition.mtpFactcheck));
|
||||
|
||||
|
@ -2398,7 +2417,8 @@ bool HistoryItem::allowsSendNow() const {
|
|||
&& isScheduled()
|
||||
&& !isSending()
|
||||
&& !hasFailed()
|
||||
&& !isEditingMedia();
|
||||
&& !isEditingMedia()
|
||||
&& !isPaidSuggestedPost();
|
||||
}
|
||||
|
||||
bool HistoryItem::allowsReschedule() const {
|
||||
|
@ -2425,7 +2445,8 @@ bool HistoryItem::allowsEdit(TimeId now) const {
|
|||
&& !isTooOldForEdit(now)
|
||||
&& (!_media || _media->allowsEdit())
|
||||
&& !isLegacyMessage()
|
||||
&& !isEditingMedia();
|
||||
&& !isEditingMedia()
|
||||
&& !isPaidSuggestedPost();
|
||||
}
|
||||
|
||||
bool HistoryItem::allowsEditMedia() const {
|
||||
|
@ -5928,8 +5949,15 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
|||
return prepareTodoAppendTasksText();
|
||||
};
|
||||
|
||||
auto prepareSuggestedPostApproval = [&](const MTPDmessageActionSuggestedPostApproval &) {
|
||||
return PreparedServiceText{ { "process_suggested" } }; AssertIsDebug();
|
||||
auto prepareSuggestedPostApproval = [&](const MTPDmessageActionSuggestedPostApproval &data) {
|
||||
if (data.is_balance_too_low()) {
|
||||
return PreparedServiceText{ { u"balance too low :( need %1 stars"_q.arg(data.vstars_amount().value_or_empty()) } };
|
||||
} else if (data.is_rejected()) {
|
||||
return PreparedServiceText{ { u"rejected :( comment: %1"_q.arg(qs(data.vreject_comment().value_or_empty())) } };
|
||||
} else if (const auto date = data.vschedule_date().value_or_empty()) {
|
||||
return PreparedServiceText{ { u"approved!! for date: %1"_q.arg(langDateTime(base::unixtime::parse(date))) } };
|
||||
}
|
||||
return PreparedServiceText{ { "approved!!" } }; AssertIsDebug();
|
||||
};
|
||||
|
||||
auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &) -> PreparedServiceText {
|
||||
|
|
|
@ -312,6 +312,7 @@ public:
|
|||
[[nodiscard]] bool hasRealFromId() const;
|
||||
[[nodiscard]] bool isPostHidingAuthor() const;
|
||||
[[nodiscard]] bool isPostShowingAuthor() const;
|
||||
[[nodiscard]] bool isPaidSuggestedPost() const;
|
||||
[[nodiscard]] bool isRegular() const;
|
||||
[[nodiscard]] bool isUploading() const;
|
||||
void sendFailed();
|
||||
|
|
|
@ -618,6 +618,7 @@ struct HistoryMessageSuggestedPost
|
|||
: RuntimeComponent<HistoryMessageSuggestedPost, HistoryItem> {
|
||||
int stars = 0;
|
||||
TimeId date = 0;
|
||||
mtpRequestId requestId = 0;
|
||||
bool accepted = false;
|
||||
bool rejected = false;
|
||||
};
|
||||
|
|
|
@ -11,8 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session.h"
|
||||
|
||||
HistoryMessageEdition::HistoryMessageEdition(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDmessage &message) {
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDmessage &message)
|
||||
: suggest(HistoryMessageSuggestInfo(message.vsuggested_post())) {
|
||||
isEditHide = message.is_edit_hide();
|
||||
isMediaUnread = message.is_media_unread();
|
||||
editDate = message.vedit_date().value_or(-1);
|
||||
|
|
|
@ -30,11 +30,13 @@ struct HistoryMessageEdition {
|
|||
bool useSameReplies = false;
|
||||
bool useSameMarkup = false;
|
||||
bool useSameReactions = false;
|
||||
bool useSameSuggest = false;
|
||||
bool savePreviousMedia = false;
|
||||
bool invertMedia = false;
|
||||
TextWithEntities textWithEntities;
|
||||
HistoryMessageMarkupData replyMarkup;
|
||||
HistoryMessageRepliesData replies;
|
||||
HistoryMessageSuggestInfo suggest;
|
||||
const MTPMessageMedia *mtpMedia = nullptr;
|
||||
const MTPMessageReactions *mtpReactions = nullptr;
|
||||
const MTPFactCheck *mtpFactcheck = nullptr;
|
||||
|
|
|
@ -762,6 +762,9 @@ MessageFlags FlagsFromMTP(
|
|||
| ((flags & MTP::f_invert_media) ? Flag::InvertMedia : Flag())
|
||||
| ((flags & MTP::f_video_processing_pending)
|
||||
? Flag::EstimatedDate
|
||||
: Flag())
|
||||
| ((flags & MTP::f_paid_suggested_post)
|
||||
? Flag::PaidSuggestedPost
|
||||
: Flag());
|
||||
}
|
||||
|
||||
|
|
|
@ -3172,9 +3172,17 @@ void HistoryWidget::applySuggestOptions(SuggestPostOptions suggest) {
|
|||
controller(),
|
||||
_peer,
|
||||
suggest);
|
||||
_suggestOptions->repaints() | rpl::start_with_next([=] {
|
||||
_suggestOptions->updates() | rpl::start_with_next([=] {
|
||||
updateField();
|
||||
saveDraftWithTextNow();
|
||||
}, _suggestOptions->lifetime());
|
||||
saveDraftWithTextNow();
|
||||
}
|
||||
|
||||
void HistoryWidget::saveDraftWithTextNow() {
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
}
|
||||
|
||||
void HistoryWidget::refreshSuggestPostToggle() {
|
||||
|
@ -4644,9 +4652,7 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
if (_preview) {
|
||||
_preview->apply({ .removed = true });
|
||||
}
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
saveDraftWithTextNow();
|
||||
|
||||
hideSelectorControlsAnimated();
|
||||
|
||||
|
@ -7680,9 +7686,7 @@ void HistoryWidget::sendInlineResult(InlineBots::ResultSelected result) {
|
|||
result.messageSendingFrom.localId);
|
||||
|
||||
clearFieldText();
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
saveDraftWithTextNow();
|
||||
|
||||
auto &bots = cRefRecentInlineBots();
|
||||
const auto index = bots.indexOf(result.bot);
|
||||
|
@ -8296,9 +8300,7 @@ bool HistoryWidget::sendExistingDocument(
|
|||
|
||||
if (_autocomplete && _autocomplete->stickersShown()) {
|
||||
clearFieldText();
|
||||
//_saveDraftText = true;
|
||||
//_saveDraftStart = crl::now();
|
||||
//saveDraft();
|
||||
//saveDraftWithTextNow();
|
||||
|
||||
// won't be needed if SendInlineBotResult will clear the cloud draft
|
||||
saveCloudDraft();
|
||||
|
@ -8634,10 +8636,7 @@ void HistoryWidget::setReplyFieldsFromProcessing() {
|
|||
refreshTopBarActiveChat();
|
||||
}
|
||||
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
|
||||
saveDraftWithTextNow();
|
||||
setInnerFocus();
|
||||
}
|
||||
|
||||
|
@ -8702,10 +8701,7 @@ void HistoryWidget::editMessage(
|
|||
updateField();
|
||||
SelectTextInFieldWithMargins(_field, selection);
|
||||
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
|
||||
saveDraftWithTextNow();
|
||||
setInnerFocus();
|
||||
}
|
||||
|
||||
|
@ -8794,9 +8790,7 @@ bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
|||
}
|
||||
}
|
||||
if (wasReply) {
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
saveDraftWithTextNow();
|
||||
}
|
||||
if (!_editMsgId
|
||||
&& _keyboard->singleUse()
|
||||
|
@ -8841,9 +8835,7 @@ void HistoryWidget::cancelEdit() {
|
|||
_saveEditMsgRequestId = 0;
|
||||
}
|
||||
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
saveDraft();
|
||||
saveDraftWithTextNow();
|
||||
|
||||
mouseMoveEvent(nullptr);
|
||||
if (!readyToForward()
|
||||
|
@ -8891,6 +8883,7 @@ bool HistoryWidget::cancelSuggestPost() {
|
|||
_suggestOptions = nullptr;
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
saveDraftWithTextNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -391,6 +391,7 @@ private:
|
|||
void saveDraft(bool delayed = false);
|
||||
void saveCloudDraft();
|
||||
void saveDraftDelayed();
|
||||
void saveDraftWithTextNow();
|
||||
void showMembersDropdown();
|
||||
void windowIsVisibleChanged();
|
||||
void saveFieldToHistoryLocalDraft();
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "history/view/history_view_message.h"
|
||||
|
||||
#include "api/api_suggest_post.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/click_handler_types.h" // ClickHandlerContext
|
||||
#include "core/ui_integration.h"
|
||||
|
@ -24,11 +25,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/share_box.h"
|
||||
#include "ui/effects/glare.h"
|
||||
#include "ui/effects/reaction_fly_animation.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text/text_extended_data.h"
|
||||
#include "ui/power_saving.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "data/components/factchecks.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/data_session.h"
|
||||
|
@ -456,17 +457,45 @@ void Message::initPaidInformation() {
|
|||
const auto item = data();
|
||||
if (!item->history()->peer->isUser()) {
|
||||
|
||||
|
||||
if (const auto suggest = item->Get<HistoryMessageSuggestedPost>()) {
|
||||
auto text = PreparedServiceText();
|
||||
if (!suggest->stars && !suggest->date) {
|
||||
setServicePreMessage({ { u"suggestion to publish for free anytime"_q } });
|
||||
text = { { u"suggestion to publish for free anytime"_q } };
|
||||
} else if (!suggest->date) {
|
||||
setServicePreMessage({ { u"suggestion to publish for %1 stars anytime"_q.arg(suggest->stars) }});
|
||||
text = { { u"suggestion to publish for %1 stars anytime"_q.arg(suggest->stars) } };
|
||||
} else if (!suggest->stars) {
|
||||
setServicePreMessage({ { u"suggestion to publish for free %1"_q.arg(langDateTime(base::unixtime::parse(suggest->date))) }});
|
||||
text = { { u"suggestion to publish for free %1"_q.arg(langDateTime(base::unixtime::parse(suggest->date))) } };
|
||||
} else {
|
||||
setServicePreMessage({ { u"suggestion to publish for %1 stars %2"_q.arg(suggest->stars).arg(langDateTime(base::unixtime::parse(suggest->date))) } });
|
||||
text = { { u"suggestion to publish for %1 stars %2"_q.arg(suggest->stars).arg(langDateTime(base::unixtime::parse(suggest->date))) } };
|
||||
}
|
||||
const auto channelIsAuthor = item->from()->isChannel();
|
||||
const auto amMonoforumAdmin = item->history()->peer->amMonoforumAdmin();
|
||||
const auto broadcast = item->history()->peer->monoforumBroadcast();
|
||||
const auto canDecline = item->isRegular()
|
||||
&& !(suggest->accepted || suggest->rejected)
|
||||
&& (channelIsAuthor ? !amMonoforumAdmin : amMonoforumAdmin);
|
||||
const auto canAccept = canDecline
|
||||
&& (channelIsAuthor
|
||||
? !amMonoforumAdmin
|
||||
: (amMonoforumAdmin
|
||||
&& broadcast
|
||||
&& broadcast->canPostMessages()));
|
||||
if (canDecline) {
|
||||
text.links.push_back(Api::DeclineClickHandler(item));
|
||||
text.text.append(", ").append(Ui::Text::Link("[Decline]", text.links.size()));
|
||||
if (canAccept) {
|
||||
text.links.push_back(Api::AcceptClickHandler(item));
|
||||
text.text.append(", ").append(Ui::Text::Link("[Accept]", text.links.size()));
|
||||
|
||||
text.links.push_back(Api::SuggestChangesClickHandler(item));
|
||||
text.text.append(", ").append(Ui::Text::Link("[SuggestChanges]", text.links.size()));
|
||||
}
|
||||
} else if (suggest->accepted) {
|
||||
text.text.append(", accepted!");
|
||||
} else if (suggest->rejected) {
|
||||
text.text.append(", rejected :(");
|
||||
}
|
||||
setServicePreMessage(std::move(text));
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -94,15 +94,27 @@ void EditOptionsBox(
|
|||
st::settingsButtonNoIcon);
|
||||
|
||||
time->setClickedCallback([=] {
|
||||
box->uiShow()->show(Box(Ui::ChooseDateTimeBox, Ui::ChooseDateTimeBoxArgs{
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
const auto parentWeak = Ui::MakeWeak(box);
|
||||
const auto done = [=](TimeId result) {
|
||||
if (parentWeak) {
|
||||
state->date = result;
|
||||
}
|
||||
if (const auto strong = weak->data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
auto dateBox = Box(Ui::ChooseDateTimeBox, Ui::ChooseDateTimeBoxArgs{
|
||||
.title = tr::lng_suggest_options_date(),
|
||||
.submit = tr::lng_settings_save(),
|
||||
.done = [=](TimeId result) { state->date = result; },
|
||||
.done = done,
|
||||
.min = [] { return base::unixtime::now() + 1; },
|
||||
.time = (state->date.current()
|
||||
? state->date.current()
|
||||
: (base::unixtime::now() + 86400)),
|
||||
}));
|
||||
});
|
||||
*weak = dateBox.data();
|
||||
box->uiShow()->show(std::move(dateBox));
|
||||
});
|
||||
|
||||
Ui::AddSkip(container);
|
||||
|
@ -172,7 +184,7 @@ void SuggestOptions::edit() {
|
|||
const auto apply = [=](SuggestPostOptions values) {
|
||||
_values = values;
|
||||
updateTexts();
|
||||
_repaints.fire({});
|
||||
_updates.fire({});
|
||||
};
|
||||
const auto broadcast = _peer->monoforumBroadcast();
|
||||
const auto &appConfig = _peer->session().appConfig();
|
||||
|
@ -226,8 +238,8 @@ SuggestPostOptions SuggestOptions::values() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
rpl::producer<> SuggestOptions::repaints() const {
|
||||
return _repaints.events();
|
||||
rpl::producer<> SuggestOptions::updates() const {
|
||||
return _updates.events();
|
||||
}
|
||||
|
||||
rpl::lifetime &SuggestOptions::lifetime() {
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
[[nodiscard]] SuggestPostOptions values() const;
|
||||
|
||||
[[nodiscard]] rpl::producer<> repaints() const;
|
||||
[[nodiscard]] rpl::producer<> updates() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime();
|
||||
|
||||
|
@ -44,7 +44,7 @@ private:
|
|||
Ui::Text::String _text;
|
||||
|
||||
SuggestPostOptions _values;
|
||||
rpl::event_stream<> _repaints;
|
||||
rpl::event_stream<> _updates;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue