mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
Allow fully editing todo lists.
This commit is contained in:
parent
d83a80ec53
commit
9290c90bdc
17 changed files with 204 additions and 42 deletions
|
@ -273,8 +273,6 @@ PRIVATE
|
|||
boxes/connection_box.h
|
||||
boxes/create_poll_box.cpp
|
||||
boxes/create_poll_box.h
|
||||
boxes/create_todo_list_box.cpp
|
||||
boxes/create_todo_list_box.h
|
||||
boxes/delete_messages_box.cpp
|
||||
boxes/delete_messages_box.h
|
||||
boxes/dictionaries_manager.cpp
|
||||
|
@ -285,6 +283,8 @@ PRIVATE
|
|||
boxes/edit_caption_box.h
|
||||
boxes/edit_privacy_box.cpp
|
||||
boxes/edit_privacy_box.h
|
||||
boxes/edit_todo_list_box.cpp
|
||||
boxes/edit_todo_list_box.h
|
||||
boxes/gift_credits_box.cpp
|
||||
boxes/gift_credits_box.h
|
||||
boxes/gift_premium_box.cpp
|
||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_file_origin.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_todo_list.h"
|
||||
#include "data/data_web_page.h"
|
||||
#include "history/view/controls/history_view_compose_media_edit_manager.h"
|
||||
#include "history/history.h"
|
||||
|
@ -358,4 +359,22 @@ mtpRequestId EditTextMessage(
|
|||
std::nullopt);
|
||||
}
|
||||
|
||||
void EditTodoList(
|
||||
not_null<HistoryItem*> item,
|
||||
const TodoListData &data,
|
||||
SendOptions options,
|
||||
Fn<void(mtpRequestId requestId)> done,
|
||||
Fn<void(const QString &error, mtpRequestId requestId)> fail) {
|
||||
const auto callback = [=](Fn<void()> applyUpdates, mtpRequestId id) {
|
||||
applyUpdates();
|
||||
done(id);
|
||||
};
|
||||
EditMessage(
|
||||
item,
|
||||
options,
|
||||
callback,
|
||||
fail,
|
||||
MTP_inputMediaTodo(TodoListDataToMTP(&data)));
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
|
|
@ -58,4 +58,11 @@ mtpRequestId EditTextMessage(
|
|||
Fn<void(const QString &error, mtpRequestId requestId)> fail,
|
||||
bool spoilered);
|
||||
|
||||
void EditTodoList(
|
||||
not_null<HistoryItem*> item,
|
||||
const TodoListData &data,
|
||||
SendOptions options,
|
||||
Fn<void(mtpRequestId requestId)> done,
|
||||
Fn<void(const QString &error, mtpRequestId requestId)> fail);
|
||||
|
||||
} // namespace Api
|
||||
|
|
|
@ -7,8 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "api/api_todo_lists.h"
|
||||
|
||||
//#include "api/api_common.h"
|
||||
//#include "api/api_updates.h"
|
||||
#include "api/api_editing.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/random.h"
|
||||
#include "data/business/data_shortcut_messages.h" // ShortcutIdToMTP
|
||||
|
@ -134,6 +133,23 @@ void TodoLists::create(
|
|||
});
|
||||
}
|
||||
|
||||
void TodoLists::edit(
|
||||
not_null<HistoryItem*> item,
|
||||
const TodoListData &data,
|
||||
SendOptions options,
|
||||
Fn<void()> done,
|
||||
Fn<void(QString)> fail) {
|
||||
EditTodoList(item, data, options, [=](mtpRequestId) {
|
||||
if (const auto onstack = done) {
|
||||
onstack();
|
||||
}
|
||||
}, [=](const QString &error, mtpRequestId) {
|
||||
if (const auto onstack = fail) {
|
||||
onstack(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void TodoLists::add(
|
||||
not_null<HistoryItem*> item,
|
||||
const std::vector<TodoListItem> &items,
|
||||
|
|
|
@ -22,6 +22,7 @@ class Session;
|
|||
namespace Api {
|
||||
|
||||
struct SendAction;
|
||||
struct SendOptions;
|
||||
|
||||
class TodoLists final {
|
||||
public:
|
||||
|
@ -32,6 +33,12 @@ public:
|
|||
SendAction action,
|
||||
Fn<void()> done,
|
||||
Fn<void(QString)> fail);
|
||||
void edit(
|
||||
not_null<HistoryItem*> item,
|
||||
const TodoListData &data,
|
||||
SendOptions options,
|
||||
Fn<void()> done,
|
||||
Fn<void(QString)> fail);
|
||||
void add(
|
||||
not_null<HistoryItem*> item,
|
||||
const std::vector<TodoListItem> &items,
|
||||
|
|
|
@ -5,7 +5,7 @@ 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 "boxes/create_todo_list_box.h"
|
||||
#include "boxes/edit_todo_list_box.h"
|
||||
|
||||
#include "base/call_delayed.h"
|
||||
#include "base/event_filter.h"
|
||||
|
@ -85,7 +85,6 @@ private:
|
|||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Main::Session*> session,
|
||||
int id,
|
||||
TextWithEntities text,
|
||||
int position,
|
||||
bool locked);
|
||||
|
||||
|
@ -144,7 +143,7 @@ private:
|
|||
int id,
|
||||
TextWithEntities text,
|
||||
anim::type animated);
|
||||
void initTaskField(not_null<Task*> task);
|
||||
void initTaskField(not_null<Task*> task, TextWithEntities text);
|
||||
void checkLastTask();
|
||||
void validateState();
|
||||
void fixAfterErase();
|
||||
|
@ -249,7 +248,6 @@ Tasks::Task::Task(
|
|||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Main::Session*> session,
|
||||
int id,
|
||||
TextWithEntities text,
|
||||
int position,
|
||||
bool locked)
|
||||
: _id(id)
|
||||
|
@ -270,11 +268,6 @@ Tasks::Task::Task(
|
|||
, _limit(session->appConfig().todoListItemTextLimit()) {
|
||||
InitField(outer, _field, session);
|
||||
_field->setMaxLength(_limit + kErrorLimit);
|
||||
_field->setTextWithTags({
|
||||
text.text,
|
||||
TextUtilities::ConvertEntitiesToTextTags(text.entities)
|
||||
});
|
||||
_field->finishAnimating();
|
||||
_field->show();
|
||||
if (locked) {
|
||||
_field->setDisabled(true);
|
||||
|
@ -487,7 +480,7 @@ Tasks::Tasks(
|
|||
for (const auto &task : existing) {
|
||||
addTask(task.id, task.text, anim::type::instant);
|
||||
}
|
||||
checkLastTask();
|
||||
validateState();
|
||||
}
|
||||
|
||||
bool Tasks::full() const {
|
||||
|
@ -539,10 +532,13 @@ std::vector<TodoListItem> Tasks::toTodoListItems() const {
|
|||
result.reserve(_list.size());
|
||||
auto usedId = 0;
|
||||
for (const auto &task : _list) {
|
||||
if (const auto id = task->id()) {
|
||||
usedId = id;
|
||||
} else if (task->isGood()) {
|
||||
++usedId;
|
||||
}
|
||||
if (task->isGood()) {
|
||||
result.push_back(task->toTodoListItem(++usedId));
|
||||
} else if (const auto id = task->id()) {
|
||||
usedId = std::max(usedId, id);
|
||||
result.push_back(task->toTodoListItem(usedId));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -646,17 +642,28 @@ void Tasks::addTask(
|
|||
_container,
|
||||
&_controller->session(),
|
||||
id,
|
||||
std::move(text),
|
||||
_position + _list.size() + _destroyed.size(),
|
||||
locked));
|
||||
const auto field = _list.back()->field();
|
||||
if (!locked) {
|
||||
initTaskField(_list.back().get());
|
||||
initTaskField(_list.back().get(), std::move(text));
|
||||
} else {
|
||||
InitMessageFieldHandlers(
|
||||
_controller,
|
||||
field,
|
||||
Window::GifPauseReason::Layer,
|
||||
[](not_null<DocumentData*>) { return true; });
|
||||
field->setTextWithTags({
|
||||
text.text,
|
||||
TextUtilities::ConvertEntitiesToTextTags(text.entities)
|
||||
});
|
||||
}
|
||||
field->finishAnimating();
|
||||
_list.back()->show(animated);
|
||||
fixShadows();
|
||||
}
|
||||
|
||||
void Tasks::initTaskField(not_null<Task*> task) {
|
||||
void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
|
||||
const auto field = task->field();
|
||||
if (const auto emojiPanel = _emojiPanel) {
|
||||
const auto emojiToggle = Ui::AddEmojiToggleToField(
|
||||
|
@ -686,6 +693,10 @@ void Tasks::initTaskField(not_null<Task*> task) {
|
|||
}, _emojiPanelLifetime);
|
||||
}, emojiToggle->lifetime());
|
||||
}
|
||||
field->setTextWithTags({
|
||||
text.text,
|
||||
TextUtilities::ConvertEntitiesToTextTags(text.entities)
|
||||
});
|
||||
field->submits(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto index = findField(field);
|
||||
|
@ -789,7 +800,7 @@ void Tasks::checkLastTask() {
|
|||
|
||||
} // namespace
|
||||
|
||||
CreateTodoListBox::CreateTodoListBox(
|
||||
EditTodoListBox::EditTodoListBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionController*> controller,
|
||||
rpl::producer<int> starsRequired,
|
||||
|
@ -802,25 +813,41 @@ CreateTodoListBox::CreateTodoListBox(
|
|||
, _titleLimit(controller->session().appConfig().todoListTitleLimit()) {
|
||||
}
|
||||
|
||||
auto CreateTodoListBox::submitRequests() const -> rpl::producer<Result> {
|
||||
EditTodoListBox::EditTodoListBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item)
|
||||
: _controller(controller)
|
||||
, _sendMenuDetails([] { return SendMenu::Details(); })
|
||||
, _editingItem(item)
|
||||
, _titleLimit(controller->session().appConfig().todoListTitleLimit()) {
|
||||
_controller->session().changes().messageUpdates(
|
||||
Data::MessageUpdate::Flag::Destroyed
|
||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||
if (update.item == item) {
|
||||
closeBox();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
auto EditTodoListBox::submitRequests() const -> rpl::producer<Result> {
|
||||
return _submitRequests.events();
|
||||
}
|
||||
|
||||
void CreateTodoListBox::setInnerFocus() {
|
||||
void EditTodoListBox::setInnerFocus() {
|
||||
_setInnerFocus();
|
||||
}
|
||||
|
||||
void CreateTodoListBox::submitFailed(const QString &error) {
|
||||
void EditTodoListBox::submitFailed(const QString &error) {
|
||||
showToast(error);
|
||||
}
|
||||
|
||||
not_null<Ui::InputField*> CreateTodoListBox::setupTitle(
|
||||
not_null<Ui::InputField*> EditTodoListBox::setupTitle(
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
using namespace Settings;
|
||||
|
||||
const auto session = &_controller->session();
|
||||
const auto isPremium = session->premium();
|
||||
|
||||
const auto title = container->add(
|
||||
object_ptr<Ui::InputField>(
|
||||
container,
|
||||
|
@ -860,6 +887,15 @@ not_null<Ui::InputField*> CreateTodoListBox::setupTitle(
|
|||
}, emojiToggle->lifetime());
|
||||
}
|
||||
|
||||
const auto media = _editingItem ? _editingItem->media() : nullptr;
|
||||
if (const auto todolist = media ? media->todolist() : nullptr) {
|
||||
const auto &text = todolist->title;
|
||||
title->setTextWithTags({
|
||||
text.text,
|
||||
TextUtilities::ConvertEntitiesToTextTags(text.entities)
|
||||
});
|
||||
}
|
||||
|
||||
const auto warning = CreateWarningLabel(
|
||||
container,
|
||||
title,
|
||||
|
@ -885,7 +921,7 @@ not_null<Ui::InputField*> CreateTodoListBox::setupTitle(
|
|||
return title;
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
||||
object_ptr<Ui::RpWidget> EditTodoListBox::setupContent() {
|
||||
using namespace Settings;
|
||||
|
||||
const auto id = FullMsgId{
|
||||
|
@ -906,11 +942,14 @@ object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
|||
tr::lng_todo_create_list(),
|
||||
st::defaultSubsectionTitle),
|
||||
st::createPollFieldTitlePadding);
|
||||
const auto media = _editingItem ? _editingItem->media() : nullptr;
|
||||
const auto todolist = media ? media->todolist() : nullptr;
|
||||
const auto tasks = lifetime().make_state<Tasks>(
|
||||
this,
|
||||
container,
|
||||
_controller,
|
||||
_emojiPanel ? _emojiPanel.get() : nullptr);
|
||||
_emojiPanel ? _emojiPanel.get() : nullptr,
|
||||
todolist ? todolist->items : std::vector<TodoListItem>());
|
||||
auto limit = tasks->addedCount() | rpl::after_next([=](int count) {
|
||||
setCloseByEscape(!count);
|
||||
setCloseByOutsideClick(!count);
|
||||
|
@ -944,14 +983,14 @@ object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
|||
object_ptr<Ui::Checkbox>(
|
||||
container,
|
||||
tr::lng_todo_create_allow_add(tr::now),
|
||||
true,
|
||||
!todolist || todolist->othersCanAppend(),
|
||||
st::defaultCheckbox),
|
||||
st::createPollCheckboxMargin);
|
||||
const auto allowMark = container->add(
|
||||
object_ptr<Ui::Checkbox>(
|
||||
container,
|
||||
tr::lng_todo_create_allow_mark(tr::now),
|
||||
true,
|
||||
!todolist || todolist->othersCanComplete(),
|
||||
st::defaultCheckbox),
|
||||
st::createPollCheckboxMargin);
|
||||
|
||||
|
@ -1019,6 +1058,14 @@ object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
|||
showError(tr::lng_todo_choose_tasks);
|
||||
tasks->focusFirst();
|
||||
} else if (!*error) {
|
||||
if (_editingItem) {
|
||||
sendOptions = {
|
||||
.scheduled = (_editingItem->isScheduled()
|
||||
? _editingItem->date()
|
||||
: TimeId()),
|
||||
.shortcutId = _editingItem->shortcutId(),
|
||||
};
|
||||
}
|
||||
_submitRequests.fire({ collectResult(), sendOptions });
|
||||
}
|
||||
};
|
||||
|
@ -1043,9 +1090,13 @@ object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
|||
_sendMenuDetails());
|
||||
};
|
||||
const auto submit = addButton(
|
||||
tr::lng_todo_create_button(),
|
||||
(_editingItem
|
||||
? tr::lng_settings_save()
|
||||
: tr::lng_todo_create_button()),
|
||||
[=] { isNormal ? send({}) : schedule(); });
|
||||
submit->setText(PaidSendButtonText(_starsRequired.value(), isNormal
|
||||
submit->setText(PaidSendButtonText(_starsRequired.value(), _editingItem
|
||||
? tr::lng_settings_save()
|
||||
: isNormal
|
||||
? tr::lng_todo_create_button()
|
||||
: tr::lng_schedule_button()));
|
||||
const auto sendMenuDetails = [=] {
|
||||
|
@ -1062,7 +1113,7 @@ object_ptr<Ui::RpWidget> CreateTodoListBox::setupContent() {
|
|||
return result;
|
||||
}
|
||||
|
||||
void CreateTodoListBox::prepare() {
|
||||
void EditTodoListBox::prepare() {
|
||||
setTitle(tr::lng_todo_create_title());
|
||||
|
||||
const auto inner = setInnerWidget(setupContent());
|
|
@ -30,19 +30,23 @@ namespace SendMenu {
|
|||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
class CreateTodoListBox : public Ui::BoxContent {
|
||||
class EditTodoListBox : public Ui::BoxContent {
|
||||
public:
|
||||
struct Result {
|
||||
TodoListData todolist;
|
||||
Api::SendOptions options;
|
||||
};
|
||||
|
||||
CreateTodoListBox(
|
||||
EditTodoListBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionController*> controller,
|
||||
rpl::producer<int> starsRequired,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Details sendMenuDetails);
|
||||
EditTodoListBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item);
|
||||
|
||||
[[nodiscard]] rpl::producer<Result> submitRequests() const;
|
||||
void submitFailed(const QString &error);
|
||||
|
@ -68,6 +72,7 @@ private:
|
|||
const not_null<Window::SessionController*> _controller;
|
||||
const Api::SendType _sendType = Api::SendType();
|
||||
const Fn<SendMenu::Details()> _sendMenuDetails;
|
||||
HistoryItem *_editingItem = nullptr;
|
||||
rpl::variable<int> _starsRequired;
|
||||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||
Fn<void()> _setInnerFocus;
|
|
@ -2367,6 +2367,10 @@ TextForMimeData MediaTodoList::clipboardText() const {
|
|||
return TextForMimeData::Rich(std::move(result));
|
||||
}
|
||||
|
||||
bool MediaTodoList::allowsEdit() const {
|
||||
return parent()->out();
|
||||
}
|
||||
|
||||
bool MediaTodoList::updateInlineResultMedia(const MTPMessageMedia &media) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -625,6 +625,7 @@ public:
|
|||
TextWithEntities notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
TextForMimeData clipboardText() const override;
|
||||
bool allowsEdit() const override;
|
||||
|
||||
bool updateInlineResultMedia(const MTPMessageMedia &media) override;
|
||||
bool updateSentMedia(const MTPMessageMedia &media) override;
|
||||
|
|
|
@ -685,7 +685,8 @@ bool PeerData::canCreatePolls() const {
|
|||
}
|
||||
|
||||
bool PeerData::canCreateTodoLists() const {
|
||||
return Data::CanSend(this, ChatRestriction::SendPolls) || isUser();
|
||||
return session().premium()
|
||||
&& (Data::CanSend(this, ChatRestriction::SendPolls) || isUser());
|
||||
}
|
||||
|
||||
bool PeerData::canCreateTopics() const {
|
||||
|
|
|
@ -8559,6 +8559,11 @@ void HistoryWidget::editMessage(
|
|||
} else if (_voiceRecordBar->isActive()) {
|
||||
controller()->showToast(tr::lng_edit_caption_voice(tr::now));
|
||||
return;
|
||||
} else if (const auto media = item->media()) {
|
||||
if (const auto todolist = media->todolist()) {
|
||||
Window::PeerMenuEditTodoList(controller(), item);
|
||||
return;
|
||||
}
|
||||
} else if (_composeSearch) {
|
||||
_composeSearch->hideAnimated();
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/spoiler_mess.h"
|
||||
#include "webrtc/webrtc_environment.h"
|
||||
#include "window/window_adaptive.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "mainwindow.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
@ -2952,6 +2953,12 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
|||
if (_voiceRecordBar->isActive()) {
|
||||
_show->showBox(Ui::MakeInformBox(tr::lng_edit_caption_voice()));
|
||||
return;
|
||||
} else if (const auto media = item->media()) {
|
||||
if (const auto todolist = media->todolist()) {
|
||||
Assert(_regularWindow != nullptr);
|
||||
Window::PeerMenuEditTodoList(_regularWindow, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEditingMessage()) {
|
||||
|
|
|
@ -352,6 +352,8 @@ ChatWidget::ChatWidget(
|
|||
_composeControls->editMessage(
|
||||
fullId,
|
||||
_inner->getSelectedTextRange(item));
|
||||
} else if (media->todolist()) {
|
||||
Window::PeerMenuEditTodoList(controller, item);
|
||||
}
|
||||
}
|
||||
}, _inner->lifetime());
|
||||
|
|
|
@ -231,6 +231,8 @@ ScheduledWidget::ScheduledWidget(
|
|||
_composeControls->editMessage(
|
||||
fullId,
|
||||
_inner->getSelectedTextRange(item));
|
||||
} else if (media->todolist()) {
|
||||
Window::PeerMenuEditTodoList(controller, item);
|
||||
}
|
||||
}
|
||||
}, _inner->lifetime());
|
||||
|
|
|
@ -58,6 +58,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/painter.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
@ -399,6 +400,8 @@ ShortcutMessages::ShortcutMessages(
|
|||
_composeControls->editMessage(
|
||||
fullId,
|
||||
_inner->getSelectedTextRange(item));
|
||||
} else if (media->todolist()) {
|
||||
Window::PeerMenuEditTodoList(_controller, item);
|
||||
}
|
||||
}
|
||||
}, _inner->lifetime());
|
||||
|
|
|
@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/moderate_messages_box.h"
|
||||
#include "boxes/choose_filter_box.h"
|
||||
#include "boxes/create_poll_box.h"
|
||||
#include "boxes/create_todo_list_box.h"
|
||||
#include "boxes/edit_todo_list_box.h"
|
||||
#include "boxes/pin_messages_box.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
#include "boxes/report_messages_box.h"
|
||||
|
@ -1244,7 +1244,8 @@ void Filler::addCreateTodoList() {
|
|||
return;
|
||||
}
|
||||
const auto can = _topic
|
||||
? Data::CanSend(_topic, ChatRestriction::SendPolls)
|
||||
? (_peer->session().premium()
|
||||
&& Data::CanSend(_topic, ChatRestriction::SendPolls))
|
||||
: _peer->canCreateTodoLists();
|
||||
if (!can) {
|
||||
return;
|
||||
|
@ -1973,19 +1974,19 @@ void PeerMenuCreateTodoList(
|
|||
) | rpl::map([=] {
|
||||
return peer->starsPerMessageChecked();
|
||||
});
|
||||
auto box = Box<CreateTodoListBox>(
|
||||
auto box = Box<EditTodoListBox>(
|
||||
controller,
|
||||
std::move(starsRequired),
|
||||
sendType,
|
||||
sendMenuDetails);
|
||||
struct State {
|
||||
Fn<void(const CreateTodoListBox::Result &)> create;
|
||||
Fn<void(const EditTodoListBox::Result &)> create;
|
||||
SendPaymentHelper sendPayment;
|
||||
bool lock = false;
|
||||
};
|
||||
const auto weak = QPointer<CreateTodoListBox>(box);
|
||||
const auto weak = QPointer<EditTodoListBox>(box);
|
||||
const auto state = box->lifetime().make_state<State>();
|
||||
state->create = [=](const CreateTodoListBox::Result &result) {
|
||||
state->create = [=](const EditTodoListBox::Result &result) {
|
||||
const auto withPaymentApproved = crl::guard(weak, [=](int stars) {
|
||||
if (const auto onstack = state->create) {
|
||||
auto copy = result;
|
||||
|
@ -2028,6 +2029,34 @@ void PeerMenuCreateTodoList(
|
|||
controller->show(std::move(box), Ui::LayerOption::CloseOther);
|
||||
}
|
||||
|
||||
void PeerMenuEditTodoList(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto media = item->media();
|
||||
const auto todolist = media ? media->todolist() : nullptr;
|
||||
if (!todolist) {
|
||||
return;
|
||||
} else if (!item->history()->session().premium()) {
|
||||
PeerMenuTodoWantsPremium(TodoWantsPremium::Add);
|
||||
return;
|
||||
}
|
||||
auto box = Box<EditTodoListBox>(controller, item);
|
||||
const auto weak = QPointer<EditTodoListBox>(box);
|
||||
box->submitRequests(
|
||||
) | rpl::start_with_next([=](const EditTodoListBox::Result &result) {
|
||||
const auto api = &item->history()->session().api();
|
||||
api->todoLists().edit(
|
||||
item,
|
||||
result.todolist,
|
||||
result.options,
|
||||
crl::guard(weak, [=] { weak->closeBox(); }),
|
||||
crl::guard(weak, [=](const QString &error) {
|
||||
weak->submitFailed(error);
|
||||
}));
|
||||
}, box->lifetime());
|
||||
controller->show(std::move(box), Ui::LayerOption::CloseOther);
|
||||
}
|
||||
|
||||
bool PeerMenuShowAddTodoListTasks(not_null<HistoryItem*> item) {
|
||||
const auto media = item ? item->media() : nullptr;
|
||||
const auto todolist = media ? media->todolist() : nullptr;
|
||||
|
|
|
@ -123,6 +123,9 @@ void PeerMenuCreateTodoList(
|
|||
FullReplyTo replyTo = FullReplyTo(),
|
||||
Api::SendType sendType = Api::SendType::Normal,
|
||||
SendMenu::Details sendMenuDetails = SendMenu::Details());
|
||||
void PeerMenuEditTodoList(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<HistoryItem*> item);
|
||||
[[nodiscard]] bool PeerMenuShowAddTodoListTasks(not_null<HistoryItem*> item);
|
||||
void PeerMenuAddTodoListTasks(
|
||||
not_null<Window::SessionController*> controller,
|
||||
|
|
Loading…
Add table
Reference in a new issue