Added initial ability to open single typed shared media in window.

This commit is contained in:
23rd 2025-01-28 18:26:47 +03:00
parent bbdd5feaa4
commit d6ba6ac41e
8 changed files with 143 additions and 2 deletions

View file

@ -106,6 +106,8 @@ WrapWidget::WrapWidget(
Wrap wrap,
not_null<Memento*> memento)
: SectionWidget(parent, window, rpl::producer<PeerData*>())
, _isSeparatedWindow(
window->windowId().type == Window::SeparateType::SharedMedia)
, _wrap(wrap)
, _controller(createController(window, memento->content()))
, _topShadow(this)
@ -1044,7 +1046,8 @@ const Ui::RoundRect *WrapWidget::bottomSkipRounding() const {
}
bool WrapWidget::hasBackButton() const {
return (wrap() == Wrap::Narrow || hasStackHistory());
return !_isSeparatedWindow
&& (wrap() == Wrap::Narrow || hasStackHistory());
}
bool WrapWidget::willHaveBackButton(

View file

@ -208,6 +208,8 @@ private:
void addProfileCallsButton();
void showTopBarMenu(bool check);
const bool _isSeparatedWindow = false;
rpl::variable<Wrap> _wrap;
std::unique_ptr<Controller> _controller;
object_ptr<ContentWidget> _content = { nullptr };

View file

@ -96,7 +96,10 @@ inline auto AddButton(
Profile::SharedMediaCountValue(peer, topicRootId, migrated, type),
MediaText(type),
tracker)->entity();
result->addClickHandler([=] {
result->addClickHandler([=](Qt::MouseButton mouse) {
if (mouse == Qt::RightButton) {
return;
}
const auto topic = topicRootId
? peer->forumTopicFor(topicRootId)
: nullptr;

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "info/profile/info_profile_inner_widget.h"
#include "base/call_delayed.h"
#include "info/info_memento.h"
#include "info/info_controller.h"
#include "info/profile/info_profile_widget.h"
@ -29,11 +30,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "api/api_peer_photo.h"
#include "window/main_window.h"
#include "window/window_separate_id.h"
#include "window/window_session_controller.h"
#include "storage/storage_shared_media.h"
#include "lang/lang_keys.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/shadow.h"
#include "ui/widgets/box_content_divider.h"
@ -44,10 +47,79 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_shared_media.h"
#include "styles/style_info.h"
#include "styles/style_boxes.h"
#include "styles/style_menu_icons.h"
namespace Info {
namespace Profile {
namespace {
Window::SeparateSharedMediaType ToSeparateType(
Storage::SharedMediaType type) {
using Type = Storage::SharedMediaType;
using SeparatedType = Window::SeparateSharedMediaType;
return (type == Type::Photo)
? SeparatedType::Photos
: (type == Type::Video)
? SeparatedType::Videos
: (type == Type::File)
? SeparatedType::Files
: (type == Type::MusicFile)
? SeparatedType::Audio
: (type == Type::Link)
? SeparatedType::Links
: (type == Type::RoundVoiceFile)
? SeparatedType::Voices
: (type == Type::GIF)
? SeparatedType::GIF
: SeparatedType::None;
}
Fn<void()> SeparateWindowFactory(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
Storage::SharedMediaType type) {
const auto separateType = ToSeparateType(type);
if (separateType == Window::SeparateSharedMediaType::None) {
return nullptr;
}
return [=] {
controller->showInNewWindow(Window::SeparateId(separateType, peer));
};
}
void AddContextMenu(
not_null<Ui::AbstractButton*> button,
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
Storage::SharedMediaType type) {
const auto callback = SeparateWindowFactory(controller, peer, type);
if (!callback) {
return;
}
button->setAcceptBoth();
struct State final {
base::unique_qptr<Ui::PopupMenu> menu;
};
const auto state = button->lifetime().make_state<State>();
button->addClickHandler([=](Qt::MouseButton mouse) {
if (mouse != Qt::RightButton) {
return;
}
state->menu = base::make_unique_q<Ui::PopupMenu>(
button.get(),
st::popupMenuWithIcons);
state->menu->addAction(tr::lng_context_new_window(tr::now), [=] {
base::call_delayed(
st::popupMenuWithIcons.showDuration,
crl::guard(button, callback));
}, &st::menuIconNewWindow);
state->menu->popup(QCursor::pos());
});
}
} // namespace
InnerWidget::InnerWidget(
QWidget *parent,
not_null<Controller*> controller,
@ -160,6 +232,9 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
_migrated,
type,
tracker);
if (const auto window = _controller->parentController(); !_topic) {
AddContextMenu(result, window, _peer, type);
}
object_ptr<Profile::FloatingIcon>(
result,
icon,

View file

@ -321,6 +321,8 @@ ivHeightMin: 480px;
ivWidthDefault: 600px;
ivHeightDefault: 800px;
maxWidthSharedMediaWindow: 419px;
// Windows specific
winQuitIcon: icon {{ "win_quit", windowFg }};

View file

@ -44,6 +44,13 @@ SeparateId::SeparateId(not_null<PeerData*> peer)
: SeparateId(SeparateType::Chat, peer->owner().history(peer)) {
}
SeparateId::SeparateId(SeparateSharedMediaType type, not_null<PeerData*> peer)
: type(SeparateType::SharedMedia)
, sharedMedia(type)
, account(&peer->session().account())
, sharedMediaLocalPeer(peer) {
}
bool SeparateId::primary() const {
return (type == SeparateType::Primary);
}
@ -74,4 +81,10 @@ bool SeparateId::hasChatsList() const {
|| (type == SeparateType::Forum);
}
PeerData *SeparateId::sharedMediaPeer() const {
return (type == SeparateType::SharedMedia)
? sharedMediaLocalPeer
: nullptr;
}
} // namespace Window

View file

@ -29,6 +29,18 @@ enum class SeparateType {
Chat,
Forum,
SavedSublist,
SharedMedia,
};
enum class SeparateSharedMediaType {
None,
Photos,
Videos,
Files,
Audio,
Links,
Voices,
GIF,
};
struct SeparateId {
@ -38,10 +50,13 @@ struct SeparateId {
SeparateId(SeparateType type, not_null<Data::Thread*> thread);
SeparateId(not_null<Data::Thread*> thread);
SeparateId(not_null<PeerData*> peer);
SeparateId(SeparateSharedMediaType type, not_null<PeerData*> peer);
SeparateType type = SeparateType::Primary;
SeparateSharedMediaType sharedMedia = SeparateSharedMediaType::None;
Main::Account *account = nullptr;
Data::Thread *thread = nullptr; // For types except Main and Archive.
PeerData *sharedMediaLocalPeer = nullptr;
[[nodiscard]] bool valid() const {
return account != nullptr;
@ -55,6 +70,7 @@ struct SeparateId {
[[nodiscard]] Data::Forum *forum() const;
[[nodiscard]] Data::Folder *folder() const;
[[nodiscard]] Data::SavedSublist *sublist() const;
[[nodiscard]] PeerData *sharedMediaPeer() const;
[[nodiscard]] bool hasChatsList() const;

View file

@ -1189,6 +1189,30 @@ void SessionNavigation::showByInitialId(
case SeparateType::Chat:
showThread(id.thread, msgId, instant);
break;
case SeparateType::SharedMedia: {
Assert(id.sharedMedia != SeparateSharedMediaType::None);
clearSectionStack(instant);
const auto type = (id.sharedMedia == SeparateSharedMediaType::Photos)
? Storage::SharedMediaType::Photo
: (id.sharedMedia == SeparateSharedMediaType::Videos)
? Storage::SharedMediaType::Video
: (id.sharedMedia == SeparateSharedMediaType::Files)
? Storage::SharedMediaType::File
: (id.sharedMedia == SeparateSharedMediaType::Audio)
? Storage::SharedMediaType::MusicFile
: (id.sharedMedia == SeparateSharedMediaType::Links)
? Storage::SharedMediaType::Link
: (id.sharedMedia == SeparateSharedMediaType::Voices)
? Storage::SharedMediaType::RoundVoiceFile
: (id.sharedMedia == SeparateSharedMediaType::GIF)
? Storage::SharedMediaType::GIF
: Storage::SharedMediaType::Photo;
showSection(
std::make_shared<Info::Memento>(id.sharedMediaPeer(), type),
instant);
parent->widget()->setMaximumWidth(st::maxWidthSharedMediaWindow);
break;
}
case SeparateType::SavedSublist:
showSection(
std::make_shared<HistoryView::SublistMemento>(id.sublist()),
@ -1782,6 +1806,9 @@ const rpl::variable<Data::Forum*> &SessionController::shownForum() const {
}
void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) {
if (windowId().type == SeparateType::SharedMedia) {
return;
}
const auto was = _activeChatEntry.current().key.history();
const auto now = row.key.history();
if (was && was != now) {