mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 23:24:01 +02:00
Added initial implementation of editing of scheduled text messages.
This commit is contained in:
parent
8320feea10
commit
0a4f3f310c
4 changed files with 138 additions and 5 deletions
|
@ -33,6 +33,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using MessageToEdit = ComposeControls::MessageToEdit;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class FieldHeader : public Ui::RpWidget {
|
class FieldHeader : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
FieldHeader(QWidget *parent, not_null<Data::Session*> data);
|
FieldHeader(QWidget *parent, not_null<Data::Session*> data);
|
||||||
|
@ -42,6 +48,7 @@ public:
|
||||||
bool isDisplayed() const;
|
bool isDisplayed() const;
|
||||||
bool isEditingMessage() const;
|
bool isEditingMessage() const;
|
||||||
rpl::producer<FullMsgId> editMsgId() const;
|
rpl::producer<FullMsgId> editMsgId() const;
|
||||||
|
MessageToEdit queryToEdit();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -81,7 +88,7 @@ FieldHeader::FieldHeader(QWidget *parent, not_null<Data::Session*> data)
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_cancel->addClickHandler([=] {
|
_cancel->addClickHandler([=] {
|
||||||
_editMsgId = nullptr;
|
_editMsgId = {};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +139,22 @@ rpl::producer<FullMsgId> FieldHeader::editMsgId() const {
|
||||||
return _editMsgId.value();
|
return _editMsgId.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageToEdit FieldHeader::queryToEdit() {
|
||||||
|
const auto item = _data->message(_editMsgId.current());
|
||||||
|
if (!isEditingMessage() || !item) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
item->fullId(),
|
||||||
|
{
|
||||||
|
item->isScheduled() ? item->date() : 0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ComposeControls::ComposeControls(
|
ComposeControls::ComposeControls(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
|
@ -202,12 +225,28 @@ rpl::producer<> ComposeControls::cancelRequests() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> ComposeControls::sendRequests() const {
|
rpl::producer<> ComposeControls::sendRequests() const {
|
||||||
|
auto filter = rpl::filter([=] {
|
||||||
|
return _send->type() == Ui::SendButton::Type::Schedule;
|
||||||
|
});
|
||||||
auto submits = base::qt_signal_producer(
|
auto submits = base::qt_signal_producer(
|
||||||
_field.get(),
|
_field.get(),
|
||||||
&Ui::InputField::submitted);
|
&Ui::InputField::submitted);
|
||||||
return rpl::merge(
|
return rpl::merge(
|
||||||
_send->clicks() | rpl::to_empty,
|
_send->clicks() | filter | rpl::to_empty,
|
||||||
std::move(submits) | rpl::to_empty);
|
std::move(submits) | filter | rpl::to_empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<MessageToEdit> ComposeControls::editRequests() const {
|
||||||
|
auto toValue = rpl::map([=] { return _header->queryToEdit(); });
|
||||||
|
auto filter = rpl::filter([=] {
|
||||||
|
return _send->type() == Ui::SendButton::Type::Save;
|
||||||
|
});
|
||||||
|
auto submits = base::qt_signal_producer(
|
||||||
|
_field.get(),
|
||||||
|
&Ui::InputField::submitted);
|
||||||
|
return rpl::merge(
|
||||||
|
_send->clicks() | filter | toValue,
|
||||||
|
std::move(submits) | filter | toValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> ComposeControls::attachRequests() const {
|
rpl::producer<> ComposeControls::attachRequests() const {
|
||||||
|
@ -307,12 +346,12 @@ void ComposeControls::init() {
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
|
|
||||||
_header->editMsgId(
|
_header->editMsgId(
|
||||||
) | rpl::start_with_next([=](auto item) {
|
) | rpl::start_with_next([=](auto id) {
|
||||||
updateHeight();
|
updateHeight();
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
|
|
||||||
if (_header->isEditingMessage()) {
|
if (_header->isEditingMessage()) {
|
||||||
setTextFromEditingMessage(item);
|
setTextFromEditingMessage(_window->session().data().message(id));
|
||||||
} else {
|
} else {
|
||||||
setText(_localSavedText);
|
setText(_localSavedText);
|
||||||
_localSavedText = {};
|
_localSavedText = {};
|
||||||
|
@ -552,7 +591,12 @@ void ComposeControls::updateHeight() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::editMessage(FullMsgId edit) {
|
void ComposeControls::editMessage(FullMsgId edit) {
|
||||||
|
cancelEditMessage();
|
||||||
_header->editMessage(std::move(edit));
|
_header->editMessage(std::move(edit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComposeControls::cancelEditMessage() {
|
||||||
|
_header->editMessage({});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "api/api_common.h"
|
||||||
#include "base/unique_qptr.h"
|
#include "base/unique_qptr.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
|
@ -54,6 +55,12 @@ public:
|
||||||
Scheduled,
|
Scheduled,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MessageToEdit {
|
||||||
|
FullMsgId fullId;
|
||||||
|
Api::SendOptions options;
|
||||||
|
TextWithTags textWithTags;
|
||||||
|
};
|
||||||
|
|
||||||
ComposeControls(
|
ComposeControls(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
|
@ -72,6 +79,7 @@ public:
|
||||||
void focus();
|
void focus();
|
||||||
[[nodiscard]] rpl::producer<> cancelRequests() const;
|
[[nodiscard]] rpl::producer<> cancelRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> sendRequests() const;
|
[[nodiscard]] rpl::producer<> sendRequests() const;
|
||||||
|
[[nodiscard]] rpl::producer<MessageToEdit> editRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> attachRequests() const;
|
[[nodiscard]] rpl::producer<> attachRequests() const;
|
||||||
[[nodiscard]] rpl::producer<not_null<DocumentData*>> fileChosen() const;
|
[[nodiscard]] rpl::producer<not_null<DocumentData*>> fileChosen() const;
|
||||||
[[nodiscard]] rpl::producer<not_null<PhotoData*>> photoChosen() const;
|
[[nodiscard]] rpl::producer<not_null<PhotoData*>> photoChosen() const;
|
||||||
|
@ -93,6 +101,7 @@ public:
|
||||||
void showFinished();
|
void showFinished();
|
||||||
|
|
||||||
void editMessage(FullMsgId edit);
|
void editMessage(FullMsgId edit);
|
||||||
|
void cancelEditMessage();
|
||||||
|
|
||||||
[[nodiscard]] TextWithTags getTextWithAppliedMarkdown() const;
|
[[nodiscard]] TextWithTags getTextWithAppliedMarkdown() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -17,10 +17,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "ui/text_options.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "api/api_common.h"
|
#include "api/api_common.h"
|
||||||
|
#include "api/api_editing.h"
|
||||||
#include "api/api_sending.h"
|
#include "api/api_sending.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -34,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
#include "storage/storage_media_prepare.h"
|
#include "storage/storage_media_prepare.h"
|
||||||
#include "storage/storage_account.h"
|
#include "storage/storage_account.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
|
@ -163,6 +166,15 @@ void ScheduledWidget::setupComposeControls() {
|
||||||
send();
|
send();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
_composeControls->editRequests(
|
||||||
|
) | rpl::start_with_next([=](auto data) {
|
||||||
|
if (const auto item = session().data().message(data.fullId)) {
|
||||||
|
if (item->isScheduled()) {
|
||||||
|
edit(item, data.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
_composeControls->attachRequests(
|
_composeControls->attachRequests(
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
return !_choosingAttach;
|
return !_choosingAttach;
|
||||||
|
@ -506,6 +518,71 @@ void ScheduledWidget::send(Api::SendOptions options) {
|
||||||
_composeControls->focus();
|
_composeControls->focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScheduledWidget::edit(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
Api::SendOptions options) {
|
||||||
|
|
||||||
|
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
|
_history,
|
||||||
|
session().user()).flags;
|
||||||
|
auto sending = TextWithEntities();
|
||||||
|
auto left = TextWithEntities {
|
||||||
|
textWithTags.text,
|
||||||
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
|
||||||
|
TextUtilities::PrepareForSending(left, prepareFlags);
|
||||||
|
|
||||||
|
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||||
|
if (item) {
|
||||||
|
Ui::show(Box<DeleteMessagesBox>(item, false));
|
||||||
|
} else {
|
||||||
|
_composeControls->focus();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (!left.text.isEmpty()) {
|
||||||
|
Ui::show(Box<InformBox>(tr::lng_edit_too_long(tr::now)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto saveEditMsgRequestId = lifetime().make_state<mtpRequestId>(0);
|
||||||
|
|
||||||
|
const auto done = [=](const MTPUpdates &result, mtpRequestId requestId) {
|
||||||
|
if (requestId == *saveEditMsgRequestId) {
|
||||||
|
*saveEditMsgRequestId = 0;
|
||||||
|
_composeControls->cancelEditMessage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto fail = [=](const RPCError &error, mtpRequestId requestId) {
|
||||||
|
if (requestId == *saveEditMsgRequestId) {
|
||||||
|
*saveEditMsgRequestId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &err = error.type();
|
||||||
|
if (ranges::contains(Api::kDefaultEditMessagesErrors, err)) {
|
||||||
|
Ui::show(Box<InformBox>(tr::lng_edit_error(tr::now)));
|
||||||
|
} else if (err == u"MESSAGE_NOT_MODIFIED"_q) {
|
||||||
|
_composeControls->cancelEditMessage();
|
||||||
|
} else if (err == u"MESSAGE_EMPTY"_q) {
|
||||||
|
_composeControls->focus();
|
||||||
|
} else {
|
||||||
|
Ui::show(Box<InformBox>(tr::lng_edit_error(tr::now)));
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
*saveEditMsgRequestId = Api::EditTextMessage(
|
||||||
|
item,
|
||||||
|
sending,
|
||||||
|
options,
|
||||||
|
crl::guard(this, done),
|
||||||
|
crl::guard(this, fail));
|
||||||
|
|
||||||
|
_composeControls->hidePanelsAnimated();
|
||||||
|
_composeControls->focus();
|
||||||
|
}
|
||||||
|
|
||||||
void ScheduledWidget::sendExistingDocument(
|
void ScheduledWidget::sendExistingDocument(
|
||||||
not_null<DocumentData*> document) {
|
not_null<DocumentData*> document) {
|
||||||
const auto callback = [=](Api::SendOptions options) {
|
const auto callback = [=](Api::SendOptions options) {
|
||||||
|
|
|
@ -141,6 +141,9 @@ private:
|
||||||
|
|
||||||
void send();
|
void send();
|
||||||
void send(Api::SendOptions options);
|
void send(Api::SendOptions options);
|
||||||
|
void edit(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
Api::SendOptions options);
|
||||||
void highlightSingleNewMessage(const Data::MessagesSlice &slice);
|
void highlightSingleNewMessage(const Data::MessagesSlice &slice);
|
||||||
void chooseAttach();
|
void chooseAttach();
|
||||||
[[nodiscard]] SendMenuType sendMenuType() const;
|
[[nodiscard]] SendMenuType sendMenuType() const;
|
||||||
|
|
Loading…
Add table
Reference in a new issue