diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index a7ee78c4f..344a975cd 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1241,6 +1241,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_send_button" = "Send"; "lng_send_silent_message" = "Send without sound"; "lng_schedule_message" = "Schedule message"; +"lng_schedule_title" = "Send this message on..."; +"lng_schedule_at" = "at"; "lng_message_ph" = "Write a message..."; "lng_broadcast_ph" = "Broadcast a message..."; "lng_broadcast_silent_ph" = "Silent broadcast..."; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index e49e49606..8a468fb23 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/emoji_suggestions_widget.h" #include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_selector.h" +#include "history/view/history_view_schedule_box.h" #include "core/file_utilities.h" #include "core/mime_type.h" #include "core/event_filter.h" @@ -1962,9 +1963,10 @@ void SendFilesBox::sendSilent() { } void SendFilesBox::sendScheduled() { - auto options = Api::SendOptions(); - options.scheduled = INT_MAX; - send(options); + Ui::show(Box(HistoryView::ScheduleBox, crl::guard(this, [=]( + Api::SendOptions options) { + send(options); + })), LayerOption::KeepOther); } SendFilesBox::~SendFilesBox() = default; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index c046768fb..c32cbef35 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/message_field.h" #include "history/history.h" #include "history/history_message.h" +#include "history/view/history_view_schedule_box.h" #include "window/themes/window_theme.h" #include "window/window_session_controller.h" #include "boxes/peer_list_box.h" @@ -468,9 +469,10 @@ void ShareBox::submitSilent() { } void ShareBox::submitScheduled() { - auto options = Api::SendOptions(); - options.scheduled = INT_MAX; - submit(options); + Ui::show(Box(HistoryView::ScheduleBox, crl::guard(this, [=]( + Api::SendOptions options) { + submit(options); + })), LayerOption::KeepOther); } void ShareBox::copyLink() { diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 1a38ade7d..7b37a1b4a 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -292,7 +292,18 @@ HistoryItem *ScheduledMessages::append( }); const auto i = list.itemById.find(id); if (i != end(list.itemById)) { - return i->second; + const auto existing = i->second; + message.match([&](const MTPDmessage &data) { + existing->updateSentContent({ + qs(data.vmessage()), + TextUtilities::EntitiesFromMTP( + data.ventities().value_or_empty()) + }, data.vmedia()); + existing->updateReplyMarkup(data.vreply_markup()); + existing->updateForwardedInfo(data.vfwd_from()); + history->owner().requestItemTextRefresh(existing); + }, [&](const auto &data) {}); + return existing; } const auto item = _session->data().addNewMessage( diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index 73cc577cd..92f38594d 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -591,3 +591,18 @@ largeEmojiSize: 36px; largeEmojiOutline: 1px; largeEmojiPadding: margins(0px, 0px, 0px, 0px); largeEmojiSkip: 4px; + +scheduleHeight: 120px; +scheduleDateTop: 44px; +scheduleDateField: InputField(defaultInputField) { + textMargins: margins(2px, 0px, 2px, 0px); + placeholderScale: 0.; + placeholderFont: normalFont; + heightMin: 24px; + font: normalFont; +} +scheduleDateWidth: 96px; +scheduleAtSkip: 24px; +scheduleAtTop: 48px; +scheduleAtLabel: FlatLabel(defaultFlatLabel) { +} diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index d0d8c2752..19d032be5 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -40,7 +40,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "history/history_item.h" #include "history/history_message.h" -#include "history/view/media/history_view_media.h" #include "history/history_drag_area.h" #include "history/history_inner_widget.h" #include "history/history_item_components.h" @@ -48,6 +47,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_service_message.h" #include "history/view/history_view_element.h" #include "history/view/history_view_scheduled_section.h" +#include "history/view/history_view_schedule_box.h" +#include "history/view/media/history_view_media.h" #include "profile/profile_block_group_members.h" #include "info/info_memento.h" #include "core/click_handler_types.h" @@ -2959,9 +2960,9 @@ void HistoryWidget::sendSilent() { } void HistoryWidget::sendScheduled() { - auto options = Api::SendOptions(); - options.scheduled = base::unixtime::now() + 86400; - send(options); + Ui::show(Box(HistoryView::ScheduleBox, [=](Api::SendOptions options) { + send(options); + })); } void HistoryWidget::unblockUser() { diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp new file mode 100644 index 000000000..87dc6a34e --- /dev/null +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp @@ -0,0 +1,96 @@ +/* +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 "history/view/history_view_schedule_box.h" + +#include "api/api_common.h" +#include "lang/lang_keys.h" +#include "base/unixtime.h" +#include "boxes/calendar_box.h" +#include "ui/widgets/input_fields.h" +#include "ui/widgets/labels.h" +#include "ui/wrap/padding_wrap.h" +#include "styles/style_history.h" + +namespace HistoryView { + +void ScheduleBox( + not_null box, + Fn done) { + box->setTitle(tr::lng_schedule_title()); + + const auto content = box->addRow( + object_ptr(box, st::scheduleHeight)); + const auto day = Ui::CreateChild( + content, + st::scheduleDateField); + const auto time = Ui::CreateChild( + content, + st::scheduleDateField); + const auto at = Ui::CreateChild( + content, + tr::lng_schedule_at(), + st::scheduleAtLabel); + + content->widthValue( + ) | rpl::start_with_next([=](int width) { + const auto paddings = width + - at->width() + - 2 * st::scheduleAtSkip + - 2 * st::scheduleDateWidth; + const auto left = paddings / 2; + day->resizeToWidth(st::scheduleDateWidth); + day->moveToLeft(left, st::scheduleDateTop, width); + at->moveToLeft( + left + st::scheduleDateWidth + st::scheduleAtSkip, + st::scheduleAtTop, + width); + time->resizeToWidth(st::scheduleDateWidth); + time->moveToLeft( + width - left - st::scheduleDateWidth, + st::scheduleDateTop, + width); + }, content->lifetime()); + + const auto save = [=] { + auto result = Api::SendOptions(); + + const auto dayValue = day->getLastText().trimmed(); + const auto dayMatch = QRegularExpression("(\\d\\d)\\.(\\d\\d)\\.(\\d\\d\\d\\d)").match(dayValue); + const auto timeValue = time->getLastText().trimmed(); + const auto timeMatch = QRegularExpression("(\\d\\d):(\\d\\d)").match(timeValue); + + if (!dayMatch.hasMatch()) { + day->showError(); + return; + } + + if (!timeMatch.hasMatch()) { + time->showError(); + return; + } + + const auto date = QDateTime( + QDate( + dayMatch.captured(3).toInt(), + dayMatch.captured(2).toInt(), + dayMatch.captured(1).toInt()), + QTime( + timeMatch.captured(1).toInt(), + timeMatch.captured(2).toInt())); + result.scheduled = date.toTime_t(); + + auto copy = done; + box->closeBox(); + copy(result); + }; + + box->addButton(tr::lng_settings_save(), save); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); +} + +} // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.h b/Telegram/SourceFiles/history/view/history_view_schedule_box.h new file mode 100644 index 000000000..51fe3fe7a --- /dev/null +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.h @@ -0,0 +1,20 @@ +/* +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 + +#include "boxes/generic_box.h" + +namespace Api { +struct SendOptions; +} // namespace Api + +namespace HistoryView { + +void ScheduleBox(not_null box, Fn done); + +} // namespace HistoryView diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index 437c6a2c9..fc3339fd4 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -331,6 +331,8 @@ <(src_loc)/history/view/history_view_message.cpp <(src_loc)/history/view/history_view_message.h <(src_loc)/history/view/history_view_object.h +<(src_loc)/history/view/history_view_schedule_box.cpp +<(src_loc)/history/view/history_view_schedule_box.h <(src_loc)/history/view/history_view_scheduled_section.cpp <(src_loc)/history/view/history_view_scheduled_section.h <(src_loc)/history/view/history_view_service_message.cpp