diff --git a/Telegram/Resources/icons/info/info_media_story_empty.png b/Telegram/Resources/icons/info/info_media_story_empty.png new file mode 100644 index 000000000..6196956ba Binary files /dev/null and b/Telegram/Resources/icons/info/info_media_story_empty.png differ diff --git a/Telegram/Resources/icons/info/info_media_story_empty@2x.png b/Telegram/Resources/icons/info/info_media_story_empty@2x.png new file mode 100644 index 000000000..c3e6997cd Binary files /dev/null and b/Telegram/Resources/icons/info/info_media_story_empty@2x.png differ diff --git a/Telegram/Resources/icons/info/info_media_story_empty@3x.png b/Telegram/Resources/icons/info/info_media_story_empty@3x.png new file mode 100644 index 000000000..b6422809d Binary files /dev/null and b/Telegram/Resources/icons/info/info_media_story_empty@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 328cc231a..018d19573 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3818,6 +3818,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stories_archive_button" = "Stories Archive"; "lng_stories_recent_button" = "Recent Stories"; "lng_stories_archive_title" = "Stories Archive"; +"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile."; "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."; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp index 24a97ae70..a0a8a8aaa 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp @@ -345,6 +345,7 @@ Content State::next() { .thumbnail = std::move(userpic), .unread = info.unread, .hidden = info.hidden, + .profile = true, .skipSmall = user->isSelf(), }); } @@ -419,7 +420,7 @@ rpl::producer LastForPeer(not_null peer) { return; } auto resolving = false; - auto result = Content(); + auto result = Content{ .full = true }; for (const auto id : ids) { const auto storyId = FullStoryId{ peerId, id }; const auto maybe = stories->lookup(storyId); diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp index b630d9b64..811fbc033 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp @@ -763,9 +763,11 @@ void List::contextMenuEvent(QContextMenuEvent *e) { const auto id = item.element.id; const auto hidden = item.element.hidden; - _menu->addAction(tr::lng_context_view_profile(tr::now), [=] { - _showProfileRequests.fire_copy(id); - }); + if (item.element.profile) { + _menu->addAction(tr::lng_context_view_profile(tr::now), [=] { + _showProfileRequests.fire_copy(id); + }); + } if (!_content.full || hidden) { _menu->addAction(hidden ? tr::lng_stories_show_in_chats(tr::now) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h index f81f90c05..a7826d892 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h @@ -36,6 +36,7 @@ struct Element { std::shared_ptr thumbnail; bool unread = false; bool hidden = false; + bool profile = false; bool skipSmall = false; friend inline bool operator==( diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index f2a9482cb..1b9d1fa4a 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -576,6 +576,7 @@ infoEmptyAudio: icon {{ "info/info_media_audio_empty", infoEmptyFg }}; infoEmptyFile: icon {{ "info/info_media_file_empty", infoEmptyFg }}; infoEmptyVoice: icon {{ "info/info_media_voice_empty", infoEmptyFg }}; infoEmptyLink: icon {{ "info/info_media_link_empty", infoEmptyFg }}; +infoEmptyStories: icon {{ "info/info_media_story_empty", infoEmptyFg }}; infoEmptyIconTop: 120px; infoEmptyLabelTop: 40px; infoEmptyLabelSkip: 20px; @@ -584,6 +585,14 @@ infoEmptyLabel: FlatLabel(defaultFlatLabel) { textFg: windowSubTextFg; } +infoStoriesAboutArchive: FlatLabel(defaultFlatLabel) { + minWidth: 245px; + align: align(top); + textFg: windowSubTextFg; + style: defaultTextStyle; +} +infoStoriesAboutArchivePadding: margins(22px, 8px, 22px, 16px); + editPeerBottomButtonsLayoutMargins: margins(0px, 7px, 0px, 0px); editPeerTopButtonsLayoutSkip: 13px; diff --git a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.cpp b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.cpp index 068da1c33..4f7af1f68 100644 --- a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.cpp +++ b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.cpp @@ -59,7 +59,7 @@ void EmptyWidget::setFullHeight(rpl::producer fullHeightValue) { ) | rpl::start_with_next([this](int fullHeight) { // Make icon center be on 1/3 height. auto iconCenter = fullHeight / 3; - auto iconHeight = st::infoEmptyFile.height(); + auto iconHeight = st::infoEmptyStories.height(); auto iconTop = iconCenter - iconHeight / 2; _height = iconTop + st::infoEmptyIconTop; resizeToWidth(width()); @@ -81,9 +81,9 @@ int EmptyWidget::resizeGetHeight(int newWidth) { void EmptyWidget::paintEvent(QPaintEvent *e) { auto p = QPainter(this); - const auto iconLeft = (width() - st::infoEmptyFile.width()) / 2; + const auto iconLeft = (width() - st::infoEmptyStories.width()) / 2; const auto iconTop = height() - st::infoEmptyIconTop; - st::infoEmptyFile.paint(p, iconLeft, iconTop, width()); + st::infoEmptyStories.paint(p, iconLeft, iconTop, width()); } InnerWidget::InnerWidget( @@ -99,28 +99,31 @@ InnerWidget::InnerWidget( _list = setupList(); } -void InnerWidget::setupArchive() { +void InnerWidget::setupTop() { const auto key = _controller->key(); const auto peer = key.storiesPeer(); if (peer && peer->isSelf() && key.storiesTab() == Stories::Tab::Saved && _isStackBottom) { - createArchiveButton(); + createButtons(); + } else if (key.storiesTab() == Stories::Tab::Archive) { + createAboutArchive(); } else { - _buttons.destroy(); + _top.destroy(); refreshHeight(); } } -void InnerWidget::createArchiveButton() { - _buttons.create(this); - _buttons->show(); +void InnerWidget::createButtons() { + _top.create(this); + _top->show(); + _topHeight = _top->heightValue(); const auto stories = &_controller->session().data().stories(); const auto self = _controller->session().user(); const auto archive = ::Settings::AddButton( - _buttons, + _top, tr::lng_stories_archive_button(), st::infoSharedMediaButton); archive->addClickHandler([=] { @@ -144,11 +147,11 @@ void InnerWidget::createArchiveButton() { st::infoIconMediaStoriesArchive, st::infoSharedMediaButtonIconPosition)->show(); - const auto recentWrap = _buttons->add( + const auto recentWrap = _top->add( object_ptr>( - _buttons, + _top, ::Settings::CreateButton( - _buttons, + _top, tr::lng_stories_recent_button(), st::infoSharedMediaButton))); @@ -204,16 +207,36 @@ void InnerWidget::createArchiveButton() { return !content.elements.empty(); })); - _buttons->add(object_ptr( - _buttons, + _top->add(object_ptr( + _top, st::infoProfileSkip)); - _buttons->add(object_ptr(_buttons)); + _top->add(object_ptr(_top)); - _buttons->resizeToWidth(width()); - _buttons->heightValue( + _top->resizeToWidth(width()); + _top->heightValue( ) | rpl::start_with_next([=] { refreshHeight(); - }, _buttons->lifetime()); + }, _top->lifetime()); +} + +void InnerWidget::createAboutArchive() { + _top.create(this); + _top->show(); + _topHeight = _top->heightValue(); + + _top->add(object_ptr( + _top, + object_ptr( + _top, + tr::lng_stories_archive_about(), + st::infoStoriesAboutArchive), + st::infoStoriesAboutArchivePadding)); + + _top->resizeToWidth(width()); + _top->heightValue( + ) | rpl::start_with_next([=] { + refreshHeight(); + }, _top->lifetime()); } void InnerWidget::visibleTopBottomUpdated( @@ -277,8 +300,8 @@ int InnerWidget::resizeGetHeight(int newWidth) { _inResize = true; auto guard = gsl::finally([this] { _inResize = false; }); - if (_buttons) { - _buttons->resizeToWidth(newWidth); + if (_top) { + _top->resizeToWidth(newWidth); } _list->resizeToWidth(newWidth); _empty->resizeToWidth(newWidth); @@ -294,9 +317,9 @@ void InnerWidget::refreshHeight() { int InnerWidget::recountHeight() { auto top = 0; - if (_buttons) { - _buttons->moveToLeft(0, top); - top += _buttons->heightNoMargins() - st::lineWidth; + if (_top) { + _top->moveToLeft(0, top); + top += _top->heightNoMargins() - st::lineWidth; } auto listHeight = 0; if (_list) { @@ -321,7 +344,8 @@ void InnerWidget::setScrollHeightValue(rpl::producer value) { _listTops.events_starting_with( _list->topValue() ) | rpl::flatten_latest(), - _1 - _2)); + _topHeight.value(), + _1 - _2 + _3)); } rpl::producer InnerWidget::scrollToRequests() const { diff --git a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h index 92814b72e..3e6819af9 100644 --- a/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h +++ b/Telegram/SourceFiles/info/stories/info_stories_inner_widget.h @@ -40,7 +40,7 @@ public: bool showInternal(not_null memento); void setIsStackBottom(bool isStackBottom) { _isStackBottom = isStackBottom; - setupArchive(); + setupTop(); } void saveState(not_null memento); @@ -64,14 +64,15 @@ private: int recountHeight(); void refreshHeight(); - void setupArchive(); - void createArchiveButton(); + void setupTop(); + void createButtons(); + void createAboutArchive(); object_ptr setupList(); const not_null _controller; - object_ptr _buttons = { nullptr }; + object_ptr _top = { nullptr }; object_ptr _list = { nullptr }; object_ptr _empty; @@ -81,6 +82,7 @@ private: rpl::event_stream _scrollToRequests; rpl::event_stream> _selectedLists; rpl::event_stream> _listTops; + rpl::variable _topHeight; };