diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 018d19573..091cf0610 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -757,6 +757,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_background_apply2" = "Enjoy the view."; "lng_background_apply_button" = "Apply For This Chat"; "lng_background_dimming" = "Background dimming"; +"lng_background_sure_reset_default" = "Are you sure you want to reset the wallpaper?"; +"lng_background_reset_default" = "Reset"; "lng_download_path_ask" = "Ask download path for each file"; "lng_download_path" = "Download path"; @@ -1348,6 +1350,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_report_group_video_title" = "Report group video"; "lng_report_channel_photo_title" = "Report channel photo"; "lng_report_channel_video_title" = "Report channel video"; +"lng_report_story" = "Report story"; "lng_report_please_select_messages" = "Please select messages to report."; "lng_report_select_messages" = "Select messages"; "lng_report_messages_none" = "Select Messages"; @@ -3822,6 +3825,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stories_reply_sent" = "Message Sent"; "lng_stories_hidden_to_contacts" = "Those stories are now shown only in your Contacts list."; "lng_stories_shown_in_chats" = "Those stories are now shown in your Chats list."; +"lng_stories_delete_one_sure" = "Are you sure you want to delete this story?"; +"lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?"; +"lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?"; "lng_stories_link_invalid" = "This link is broken or has expired."; diff --git a/Telegram/SourceFiles/api/api_report.cpp b/Telegram/SourceFiles/api/api_report.cpp index 7185b76f5..501870180 100644 --- a/Telegram/SourceFiles/api/api_report.cpp +++ b/Telegram/SourceFiles/api/api_report.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "data/data_peer.h" #include "data/data_photo.h" +#include "data/data_user.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "ui/boxes/report_box.h" @@ -39,11 +40,15 @@ MTPreportReason ReasonToTL(const Ui::ReportReason &reason) { } // namespace void SendReport( - std::shared_ptr show, - not_null peer, - Ui::ReportReason reason, - const QString &comment, - std::variant> data) { + std::shared_ptr show, + not_null peer, + Ui::ReportReason reason, + const QString &comment, + std::variant< + v::null_t, + MessageIdsList, + not_null, + StoryId> data) { auto done = [=] { show->showToast(tr::lng_report_thanks(tr::now)); }; @@ -72,6 +77,17 @@ void SendReport( ReasonToTL(reason), MTP_string(comment) )).done(std::move(done)).send(); + }, [&](StoryId id) { + const auto user = peer->asUser(); + if (!user) { + return; + } + peer->session().api().request(MTPstories_Report( + user->inputUser, + MTP_vector(1, MTP_int(id)), + ReasonToTL(reason), + MTP_string(comment) + )).done(std::move(done)).send(); }); } diff --git a/Telegram/SourceFiles/api/api_report.h b/Telegram/SourceFiles/api/api_report.h index 08535c00b..14e9d4ef1 100644 --- a/Telegram/SourceFiles/api/api_report.h +++ b/Telegram/SourceFiles/api/api_report.h @@ -22,6 +22,10 @@ void SendReport( not_null peer, Ui::ReportReason reason, const QString &comment, - std::variant> data); + std::variant< + v::null_t, + MessageIdsList, + not_null, + StoryId> data); } // namespace Api diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index e1262b4c9..a7b92aa32 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -282,9 +282,9 @@ void BackgroundBox::chosen(const Data::WallPaper &paper) { close(); }); _controller->show(Ui::MakeConfirmBox({ - .text = u"Are you sure you want to reset the wallpaper?"_q, + .text = tr::lng_background_sure_reset_default(), .confirmed = reset, - .confirmText = u"Reset"_q, + .confirmText = tr::lng_background_reset_default(), })); } else { closeBox(); diff --git a/Telegram/SourceFiles/boxes/report_messages_box.cpp b/Telegram/SourceFiles/boxes/report_messages_box.cpp index 291e0617b..5c8d59133 100644 --- a/Telegram/SourceFiles/boxes/report_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/report_messages_box.cpp @@ -14,12 +14,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/report_box.h" #include "ui/layers/generic_box.h" #include "window/window_session_controller.h" +#include "styles/style_chat_helpers.h" namespace { [[nodiscard]] object_ptr Report( not_null peer, - std::variant> data) { + std::variant< + v::null_t, + MessageIdsList, + not_null, + StoryId> data, + const style::ReportBox *stOverride) { const auto source = v::match(data, [](const MessageIdsList &ids) { return Ui::ReportSource::Message; }, [&](not_null photo) { @@ -34,15 +40,18 @@ namespace { : (photo->hasVideo() ? Ui::ReportSource::ChannelVideo : Ui::ReportSource::ChannelPhoto); + }, [&](StoryId id) { + return Ui::ReportSource::Story; }, [](v::null_t) { Unexpected("Bad source report."); return Ui::ReportSource::Bot; }); + const auto st = stOverride ? stOverride : &st::defaultReportBox; return Box([=](not_null box) { const auto show = box->uiShow(); - Ui::ReportReasonBox(box, source, [=](Ui::ReportReason reason) { + Ui::ReportReasonBox(box, *st, source, [=](Ui::ReportReason reason) { show->showBox(Box([=](not_null box) { - Ui::ReportDetailsBox(box, [=](const QString &text) { + Ui::ReportDetailsBox(box, *st, [=](const QString &text) { Api::SendReport(show, peer, reason, text, data); show->hideLayer(); }); @@ -56,13 +65,13 @@ namespace { object_ptr ReportItemsBox( not_null peer, MessageIdsList ids) { - return Report(peer, ids); + return Report(peer, ids, nullptr); } object_ptr ReportProfilePhotoBox( not_null peer, not_null photo) { - return Report(peer, photo); + return Report(peer, photo, nullptr); } void ShowReportPeerBox( @@ -93,17 +102,20 @@ void ShowReportPeerBox( if (reason == Ui::ReportReason::Fake || reason == Ui::ReportReason::Other) { state->ids = {}; - state->detailsBox = window->show(Box(Ui::ReportDetailsBox, send)); + state->detailsBox = window->show( + Box(Ui::ReportDetailsBox, st::defaultReportBox, send)); return; } window->showChooseReportMessages(peer, reason, [=]( MessageIdsList ids) { state->ids = std::move(ids); - state->detailsBox = window->show(Box(Ui::ReportDetailsBox, send)); + state->detailsBox = window->show( + Box(Ui::ReportDetailsBox, st::defaultReportBox, send)); }); }; state->reasonBox = window->show(Box( Ui::ReportReasonBox, + st::defaultReportBox, (peer->isBroadcast() ? Ui::ReportSource::Channel : peer->isUser() diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index e5552ead4..5c72090e0 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -206,6 +206,21 @@ ComposeControls { premium: PremiumLimits; } +ReportBox { + button: SettingsButton; + label: FlatLabel; + field: InputField; + spam: icon; + fake: icon; + violence: icon; + children: icon; + pornography: icon; + copyright: icon; + drugs: icon; + personal: icon; + other: icon; +} + WhoRead { userpics: GroupCallUserpics; photoLeft: pixels; @@ -1152,3 +1167,25 @@ moreChatsBarClose: IconButton(defaultIconButton) { color: windowBgOver; } } + +reportReasonTopSkip: 8px; +reportReasonButton: SettingsButton(defaultSettingsButton) { + style: boxTextStyle; + padding: margins(62px, 7px, 8px, 7px); + iconLeft: 22px; +} + +defaultReportBox: ReportBox { + button: reportReasonButton; + label: boxLabel; + field: newGroupDescription; + spam: menuIconDelete; + fake: menuIconFake; + violence: menuIconViolence; + children: menuIconBlock; + pornography: menuIconPorn; + copyright: menuIconCopyright; + drugs: menuIconDrugs; + personal: menuIconPersonal; + other: menuIconReport; +} diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index 525a0d200..1ebd7a1ed 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_stories.h" +#include "api/api_report.h" #include "base/unixtime.h" #include "api/api_text_entities.h" #include "apiwrap.h" @@ -223,6 +224,22 @@ bool Story::closeFriends() const { return _closeFriends; } +bool Story::canDownload() const { + return _peer->isSelf(); +} + +bool Story::canShare() const { + return isPublic() && (pinned() || !expired()); +} + +bool Story::canDelete() const { + return _peer->isSelf(); +} + +bool Story::canReport() const { + return !_peer->isSelf(); +} + bool Story::hasDirectLink() const { if (!_isPublic || (!_pinned && expired())) { return false; @@ -1479,7 +1496,38 @@ void Stories::savedLoadMore(PeerId peerId) { saved.total = int(saved.ids.list.size()); _savedChanged.fire_copy(peerId); }).send(); +} +void Stories::deleteList(const std::vector &ids) { + auto list = QVector(); + list.reserve(ids.size()); + const auto selfId = session().userPeerId(); + for (const auto &id : ids) { + if (id.peer == selfId) { + list.push_back(MTP_int(id.story)); + } + } + if (!list.empty()) { + const auto api = &_owner->session().api(); + api->request(MTPstories_DeleteStories( + MTP_vector(list) + )).done([=](const MTPVector &result) { + for (const auto &id : result.v) { + applyDeleted({ selfId, id.v }); + } + }).send(); + } +} + +void Stories::report( + std::shared_ptr show, + FullStoryId id, + Ui::ReportReason reason, + QString text) { + if (const auto maybeStory = lookup(id)) { + const auto story = *maybeStory; + Api::SendReport(show, story->peer(), reason, text, story->id()); + } } bool Stories::isQuitPrevent() { diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index d082d05a6..3199ff82f 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -23,6 +23,7 @@ class Session; namespace Ui { class Show; +enum class ReportReason; } // namespace Ui namespace Data { @@ -106,6 +107,11 @@ public: void setCloseFriends(bool closeFriends); [[nodiscard]] bool closeFriends() const; + [[nodiscard]] bool canDownload() const; + [[nodiscard]] bool canShare() const; + [[nodiscard]] bool canDelete() const; + [[nodiscard]] bool canReport() const; + [[nodiscard]] bool hasDirectLink() const; [[nodiscard]] std::optional errorTextForForward( not_null to) const; @@ -284,6 +290,13 @@ public: [[nodiscard]] bool savedLoaded(PeerId peerId) const; void savedLoadMore(PeerId peerId); + void deleteList(const std::vector &ids); + void report( + std::shared_ptr show, + FullStoryId id, + Ui::ReportReason reason, + QString text); + private: struct Saved { StoriesIds ids; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 8e50593be..e99b55c85 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -4009,7 +4009,8 @@ void HistoryWidget::reportSelectedMessages() { const auto reason = _chooseForReport->reason; const auto weak = Ui::MakeWeak(_list.data()); controller()->window().show(Box([=](not_null box) { - Ui::ReportDetailsBox(box, [=](const QString &text) { + const auto &st = st::defaultReportBox; + Ui::ReportDetailsBox(box, st, [=](const QString &text) { if (weak) { clearSelected(); controller()->clearChooseReportMessages(); diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index fcd649b38..b6958d4fa 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -885,10 +885,4 @@ shortInfoCover: ShortInfoCover { } } -reportReasonTopSkip: 8px; -reportReasonButton: SettingsButton(infoProfileButton) { - style: boxTextStyle; - padding: margins(62px, 7px, 8px, 7px); -} - permissionsExpandIcon: icon{{ "info/edit/expand_arrow_small", windowBoldFg }}; diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index 79828f7fc..bc7d0eaec 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -33,6 +33,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/stories/media_stories_share.h" #include "media/stories/media_stories_view.h" #include "media/audio/media_audio.h" +#include "ui/boxes/confirm_box.h" +#include "ui/boxes/report_box.h" #include "ui/effects/emoji_fly_animation.h" #include "ui/effects/message_sending_animation_common.h" #include "ui/effects/reaction_fly_animation.h" @@ -493,6 +495,11 @@ void Controller::initLayout() { }); } +Data::Story *Controller::story() const { + const auto maybeStory = _session->data().stories().lookup(_shown); + return maybeStory ? maybeStory->get() : nullptr; +} + not_null Controller::wrap() const { return _wrap; } @@ -995,25 +1002,6 @@ void Controller::setMenuShown(bool shown) { } } -bool Controller::canShare() const { - if (const auto maybeStory = _session->data().stories().lookup(_shown)) { - const auto story = *maybeStory; - const auto user = story->peer()->asUser(); - return story->isPublic() - && (story->pinned() || !story->expired()) - && (!user->username().isEmpty() - || !user->hasPrivateForwardName()); - } - return false; -} - -bool Controller::canDownload() const { - if (const auto maybeStory = _session->data().stories().lookup(_shown)) { - return (*maybeStory)->peer()->isSelf(); - } - return false; -} - void Controller::repaintSibling(not_null sibling) { if (sibling == _siblingLeft.get() || sibling == _siblingRight.get()) { _delegate->storiesRepaint(); @@ -1237,13 +1225,55 @@ void Controller::unfocusReply() { _wrap->setFocus(); } -void Controller::share() { +void Controller::shareRequested() { const auto show = _delegate->storiesShow(); if (auto box = PrepareShareBox(show, _shown)) { show->show(std::move(box)); } } +void Controller::deleteRequested() { + const auto story = this->story(); + if (!story) { + return; + } + const auto id = story->fullId(); + const auto owner = &story->owner(); + const auto confirmed = [=](Fn close) { + owner->stories().deleteList({ id }); + close(); + }; + uiShow()->show(Ui::MakeConfirmBox({ + .text = tr::lng_stories_delete_one_sure(), + .confirmed = confirmed, + .confirmText = tr::lng_selected_delete(), + .labelStyle = &st::storiesBoxLabel, + })); +} + +void Controller::reportRequested() { + const auto story = this->story(); + if (!story) { + return; + } + const auto id = story->fullId(); + const auto owner = &story->owner(); + const auto confirmed = [=](Fn close) { + owner->stories().deleteList({ id }); + close(); + }; + const auto show = uiShow(); + const auto st = &st::storiesReportBox; + show->show(Box(Ui::ReportReasonBox, *st, Ui::ReportSource::Story, [=]( + Ui::ReportReason reason) { + const auto done = [=](const QString &text) { + owner->stories().report(show, id, reason, text); + show->hideLayer(); + }; + show->showBox(Box(Ui::ReportDetailsBox, *st, done)); + })); +} + rpl::lifetime &Controller::lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 405960f39..a680d7f68 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -96,6 +96,7 @@ public: explicit Controller(not_null delegate); ~Controller(); + [[nodiscard]] Data::Story *story() const; [[nodiscard]] not_null wrap() const; [[nodiscard]] Layout layout() const; [[nodiscard]] rpl::producer layoutValue() const; @@ -123,9 +124,6 @@ public: void contentPressed(bool pressed); void setMenuShown(bool shown); - [[nodiscard]] bool canShare() const; - [[nodiscard]] bool canDownload() const; - void repaintSibling(not_null sibling); [[nodiscard]] SiblingView sibling(SiblingType type) const; @@ -133,7 +131,9 @@ public: [[nodiscard]] rpl::producer<> moreViewsLoaded() const; void unfocusReply(); - void share(); + void shareRequested(); + void deleteRequested(); + void reportRequested(); [[nodiscard]] rpl::lifetime &lifetime(); diff --git a/Telegram/SourceFiles/media/stories/media_stories_view.cpp b/Telegram/SourceFiles/media/stories/media_stories_view.cpp index 1b2747ee4..b79064e2e 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_view.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_view.cpp @@ -32,12 +32,8 @@ void View::ready() { _controller->ready(); } -bool View::canShare() const { - return _controller->canShare(); -} - -bool View::canDownload() const { - return _controller->canDownload(); +Data::Story *View::story() const { + return _controller->story(); } QRect View::finalShownGeometry() const { @@ -83,8 +79,16 @@ void View::contentPressed(bool pressed) { _controller->contentPressed(pressed); } -void View::share() { - _controller->share(); +void View::shareRequested() { + _controller->shareRequested(); +} + +void View::deleteRequested() { + _controller->deleteRequested(); +} + +void View::reportRequested() { + _controller->reportRequested(); } SiblingView View::sibling(SiblingType type) const { diff --git a/Telegram/SourceFiles/media/stories/media_stories_view.h b/Telegram/SourceFiles/media/stories/media_stories_view.h index ba138ac5d..dabb6952a 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_view.h +++ b/Telegram/SourceFiles/media/stories/media_stories_view.h @@ -56,8 +56,7 @@ public: void show(not_null story, Data::StoriesContext context); void ready(); - [[nodiscard]] bool canShare() const; - [[nodiscard]] bool canDownload() const; + [[nodiscard]] Data::Story *story() const; [[nodiscard]] QRect finalShownGeometry() const; [[nodiscard]] rpl::producer finalShownGeometryValue() const; [[nodiscard]] ContentLayout contentLayout() const; @@ -75,7 +74,10 @@ public: [[nodiscard]] bool paused() const; void togglePaused(bool paused); void contentPressed(bool pressed); - void share(); + + void shareRequested(); + void deleteRequested(); + void reportRequested(); [[nodiscard]] rpl::lifetime &lifetime(); diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index edc5bd517..85a2716d3 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -509,6 +509,9 @@ storiesPopupMenuWithIcons: PopupMenu(storiesPopupMenu) { menu: storiesMenuWithIcons; } +storiesBoxLabel: FlatLabel(boxLabel) { + textFg: groupCallMembersFg; +} storiesAttachEmojiInner: IconButton(storiesAttach) { icon: icon {{ "chat/input_smile_face", storiesComposeGrayIcon }}; iconOver: icon {{ "chat/input_smile_face", storiesComposeGrayIcon }}; @@ -520,9 +523,7 @@ storiesAttachEmoji: EmojiButton(historyAttachEmoji) { lineFgOver: storiesComposeGrayIcon; } storiesComposePremium: PremiumLimits(defaultPremiumLimits) { - boxLabel: FlatLabel(boxLabel) { - textFg: groupCallMembersFg; - } + boxLabel: storiesBoxLabel; nonPremiumBg: storiesComposeBgOver; nonPremiumFg: storiesComposeWhiteText; } @@ -588,9 +589,7 @@ storiesEmojiPan: EmojiPan(defaultEmojiPan) { } search: storiesEmojiTabbedSearch; removeSet: storiesRemoveSet; - boxLabel: FlatLabel(boxLabel) { - textFg: groupCallMembersFg; - } + boxLabel: storiesBoxLabel; icons: ComposeIcons { settings: icon {{ "emoji/emoji_settings", storiesComposeGrayIcon }}; @@ -642,6 +641,15 @@ storiesEmojiPan: EmojiPan(defaultEmojiPan) { } autocompleteBottomSkip: 10px; } +storiesBoxInputField: InputField(defaultComposeFilesField) { + textFg: storiesComposeWhiteText; + textBg: storiesComposeBg; + placeholderFg: storiesComposeGrayText; + placeholderFgActive: storiesComposeBlue; + borderFg: storiesComposeGrayText; + borderFgActive: storiesComposeBlue; + menu: storiesPopupMenu; +} storiesComposeControls: ComposeControls(defaultComposeControls) { bg: storiesComposeBg; radius: storiesRadius; @@ -718,15 +726,7 @@ storiesComposeControls: ComposeControls(defaultComposeControls) { iconOver: icon {{ "title_menu_dots", storiesComposeGrayIcon }}; ripple: storiesComposeRippleLight; } - caption: InputField(defaultComposeFilesField) { - textFg: storiesComposeWhiteText; - textBg: storiesComposeBg; - placeholderFg: storiesComposeGrayText; - placeholderFgActive: storiesComposeBlue; - borderFg: storiesComposeGrayText; - borderFgActive: storiesComposeBlue; - menu: storiesPopupMenu; - } + caption: storiesBoxInputField; emoji: EmojiButton(storiesAttachEmoji) { inner: IconButton(storiesAttachEmojiInner) { width: 30px; @@ -818,3 +818,26 @@ storiesShortInfoBox: ShortInfoBox(shortInfoBox) { palette: mediaviewTextPalette; } } +storiesReportBox: ReportBox(defaultReportBox) { + button: SettingsButton(reportReasonButton) { + textFg: storiesComposeWhiteText; + textFgOver: storiesComposeWhiteText; + textBg: storiesComposeBg; + textBgOver: storiesComposeBgOver; + ripple: storiesComposeRipple; + } + label: storiesBoxLabel; + field: InputField(storiesBoxInputField) { + textMargins: margins(1px, 26px, 1px, 4px); + heightMax: 116px; + } + spam: icon {{ "menu/delete", storiesComposeWhiteText }}; + fake: icon {{ "menu/fake", storiesComposeWhiteText }}; + violence: icon {{ "menu/violence", storiesComposeWhiteText }}; + children: icon {{ "menu/block", storiesComposeWhiteText }}; + pornography: icon {{ "menu/porn", storiesComposeWhiteText }}; + copyright: icon {{ "menu/copyright", storiesComposeWhiteText }}; + drugs: icon {{ "menu/drugs", storiesComposeWhiteText }}; + personal: icon {{ "menu/personal", storiesComposeWhiteText }}; + other: icon {{ "menu/report", storiesComposeWhiteText }}; +} diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index bb8d12a5b..30c1ae8aa 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -970,7 +970,8 @@ QSize OverlayWidget::flipSizeByRotation(QSize size) const { } bool OverlayWidget::hasCopyMediaRestriction() const { - return (_stories && !_stories->canDownload()) + const auto story = _stories ? _stories->story() : nullptr; + return (story && !story->canDownload()) || (_history && !_history->peer->allowsForwarding()) || (_message && _message->forbidsSaving()); } @@ -1223,12 +1224,13 @@ void OverlayWidget::updateControls() { updateThemePreviewGeometry(); + const auto story = _stories ? _stories->story() : nullptr; const auto overRect = QRect( QPoint(), QSize(st::mediaviewIconOver, st::mediaviewIconOver)); _saveVisible = contentCanBeSaved(); - _shareVisible = _stories && _stories->canShare(); - _rotateVisible = !_themePreviewShown && !_stories; + _shareVisible = story && story->canShare(); + _rotateVisible = !_themePreviewShown && !story; const auto navRect = [&](int i) { return QRect(width() - st::mediaviewIconSize.width() * i, height() - st::mediaviewIconSize.height(), @@ -1364,7 +1366,8 @@ void OverlayWidget::refreshCaptionGeometry() { } void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { - if (_document && _document->loading()) { + const auto story = _stories ? _stories->story() : nullptr; + if (!story && _document && _document->loading()) { addAction( tr::lng_cancel(tr::now), [=] { saveCancel(); }, @@ -1376,7 +1379,9 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { [=] { toMessage(); }, &st::mediaMenuIconShowInChat); } - if (_document && !_document->filepath(true).isEmpty()) { + if ((!story || story->canDownload()) + && _document + && !_document->filepath(true).isEmpty()) { const auto text = Platform::IsMac() ? tr::lng_context_show_in_finder(tr::now) : tr::lng_context_show_in_folder(tr::now); @@ -1406,8 +1411,15 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { [=] { forwardMedia(); }, &st::mediaMenuIconForward); } + if (story && story->canShare()) { + addAction(tr::lng_mediaview_forward(tr::now), [=] { + _stories->shareRequested(); + }, &st::mediaMenuIconForward); + } const auto canDelete = [&] { - if (_message && _message->canDelete()) { + if (story && story->canDelete()) { + return true; + } else if (_message && _message->canDelete()) { return true; } else if (!_message && _photo @@ -1527,6 +1539,11 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { } }, &st::mediaMenuIconReport); }(); + if (story && story->canReport()) { + addAction(tr::lng_profile_report(tr::now), [=] { + _stories->reportRequested(); + }, &st::mediaMenuIconReport); + } } auto OverlayWidget::computeOverviewType() const @@ -2433,7 +2450,10 @@ void OverlayWidget::forwardMedia() { } void OverlayWidget::deleteMedia() { - if (!_session) { + if (_stories) { + _stories->deleteRequested(); + return; + } else if (!_session) { return; } @@ -5521,7 +5541,7 @@ void OverlayWidget::handleMouseRelease( } else if (_over == Over::Save && _down == Over::Save) { downloadMedia(); } else if (_over == Over::Share && _down == Over::Share && _stories) { - _stories->share(); + _stories->shareRequested(); } else if (_over == Over::Rotate && _down == Over::Rotate) { playbackControlsRotate(); } else if (_over == Over::Icon && _down == Over::Icon) { diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 1ccafbc6f..7509f2c0e 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -2102,3 +2102,4 @@ stories.incrementStoryViews#22126127 user_id:InputUser id:Vector = Bool; stories.getStoryViewsList#4b3b5e97 id:int offset_date:int offset_id:long limit:int = stories.StoryViewsList; stories.getStoriesViews#9a75d6a6 id:Vector = stories.StoryViews; stories.exportStoryLink#16e443ce user_id:InputUser id:int = ExportedStoryLink; +stories.report#c95be06a user_id:InputUser id:Vector reason:ReportReason message:string = Bool; diff --git a/Telegram/SourceFiles/ui/boxes/report_box.cpp b/Telegram/SourceFiles/ui/boxes/report_box.cpp index 97fd61120..fa0ac22ff 100644 --- a/Telegram/SourceFiles/ui/boxes/report_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/report_box.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/input_fields.h" #include "ui/toast/toast.h" #include "info/profile/info_profile_icon.h" +#include "styles/style_chat_helpers.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_profile.h" @@ -32,6 +33,7 @@ using Reason = ReportReason; void ReportReasonBox( not_null box, + const style::ReportBox &st, ReportSource source, Fn done) { box->setTitle([&] { @@ -50,28 +52,27 @@ void ReportReasonBox( return tr::lng_report_channel_photo_title(); case Source::ChannelVideo: return tr::lng_report_channel_video_title(); + case Source::Story: + return tr::lng_report_story(); } Unexpected("'source' in ReportReasonBox."); }()); - const auto isProfileSource = (source == Source::ProfilePhoto) - || (source == Source::ProfileVideo); auto margin = style::margins{ 0, st::reportReasonTopSkip, 0, 0 }; const auto add = [&]( Reason reason, tr::phrase<> text, const style::icon &icon) { - const auto &st = st::reportReasonButton; const auto layout = box->verticalLayout(); const auto button = layout->add( - object_ptr(layout.get(), text(), st), + object_ptr(layout.get(), text(), st.button), margin); margin = {}; button->setClickedCallback([=] { done(reason); }); - const auto height = st.padding.top() - + st.height - + st.padding.bottom(); + const auto height = st.button.padding.top() + + st.button.height + + st.button.padding.bottom(); object_ptr( button, icon, @@ -80,49 +81,52 @@ void ReportReasonBox( (height - icon.height()) / 2, }); }; - add(Reason::Spam, tr::lng_report_reason_spam, st::menuIconDelete); - if (source != Source::Message && !isProfileSource) { - add(Reason::Fake, tr::lng_report_reason_fake, st::menuIconFake); + add(Reason::Spam, tr::lng_report_reason_spam, st.spam); + if (source == Source::Channel + || source == Source::Group + || source == Source::Bot) { + add(Reason::Fake, tr::lng_report_reason_fake, st.fake); } add( Reason::Violence, tr::lng_report_reason_violence, - st::menuIconViolence); + st.violence); add( Reason::ChildAbuse, tr::lng_report_reason_child_abuse, - st::menuIconBlock); + st.children); add( Reason::Pornography, tr::lng_report_reason_pornography, - st::menuIconPorn); + st.pornography); add( Reason::Copyright, tr::lng_report_reason_copyright, - st::menuIconCopyright); - if (source == Source::Message) { + st.copyright); + if (source == Source::Message || source == Source::Story) { add( Reason::IllegalDrugs, tr::lng_report_reason_illegal_drugs, - st::menuIconDrugs); + st.drugs); add( Reason::PersonalDetails, tr::lng_report_reason_personal_details, - st::menuIconPersonal); + st.personal); } - add(Reason::Other, tr::lng_report_reason_other, st::menuIconReport); + add(Reason::Other, tr::lng_report_reason_other, st.other); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); } void ReportDetailsBox( not_null box, + const style::ReportBox &st, Fn done) { box->addRow( object_ptr( box, // #TODO reports tr::lng_report_details_about(), - st::boxLabel), + st.label), { st::boxRowPadding.left(), st::boxPadding.top(), @@ -131,7 +135,7 @@ void ReportDetailsBox( const auto details = box->addRow( object_ptr( box, - st::newGroupDescription, + st.field, InputField::Mode::MultiLine, tr::lng_report_details(), QString())); diff --git a/Telegram/SourceFiles/ui/boxes/report_box.h b/Telegram/SourceFiles/ui/boxes/report_box.h index 61d17e612..fb462bad5 100644 --- a/Telegram/SourceFiles/ui/boxes/report_box.h +++ b/Telegram/SourceFiles/ui/boxes/report_box.h @@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +namespace style { +struct ReportBox; +} // namespace style + namespace Ui { class GenericBox; @@ -22,6 +26,7 @@ enum class ReportSource { GroupVideo, ChannelPhoto, ChannelVideo, + Story, }; enum class ReportReason { @@ -38,11 +43,13 @@ enum class ReportReason { void ReportReasonBox( not_null box, + const style::ReportBox &st, ReportSource source, Fn done); void ReportDetailsBox( not_null box, + const style::ReportBox &st, Fn done); } // namespace Ui