mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-13 04:37:11 +02:00
Separate window for forums/topics/sublists/archive.
This commit is contained in:
parent
6dc3bd65e8
commit
69d21f73ef
34 changed files with 753 additions and 414 deletions
|
@ -1546,6 +1546,8 @@ PRIVATE
|
|||
window/window_peer_menu.cpp
|
||||
window/window_peer_menu.h
|
||||
window/window_section_common.h
|
||||
window/window_separate_id.cpp
|
||||
window/window_separate_id.h
|
||||
window/window_session_controller.cpp
|
||||
window/window_session_controller.h
|
||||
window/window_session_controller_link_info.h
|
||||
|
|
|
@ -81,7 +81,7 @@ void ChangeFilterById(
|
|||
MTP_int(filter.id()),
|
||||
filter.tl()
|
||||
)).done([=, chat = history->peer->name(), name = filter.title()] {
|
||||
const auto account = &history->session().account();
|
||||
const auto account = not_null(&history->session().account());
|
||||
if (const auto controller = Core::App().windowFor(account)) {
|
||||
controller->showToast((add
|
||||
? tr::lng_filters_toast_add
|
||||
|
|
|
@ -706,7 +706,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
|
|||
}
|
||||
}
|
||||
if (data.is_need_rating() && _id && _accessHash) {
|
||||
const auto window = Core::App().windowFor(_user);
|
||||
const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user));
|
||||
const auto session = &_user->session();
|
||||
const auto callId = _id;
|
||||
const auto callAccessHash = _accessHash;
|
||||
|
@ -1402,7 +1403,8 @@ void Call::handleRequestError(const QString &error) {
|
|||
_user->name())
|
||||
: QString();
|
||||
if (!inform.isEmpty()) {
|
||||
if (const auto window = Core::App().windowFor(_user)) {
|
||||
if (const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user))) {
|
||||
window->show(Ui::MakeInformBox(inform));
|
||||
} else {
|
||||
Ui::show(Ui::MakeInformBox(inform));
|
||||
|
@ -1420,7 +1422,8 @@ void Call::handleControllerError(const QString &error) {
|
|||
? tr::lng_call_error_audio_io(tr::now)
|
||||
: QString();
|
||||
if (!inform.isEmpty()) {
|
||||
if (const auto window = Core::App().windowFor(_user)) {
|
||||
if (const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user))) {
|
||||
window->show(Ui::MakeInformBox(inform));
|
||||
} else {
|
||||
Ui::show(Ui::MakeInformBox(inform));
|
||||
|
|
|
@ -30,15 +30,15 @@ ResolveWindow ResolveWindowDefault() {
|
|||
return (Window::SessionController*)nullptr;
|
||||
};
|
||||
auto &app = Core::App();
|
||||
const auto account = not_null(&session->account());
|
||||
if (const auto a = check(app.activeWindow())) {
|
||||
return a;
|
||||
} else if (const auto b = check(app.activePrimaryWindow())) {
|
||||
return b;
|
||||
} else if (const auto c = check(app.windowFor(&session->account()))) {
|
||||
} else if (const auto c = check(app.windowFor(account))) {
|
||||
return c;
|
||||
} else if (const auto d = check(
|
||||
app.ensureSeparateWindowForAccount(
|
||||
&session->account()))) {
|
||||
} else if (const auto d = check(app.ensureSeparateWindowFor(
|
||||
account))) {
|
||||
return d;
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/application.h"
|
||||
|
||||
#include "data/data_abstract_structure.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
|
@ -91,6 +92,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "payments/payments_checkout_process.h"
|
||||
#include "export/export_manager.h"
|
||||
#include "webrtc/webrtc_environment.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
|
@ -209,8 +211,7 @@ Application::~Application() {
|
|||
setLastActiveWindow(nullptr);
|
||||
_windowInSettings = _lastActivePrimaryWindow = nullptr;
|
||||
_closingAsyncWindows.clear();
|
||||
_secondaryWindows.clear();
|
||||
_primaryWindows.clear();
|
||||
_windows.clear();
|
||||
_mediaView = nullptr;
|
||||
_notifications->clearAllFast();
|
||||
|
||||
|
@ -315,8 +316,8 @@ void Application::run() {
|
|||
// Create mime database, so it won't be slow later.
|
||||
QMimeDatabase().mimeTypeForName(u"text/plain"_q);
|
||||
|
||||
_primaryWindows.emplace(nullptr, std::make_unique<Window::Controller>());
|
||||
setLastActiveWindow(_primaryWindows.front().second.get());
|
||||
_windows.emplace(nullptr, std::make_unique<Window::Controller>());
|
||||
setLastActiveWindow(_windows.front().second.get());
|
||||
_windowInSettings = _lastActivePrimaryWindow = _lastActiveWindow;
|
||||
|
||||
_domain->activeChanges(
|
||||
|
@ -405,7 +406,7 @@ void Application::run() {
|
|||
}
|
||||
|
||||
void Application::showAccount(not_null<Main::Account*> account) {
|
||||
if (const auto separate = separateWindowForAccount(account)) {
|
||||
if (const auto separate = separateWindowFor(account)) {
|
||||
_lastActivePrimaryWindow = separate;
|
||||
separate->activate();
|
||||
} else if (const auto last = activePrimaryWindow()) {
|
||||
|
@ -413,13 +414,13 @@ void Application::showAccount(not_null<Main::Account*> account) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::checkWindowAccount(not_null<Window::Controller*> window) {
|
||||
const auto account = window->maybeAccount();
|
||||
for (auto &[key, existing] : _primaryWindows) {
|
||||
if (existing.get() == window && key != account) {
|
||||
void Application::checkWindowId(not_null<Window::Controller*> window) {
|
||||
const auto id = window->id();
|
||||
for (auto &[existingId, existing] : _windows) {
|
||||
if (existing.get() == window && existingId != id) {
|
||||
auto found = std::move(existing);
|
||||
_primaryWindows.remove(key);
|
||||
_primaryWindows.emplace(account, std::move(found));
|
||||
_windows.remove(existingId);
|
||||
_windows.emplace(id, std::move(found));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -495,10 +496,7 @@ void Application::startSystemDarkModeViewer() {
|
|||
|
||||
void Application::enumerateWindows(Fn<void(
|
||||
not_null<Window::Controller*>)> callback) const {
|
||||
for (const auto &window : ranges::views::values(_primaryWindows)) {
|
||||
callback(window.get());
|
||||
}
|
||||
for (const auto &window : ranges::views::values(_secondaryWindows)) {
|
||||
for (const auto &window : ranges::views::values(_windows)) {
|
||||
callback(window.get());
|
||||
}
|
||||
}
|
||||
|
@ -607,10 +605,7 @@ void Application::clearEmojiSourceImages() {
|
|||
}
|
||||
|
||||
bool Application::isActiveForTrayMenu() const {
|
||||
return ranges::any_of(ranges::views::values(_primaryWindows), [=](
|
||||
const std::unique_ptr<Window::Controller> &controller) {
|
||||
return controller->widget()->isActiveForTrayMenu();
|
||||
}) || ranges::any_of(ranges::views::values(_secondaryWindows), [=](
|
||||
return ranges::any_of(ranges::views::values(_windows), [=](
|
||||
const std::unique_ptr<Window::Controller> &controller) {
|
||||
return controller->widget()->isActiveForTrayMenu();
|
||||
});
|
||||
|
@ -1287,44 +1282,36 @@ Window::Controller *Application::activePrimaryWindow() const {
|
|||
return _lastActivePrimaryWindow;
|
||||
}
|
||||
|
||||
Window::Controller *Application::separateWindowForAccount(
|
||||
not_null<Main::Account*> account) const {
|
||||
for (const auto &[openedAccount, window] : _primaryWindows) {
|
||||
if (openedAccount == account.get()) {
|
||||
Window::Controller *Application::separateWindowFor(
|
||||
Window::SeparateId id) const {
|
||||
for (const auto &[existingId, window] : _windows) {
|
||||
if (existingId == id) {
|
||||
return window.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Window::Controller *Application::separateWindowForPeer(
|
||||
not_null<PeerData*> peer) const {
|
||||
for (const auto &[history, window] : _secondaryWindows) {
|
||||
if (history->peer == peer) {
|
||||
return window.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Window::Controller *Application::ensureSeparateWindowForPeer(
|
||||
not_null<PeerData*> peer,
|
||||
Window::Controller *Application::ensureSeparateWindowFor(
|
||||
Window::SeparateId id,
|
||||
MsgId showAtMsgId) {
|
||||
const auto activate = [&](not_null<Window::Controller*> window) {
|
||||
window->activate();
|
||||
return window;
|
||||
};
|
||||
|
||||
if (const auto existing = separateWindowForPeer(peer)) {
|
||||
existing->sessionController()->showPeerHistory(
|
||||
peer,
|
||||
Window::SectionShow::Way::ClearStack,
|
||||
showAtMsgId);
|
||||
if (const auto existing = separateWindowFor(id)) {
|
||||
if (id.thread && id.type == Window::SeparateType::Chat) {
|
||||
existing->sessionController()->showThread(
|
||||
id.thread,
|
||||
showAtMsgId,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
}
|
||||
return activate(existing);
|
||||
}
|
||||
const auto result = _secondaryWindows.emplace(
|
||||
peer->owner().history(peer),
|
||||
std::make_unique<Window::Controller>(peer, showAtMsgId)
|
||||
|
||||
const auto result = _windows.emplace(
|
||||
id,
|
||||
std::make_unique<Window::Controller>(id, showAtMsgId)
|
||||
).first->second.get();
|
||||
processCreatedWindow(result);
|
||||
result->firstShow();
|
||||
|
@ -1332,55 +1319,63 @@ Window::Controller *Application::ensureSeparateWindowForPeer(
|
|||
return activate(result);
|
||||
}
|
||||
|
||||
Window::Controller *Application::ensureSeparateWindowForAccount(
|
||||
not_null<Main::Account*> account) {
|
||||
const auto activate = [&](not_null<Window::Controller*> window) {
|
||||
window->activate();
|
||||
return window;
|
||||
};
|
||||
|
||||
if (const auto existing = separateWindowForAccount(account)) {
|
||||
return activate(existing);
|
||||
}
|
||||
const auto result = _primaryWindows.emplace(
|
||||
account,
|
||||
std::make_unique<Window::Controller>(account)
|
||||
).first->second.get();
|
||||
processCreatedWindow(result);
|
||||
result->firstShow();
|
||||
result->finishFirstShow();
|
||||
return activate(result);
|
||||
}
|
||||
|
||||
Window::Controller *Application::windowFor(not_null<PeerData*> peer) const {
|
||||
if (const auto separate = separateWindowForPeer(peer)) {
|
||||
return separate;
|
||||
}
|
||||
return windowFor(&peer->account());
|
||||
}
|
||||
|
||||
Window::Controller *Application::windowFor(
|
||||
not_null<Main::Account*> account) const {
|
||||
if (const auto separate = separateWindowForAccount(account)) {
|
||||
Window::Controller *Application::windowFor(Window::SeparateId id) const {
|
||||
if (const auto separate = separateWindowFor(id)) {
|
||||
return separate;
|
||||
} else if (id && id.primary()) {
|
||||
return windowFor(not_null(id.account));
|
||||
}
|
||||
return activePrimaryWindow();
|
||||
}
|
||||
|
||||
Window::Controller *Application::windowForShowingHistory(
|
||||
not_null<PeerData*> peer) const {
|
||||
if (const auto separate = separateWindowFor(peer)) {
|
||||
return separate;
|
||||
}
|
||||
auto result = (Window::Controller*)nullptr;
|
||||
enumerateWindows([&](not_null<Window::Controller*> window) {
|
||||
if (const auto controller = window->sessionController()) {
|
||||
const auto current = controller->activeChatCurrent();
|
||||
if (const auto history = current.history()) {
|
||||
if (history->peer == peer) {
|
||||
result = window;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Window::Controller *Application::windowForShowingForum(
|
||||
not_null<Data::Forum*> forum) const {
|
||||
const auto id = Window::SeparateId(
|
||||
Window::SeparateType::Forum,
|
||||
forum->history());
|
||||
if (const auto separate = separateWindowFor(id)) {
|
||||
return separate;
|
||||
}
|
||||
auto result = (Window::Controller*)nullptr;
|
||||
enumerateWindows([&](not_null<Window::Controller*> window) {
|
||||
if (const auto controller = window->sessionController()) {
|
||||
const auto current = controller->shownForum().current();
|
||||
if (forum == current) {
|
||||
result = window;
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Window::Controller *Application::findWindow(
|
||||
not_null<QWidget*> widget) const {
|
||||
const auto window = widget->window();
|
||||
if (_lastActiveWindow && _lastActiveWindow->widget() == window) {
|
||||
return _lastActiveWindow;
|
||||
}
|
||||
for (const auto &[account, primary] : _primaryWindows) {
|
||||
if (primary->widget() == window) {
|
||||
return primary.get();
|
||||
}
|
||||
}
|
||||
for (const auto &[history, secondary] : _secondaryWindows) {
|
||||
if (secondary->widget() == window) {
|
||||
return secondary.get();
|
||||
for (const auto &[id, controller] : _windows) {
|
||||
if (controller->widget() == window) {
|
||||
return controller.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1392,10 +1387,11 @@ Window::Controller *Application::activeWindow() const {
|
|||
|
||||
bool Application::closeNonLastAsync(not_null<Window::Controller*> window) {
|
||||
const auto hasOther = [&] {
|
||||
for (const auto &[account, primary] : _primaryWindows) {
|
||||
if (!_closingAsyncWindows.contains(primary.get())
|
||||
&& primary.get() != window
|
||||
&& primary->maybeSession()) {
|
||||
for (const auto &[id, controller] : _windows) {
|
||||
if (id.primary()
|
||||
&& !_closingAsyncWindows.contains(controller.get())
|
||||
&& controller.get() != window
|
||||
&& controller->maybeSession()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1457,10 +1453,10 @@ void Application::closeWindow(not_null<Window::Controller*> window) {
|
|||
: nullptr;
|
||||
const auto next = nextFromStack
|
||||
? nextFromStack
|
||||
: (_primaryWindows.front().second.get() != window)
|
||||
? _primaryWindows.front().second.get()
|
||||
: (_primaryWindows.back().second.get() != window)
|
||||
? _primaryWindows.back().second.get()
|
||||
: (_windows.front().second.get() != window)
|
||||
? _windows.front().second.get()
|
||||
: (_windows.back().second.get() != window)
|
||||
? _windows.back().second.get()
|
||||
: nullptr;
|
||||
Assert(next != window);
|
||||
|
||||
|
@ -1481,20 +1477,12 @@ void Application::closeWindow(not_null<Window::Controller*> window) {
|
|||
}
|
||||
}
|
||||
_closingAsyncWindows.remove(window);
|
||||
for (auto i = begin(_primaryWindows); i != end(_primaryWindows);) {
|
||||
for (auto i = begin(_windows); i != end(_windows);) {
|
||||
if (i->second.get() == window) {
|
||||
Assert(_lastActiveWindow != window);
|
||||
Assert(_lastActivePrimaryWindow != window);
|
||||
Assert(_windowInSettings != window);
|
||||
i = _primaryWindows.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
for (auto i = begin(_secondaryWindows); i != end(_secondaryWindows);) {
|
||||
if (i->second.get() == window) {
|
||||
Assert(_lastActiveWindow != window);
|
||||
i = _secondaryWindows.erase(i);
|
||||
i = _windows.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
|
@ -1502,36 +1490,34 @@ void Application::closeWindow(not_null<Window::Controller*> window) {
|
|||
const auto account = domain().started()
|
||||
? &domain().active()
|
||||
: nullptr;
|
||||
if (account && !_primaryWindows.contains(account) && _lastActiveWindow) {
|
||||
if (account
|
||||
&& !_windows.contains(Window::SeparateId(account))
|
||||
&& _lastActiveWindow) {
|
||||
domain().activate(&_lastActiveWindow->account());
|
||||
}
|
||||
}
|
||||
|
||||
void Application::closeChatFromWindows(not_null<PeerData*> peer) {
|
||||
if (const auto window = windowFor(peer)
|
||||
; window && !window->isPrimary()) {
|
||||
closeWindow(window);
|
||||
}
|
||||
for (const auto &[history, window] : _secondaryWindows) {
|
||||
if (const auto session = window->sessionController()) {
|
||||
if (session->activeChatCurrent().peer() == peer) {
|
||||
session->showPeerHistory(
|
||||
window->singlePeer()->id,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto window = windowFor(&peer->account())) {
|
||||
if (const auto primary = window->sessionController()) {
|
||||
if (primary->activeChatCurrent().peer() == peer) {
|
||||
primary->clearSectionStack();
|
||||
}
|
||||
if (const auto forum = primary->shownForum().current()) {
|
||||
if (peer->forum() == forum) {
|
||||
primary->closeForum();
|
||||
const auto closeOne = [&] {
|
||||
for (const auto &[id, window] : _windows) {
|
||||
if (id.thread && id.thread->peer() == peer) {
|
||||
closeWindow(window.get());
|
||||
return true;
|
||||
} else if (const auto controller = window->sessionController()) {
|
||||
if (controller->activeChatCurrent().peer() == peer) {
|
||||
controller->showByInitialId();
|
||||
}
|
||||
if (const auto forum = controller->shownForum().current()) {
|
||||
if (peer->forum() == forum) {
|
||||
controller->closeForum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
while (closeOne()) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1737,11 +1723,8 @@ void Application::quitPreventFinished() {
|
|||
}
|
||||
|
||||
void Application::quitDelayed() {
|
||||
for (const auto &[account, window] : _primaryWindows) {
|
||||
window->widget()->hide();
|
||||
}
|
||||
for (const auto &[history, window] : _secondaryWindows) {
|
||||
window->widget()->hide();
|
||||
for (const auto &[id, controller] : _windows) {
|
||||
controller->widget()->hide();
|
||||
}
|
||||
if (!_private->quitTimer.isActive()) {
|
||||
_private->quitTimer.setCallback([] { Sandbox::QuitWhenStarted(); });
|
||||
|
|
|
@ -7,9 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "mtproto/mtproto_auth_key.h"
|
||||
#include "mtproto/mtproto_proxy_data.h"
|
||||
#include "base/timer.h"
|
||||
#include "window/window_separate_id.h"
|
||||
|
||||
class History;
|
||||
|
||||
|
@ -29,11 +30,9 @@ namespace Window {
|
|||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
namespace Window {
|
||||
namespace Notifications {
|
||||
namespace Window::Notifications {
|
||||
class System;
|
||||
} // namespace Notifications
|
||||
} // namespace Window
|
||||
} // namespace Window::Notifications
|
||||
|
||||
namespace ChatHelpers {
|
||||
class EmojiKeywords;
|
||||
|
@ -170,19 +169,17 @@ public:
|
|||
not_null<QWidget*> widget) const;
|
||||
[[nodiscard]] Window::Controller *activeWindow() const;
|
||||
[[nodiscard]] Window::Controller *activePrimaryWindow() const;
|
||||
[[nodiscard]] Window::Controller *separateWindowForAccount(
|
||||
not_null<Main::Account*> account) const;
|
||||
[[nodiscard]] Window::Controller *separateWindowForPeer(
|
||||
not_null<PeerData*> peer) const;
|
||||
Window::Controller *ensureSeparateWindowForPeer(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId showAtMsgId);
|
||||
Window::Controller *ensureSeparateWindowForAccount(
|
||||
not_null<Main::Account*> account);
|
||||
[[nodiscard]] Window::Controller *separateWindowFor(
|
||||
Window::SeparateId id) const;
|
||||
Window::Controller *ensureSeparateWindowFor(
|
||||
Window::SeparateId id,
|
||||
MsgId showAtMsgId = 0);
|
||||
[[nodiscard]] Window::Controller *windowFor( // Doesn't auto-switch.
|
||||
Window::SeparateId id) const;
|
||||
[[nodiscard]] Window::Controller *windowForShowingHistory(
|
||||
not_null<PeerData*> peer) const;
|
||||
[[nodiscard]] Window::Controller *windowFor( // Doesn't auto-switch.
|
||||
not_null<Main::Account*> account) const;
|
||||
[[nodiscard]] Window::Controller *windowForShowingForum(
|
||||
not_null<Data::Forum*> forum) const;
|
||||
[[nodiscard]] bool closeNonLastAsync(
|
||||
not_null<Window::Controller*> window);
|
||||
void closeWindow(not_null<Window::Controller*> window);
|
||||
|
@ -195,7 +192,7 @@ public:
|
|||
void checkSystemDarkMode();
|
||||
[[nodiscard]] bool isActiveForTrayMenu() const;
|
||||
void closeChatFromWindows(not_null<PeerData*> peer);
|
||||
void checkWindowAccount(not_null<Window::Controller*> window);
|
||||
void checkWindowId(not_null<Window::Controller*> window);
|
||||
void activate();
|
||||
|
||||
// Media view interface.
|
||||
|
@ -423,12 +420,9 @@ private:
|
|||
const std::unique_ptr<Calls::Instance> _calls;
|
||||
const std::unique_ptr<Iv::Instance> _iv;
|
||||
base::flat_map<
|
||||
Main::Account*,
|
||||
std::unique_ptr<Window::Controller>> _primaryWindows;
|
||||
Window::SeparateId,
|
||||
std::unique_ptr<Window::Controller>> _windows;
|
||||
base::flat_set<not_null<Window::Controller*>> _closingAsyncWindows;
|
||||
base::flat_map<
|
||||
not_null<History*>,
|
||||
std::unique_ptr<Window::Controller>> _secondaryWindows;
|
||||
std::vector<not_null<Window::Controller*>> _windowStack;
|
||||
Window::Controller *_lastActiveWindow = nullptr;
|
||||
Window::Controller *_lastActivePrimaryWindow = nullptr;
|
||||
|
|
|
@ -531,7 +531,7 @@ void DownloadManager::loadingStopWithConfirmation(
|
|||
return;
|
||||
}
|
||||
const auto window = Core::App().windowFor(
|
||||
&item->history()->session().account());
|
||||
not_null(&item->history()->session().account()));
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3676,7 +3676,7 @@ void InnerWidget::preloadRowsData() {
|
|||
}
|
||||
}
|
||||
|
||||
bool InnerWidget::chooseCollapsedRow() {
|
||||
bool InnerWidget::chooseCollapsedRow(Qt::KeyboardModifiers modifiers) {
|
||||
if (_state != WidgetState::Default) {
|
||||
return false;
|
||||
} else if ((_collapsedSelected < 0)
|
||||
|
@ -3769,7 +3769,15 @@ bool InnerWidget::chooseHashtag() {
|
|||
|
||||
ChosenRow InnerWidget::computeChosenRow() const {
|
||||
if (_state == WidgetState::Default) {
|
||||
if (_selected) {
|
||||
if ((_collapsedSelected >= 0)
|
||||
&& (_collapsedSelected < _collapsedRows.size())) {
|
||||
const auto &row = _collapsedRows[_collapsedSelected];
|
||||
Assert(row->folder != nullptr);
|
||||
return {
|
||||
.key = row->folder,
|
||||
.message = Data::UnreadMessagePosition,
|
||||
};
|
||||
} else if (_selected) {
|
||||
return {
|
||||
.key = _selected->key(),
|
||||
.message = Data::UnreadMessagePosition,
|
||||
|
@ -3813,9 +3821,7 @@ bool InnerWidget::isUserpicPressOnWide() const {
|
|||
bool InnerWidget::chooseRow(
|
||||
Qt::KeyboardModifiers modifiers,
|
||||
MsgId pressedTopicRootId) {
|
||||
if (chooseCollapsedRow()) {
|
||||
return true;
|
||||
} else if (chooseHashtag()) {
|
||||
if (chooseHashtag()) {
|
||||
return true;
|
||||
}
|
||||
const auto modifyChosenRow = [&](
|
||||
|
|
|
@ -252,7 +252,7 @@ private:
|
|||
void repaintCollapsedFolderRow(not_null<Data::Folder*> folder);
|
||||
void refreshWithCollapsedRows(bool toTop = false);
|
||||
bool needCollapsedRowsRefresh() const;
|
||||
bool chooseCollapsedRow();
|
||||
bool chooseCollapsedRow(Qt::KeyboardModifiers modifiers);
|
||||
void switchToFilter(FilterId filterId);
|
||||
bool chooseHashtag();
|
||||
ChosenRow computeChosenRow() const;
|
||||
|
|
|
@ -562,6 +562,8 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
if (topicJump) {
|
||||
if (controller()->shownForum().current() == topicJump->forum()) {
|
||||
controller()->closeForum();
|
||||
} else if (row.newWindow) {
|
||||
controller()->showInNewWindow(Window::SeparateId(topicJump));
|
||||
} else {
|
||||
if (!controller()->adaptive().isOneColumn()) {
|
||||
controller()->showForum(
|
||||
|
@ -575,11 +577,17 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
}
|
||||
return;
|
||||
} else if (const auto topic = row.key.topic()) {
|
||||
session().data().saveViewAsMessages(topic->forum(), false);
|
||||
controller()->showThread(
|
||||
topic,
|
||||
row.message.fullId.msg,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
if (row.newWindow) {
|
||||
controller()->showInNewWindow(
|
||||
Window::SeparateId(topic),
|
||||
row.message.fullId.msg);
|
||||
} else {
|
||||
session().data().saveViewAsMessages(topic->forum(), false);
|
||||
controller()->showThread(
|
||||
topic,
|
||||
row.message.fullId.msg,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
}
|
||||
} else if (history
|
||||
&& row.userpicClick
|
||||
&& (row.message.fullId.msg == ShowAtUnreadMsgId)
|
||||
|
@ -595,16 +603,19 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
const auto forum = history->peer->forum();
|
||||
if (controller()->shownForum().current() == forum) {
|
||||
controller()->closeForum();
|
||||
return;
|
||||
}
|
||||
controller()->showForum(
|
||||
forum,
|
||||
Window::SectionShow().withChildColumn());
|
||||
if (forum->channel()->viewForumAsMessages()) {
|
||||
controller()->showThread(
|
||||
history,
|
||||
ShowAtUnreadMsgId,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
} else if (row.newWindow) {
|
||||
controller()->showInNewWindow(
|
||||
Window::SeparateId(Window::SeparateType::Forum, history));
|
||||
} else {
|
||||
controller()->showForum(
|
||||
forum,
|
||||
Window::SectionShow().withChildColumn());
|
||||
if (forum->channel()->viewForumAsMessages()) {
|
||||
controller()->showThread(
|
||||
history,
|
||||
ShowAtUnreadMsgId,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (history) {
|
||||
|
@ -630,6 +641,12 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (row.newWindow) {
|
||||
controller()->showInNewWindow(Window::SeparateId(
|
||||
Window::SeparateType::Archive,
|
||||
&session()));
|
||||
return;
|
||||
}
|
||||
controller()->openFolder(folder);
|
||||
hideChildList();
|
||||
}
|
||||
|
@ -1847,13 +1864,21 @@ void Widget::slideFinished() {
|
|||
|
||||
void Widget::escape() {
|
||||
if (!cancelSearch({ .jumpBackToSearchedChat = true })) {
|
||||
if (controller()->shownForum().current()) {
|
||||
controller()->closeForum();
|
||||
if (const auto forum = controller()->shownForum().current()) {
|
||||
const auto id = controller()->windowId();
|
||||
const auto initial = id.forum();
|
||||
if (!initial) {
|
||||
controller()->closeForum();
|
||||
} else if (initial != forum) {
|
||||
controller()->showForum(initial);
|
||||
}
|
||||
} else if (controller()->openedFolder().current()) {
|
||||
controller()->closeFolder();
|
||||
if (!controller()->windowId().folder()) {
|
||||
controller()->closeFolder();
|
||||
}
|
||||
} else if (controller()->activeChatEntryCurrent().key) {
|
||||
controller()->content()->dialogsCancelled();
|
||||
} else {
|
||||
} else if (controller()->isPrimary()) {
|
||||
const auto filters = &session().data().chatsFilters();
|
||||
const auto &list = filters->list();
|
||||
const auto first = list.empty() ? FilterId() : list.front().id();
|
||||
|
@ -2704,6 +2729,9 @@ void Widget::updateForceDisplayWide() {
|
|||
void Widget::showForum(
|
||||
not_null<Data::Forum*> forum,
|
||||
const Window::SectionShow ¶ms) {
|
||||
if (_openedForum == forum) {
|
||||
return;
|
||||
}
|
||||
const auto nochat = !controller()->mainSectionShown();
|
||||
if (!params.childColumn
|
||||
|| (Core::App().settings().dialogsWidthRatio(nochat) == 0.)
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace Window {
|
|||
class SessionController;
|
||||
class ConnectionState;
|
||||
struct SectionShow;
|
||||
struct SeparateId;
|
||||
} // namespace Window
|
||||
|
||||
namespace Dialogs::Stories {
|
||||
|
|
|
@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/dynamic_thumbnails.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/unread_badge_paint.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
|
|
@ -317,7 +317,7 @@ ClickHandlerPtr JumpToMessageClickHandler(
|
|||
TextWithEntities highlightPart,
|
||||
int highlightPartOffsetHint) {
|
||||
return std::make_shared<LambdaClickHandler>([=] {
|
||||
const auto separate = Core::App().separateWindowForPeer(peer);
|
||||
const auto separate = Core::App().separateWindowFor(peer);
|
||||
const auto controller = separate
|
||||
? separate->sessionController()
|
||||
: peer->session().tryResolveWindow();
|
||||
|
@ -347,7 +347,7 @@ ClickHandlerPtr JumpToStoryClickHandler(
|
|||
not_null<PeerData*> peer,
|
||||
StoryId storyId) {
|
||||
return std::make_shared<LambdaClickHandler>([=] {
|
||||
const auto separate = Core::App().separateWindowForPeer(peer);
|
||||
const auto separate = Core::App().separateWindowFor(peer);
|
||||
const auto controller = separate
|
||||
? separate->sessionController()
|
||||
: peer->session().tryResolveWindow();
|
||||
|
|
|
@ -823,7 +823,7 @@ HistoryWidget::HistoryWidget(
|
|||
if (flags & PeerUpdateFlag::UnavailableReason) {
|
||||
const auto unavailable = _peer->computeUnavailableReason();
|
||||
if (!unavailable.isEmpty()) {
|
||||
const auto account = &_peer->account();
|
||||
const auto account = not_null(&_peer->account());
|
||||
closeCurrent();
|
||||
if (const auto primary = Core::App().windowFor(account)) {
|
||||
primary->showToast(unavailable);
|
||||
|
@ -3342,7 +3342,8 @@ void HistoryWidget::messagesFailed(const MTP::Error &error, int requestId) {
|
|||
|| error.type() == u"USER_BANNED_IN_CHANNEL"_q) {
|
||||
auto was = _peer;
|
||||
closeCurrent();
|
||||
if (const auto primary = Core::App().windowFor(&was->account())) {
|
||||
const auto wasAccount = not_null(&was->account());
|
||||
if (const auto primary = Core::App().windowFor(wasAccount)) {
|
||||
primary->showToast((was && was->isMegagroup())
|
||||
? tr::lng_group_not_accessible(tr::now)
|
||||
: tr::lng_channel_not_accessible(tr::now));
|
||||
|
@ -4974,8 +4975,8 @@ bool HistoryWidget::updateCmdStartShown() {
|
|||
}
|
||||
|
||||
bool HistoryWidget::searchInChatEmbedded(Dialogs::Key chat, QString query) {
|
||||
const auto peer = chat.peer();
|
||||
if (!peer || peer != controller()->singlePeer()) {
|
||||
const auto peer = chat.peer(); // windows todo
|
||||
if (!peer || Window::SeparateId(peer) != controller()->windowId()) {
|
||||
return false;
|
||||
} else if (_peer != peer) {
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
|
|
|
@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_peer_values.h"
|
||||
#include "data/data_group_call.h" // GroupCall::input.
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_stories.h"
|
||||
|
@ -714,10 +715,13 @@ void TopBarWidget::mousePressEvent(QMouseEvent *e) {
|
|||
&& !showSelectedState()
|
||||
&& !_chooseForReportReason;
|
||||
if (handleClick) {
|
||||
const auto archiveTop = (_activeChat.section == Section::ChatsList)
|
||||
&& _activeChat.key.folder();
|
||||
if ((_animatingMode && _back->rect().contains(e->pos()))
|
||||
|| (_activeChat.section == Section::ChatsList
|
||||
&& _activeChat.key.folder())) {
|
||||
backClicked();
|
||||
|| archiveTop) {
|
||||
if (!rootChatsListBar()) {
|
||||
backClicked();
|
||||
}
|
||||
} else {
|
||||
infoClicked();
|
||||
}
|
||||
|
@ -890,9 +894,22 @@ void TopBarWidget::setCustomTitle(const QString &title) {
|
|||
}
|
||||
}
|
||||
|
||||
bool TopBarWidget::rootChatsListBar() const {
|
||||
if (_activeChat.section != Section::ChatsList) {
|
||||
return false;
|
||||
}
|
||||
const auto id = _controller->windowId();
|
||||
const auto separateFolder = id.folder();
|
||||
const auto separateForum = id.forum();
|
||||
const auto active = _activeChat.key;
|
||||
return (separateForum && separateForum->history() == active.history())
|
||||
|| (separateFolder && separateFolder == active.folder());
|
||||
}
|
||||
|
||||
void TopBarWidget::refreshInfoButton() {
|
||||
if (_activeChat.key.topic()
|
||||
|| _activeChat.section == Section::ChatsList) {
|
||||
|| (_activeChat.section == Section::ChatsList
|
||||
&& !rootChatsListBar())) {
|
||||
_info.destroy();
|
||||
} else if (const auto peer = _activeChat.key.peer()) {
|
||||
auto info = object_ptr<Ui::UserpicButton>(
|
||||
|
@ -989,6 +1006,14 @@ void TopBarWidget::updateControlsGeometry() {
|
|||
_leftTaken += _back->width();
|
||||
}
|
||||
if (_info && !_info->isHidden()) {
|
||||
if (_back->isHidden() && _narrowRatio > 0.) {
|
||||
const auto &infoSt = st::topBarInfoButton;
|
||||
const auto middle = (_narrowWidth - infoSt.photoSize) / 2;
|
||||
_leftTaken = anim::interpolate(
|
||||
_leftTaken,
|
||||
middle - infoSt.photoPosition.x(),
|
||||
_narrowRatio);
|
||||
}
|
||||
_info->moveToLeft(_leftTaken, otherButtonsTop);
|
||||
_leftTaken += _info->width();
|
||||
} else if (_activeChat.key.topic()
|
||||
|
@ -997,7 +1022,9 @@ void TopBarWidget::updateControlsGeometry() {
|
|||
}
|
||||
|
||||
if (_searchField) {
|
||||
const auto fieldLeft = _leftTaken;
|
||||
const auto fieldLeft = _back->isHidden()
|
||||
? st::topBarArrowPadding.right()
|
||||
: _leftTaken;
|
||||
const auto fieldTop = searchFieldTop
|
||||
+ (height() - _searchField->height()) / 2;
|
||||
const auto fieldRight = st::dialogsFilterSkip
|
||||
|
@ -1075,9 +1102,10 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
_sendNow->setVisible(_canSendNow);
|
||||
|
||||
const auto isOneColumn = _controller->adaptive().isOneColumn();
|
||||
auto backVisible = isOneColumn
|
||||
|| !_controller->content()->stackIsEmpty()
|
||||
|| (_activeChat.section == Section::ChatsList);
|
||||
const auto backVisible = !rootChatsListBar()
|
||||
&& (isOneColumn
|
||||
|| (_activeChat.section == Section::ChatsList)
|
||||
|| !_controller->content()->stackIsEmpty());
|
||||
_back->setVisible(backVisible && !_chooseForReportReason);
|
||||
_cancelChoose->setVisible(_chooseForReportReason.has_value());
|
||||
if (_info) {
|
||||
|
@ -1085,7 +1113,8 @@ void TopBarWidget::updateControlsVisibility() {
|
|||
&& (isOneColumn || !_primaryWindow));
|
||||
}
|
||||
if (_unreadBadge) {
|
||||
_unreadBadge->setVisible(!_chooseForReportReason);
|
||||
_unreadBadge->setVisible(!_chooseForReportReason
|
||||
&& !rootChatsListBar());
|
||||
}
|
||||
const auto topic = _activeChat.key.topic();
|
||||
const auto section = _activeChat.section;
|
||||
|
|
|
@ -131,6 +131,7 @@ protected:
|
|||
private:
|
||||
struct EmojiInteractionSeenAnimation;
|
||||
|
||||
[[nodiscard]] bool rootChatsListBar() const;
|
||||
void refreshInfoButton();
|
||||
void refreshLang();
|
||||
void updateSearchVisibility();
|
||||
|
|
|
@ -318,8 +318,8 @@ not_null<Main::Account*> Domain::add(MTP::Environment environment) {
|
|||
void Domain::addActivated(MTP::Environment environment, bool newWindow) {
|
||||
const auto added = [&](not_null<Main::Account*> account) {
|
||||
if (newWindow) {
|
||||
Core::App().ensureSeparateWindowForAccount(account);
|
||||
} else if (const auto window = Core::App().separateWindowForAccount(
|
||||
Core::App().ensureSeparateWindowFor(account);
|
||||
} else if (const auto window = Core::App().separateWindowFor(
|
||||
account)) {
|
||||
window->activate();
|
||||
} else {
|
||||
|
@ -371,11 +371,11 @@ void Domain::watchSession(not_null<Account*> account) {
|
|||
void Domain::closeAccountWindows(not_null<Main::Account*> account) {
|
||||
auto another = (Main::Account*)nullptr;
|
||||
for (auto i = _accounts.begin(); i != _accounts.end(); ++i) {
|
||||
const auto other = i->account.get();
|
||||
const auto other = not_null(i->account.get());
|
||||
if (other == account) {
|
||||
continue;
|
||||
} else if (Core::App().separateWindowForAccount(other)) {
|
||||
const auto that = Core::App().separateWindowForAccount(account);
|
||||
} else if (Core::App().separateWindowFor(other)) {
|
||||
const auto that = Core::App().separateWindowFor(account);
|
||||
if (that) {
|
||||
that->close();
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ void Domain::removeRedundantAccounts() {
|
|||
|
||||
const auto was = _accounts.size();
|
||||
for (auto i = _accounts.begin(); i != _accounts.end();) {
|
||||
if (Core::App().separateWindowForAccount(i->account.get())
|
||||
if (Core::App().separateWindowFor(not_null(i->account.get()))
|
||||
|| i->account->sessionExists()) {
|
||||
++i;
|
||||
continue;
|
||||
|
@ -442,7 +442,7 @@ void Domain::checkForLastProductionConfig(
|
|||
}
|
||||
|
||||
void Domain::maybeActivate(not_null<Main::Account*> account) {
|
||||
if (Core::App().separateWindowForAccount(account)) {
|
||||
if (Core::App().separateWindowFor(account)) {
|
||||
activate(account);
|
||||
} else {
|
||||
Core::App().preventOrInvoke(crl::guard(account, [=] {
|
||||
|
@ -452,7 +452,7 @@ void Domain::maybeActivate(not_null<Main::Account*> account) {
|
|||
}
|
||||
|
||||
void Domain::activate(not_null<Main::Account*> account) {
|
||||
if (const auto window = Core::App().separateWindowForAccount(account)) {
|
||||
if (const auto window = Core::App().separateWindowFor(account)) {
|
||||
window->activate();
|
||||
}
|
||||
if (_active.current() == account.get()) {
|
||||
|
|
|
@ -497,7 +497,8 @@ Window::SessionController *Session::tryResolveWindow(
|
|||
if (forPeer) {
|
||||
auto primary = (Window::SessionController*)nullptr;
|
||||
for (const auto &window : _windows) {
|
||||
if (window->singlePeer() == forPeer) {
|
||||
const auto thread = window->windowId().thread;
|
||||
if (thread && thread->peer() == forPeer) {
|
||||
return window;
|
||||
} else if (window->isPrimary()) {
|
||||
primary = window;
|
||||
|
|
|
@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_connecting_widget.h"
|
||||
#include "window/window_top_bar_wrap.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "window/window_slide_animation.h"
|
||||
#include "window/window_history_hider.h"
|
||||
#include "window/window_controller.h"
|
||||
|
@ -232,19 +233,19 @@ MainWidget::MainWidget(
|
|||
, _controller(controller)
|
||||
, _dialogsWidth(st::columnMinimalWidthLeft)
|
||||
, _thirdColumnWidth(st::columnMinimalWidthThird)
|
||||
, _sideShadow(isPrimary()
|
||||
? base::make_unique_q<Ui::PlainShadow>(this)
|
||||
: nullptr)
|
||||
, _dialogs(isPrimary()
|
||||
, _dialogs(windowId().hasChatsList()
|
||||
? base::make_unique_q<Dialogs::Widget>(
|
||||
this,
|
||||
_controller,
|
||||
Dialogs::Widget::Layout::Main)
|
||||
: nullptr)
|
||||
, _history(std::in_place, this, _controller)
|
||||
, _sideShadow(_dialogs
|
||||
? base::make_unique_q<Ui::PlainShadow>(this)
|
||||
: nullptr)
|
||||
, _playerPlaylist(this, _controller)
|
||||
, _changelogs(Core::Changelogs::Create(&controller->session())) {
|
||||
if (isPrimary()) {
|
||||
if (_dialogs) {
|
||||
setupConnectingWidget();
|
||||
}
|
||||
|
||||
|
@ -732,7 +733,7 @@ void MainWidget::hideSingleUseKeyboard(FullMsgId replyToId) {
|
|||
|
||||
void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
||||
auto tags = Data::SearchTagsFromQuery(query);
|
||||
if (controller()->isPrimary()) {
|
||||
if (_dialogs) {
|
||||
auto state = Dialogs::SearchState{
|
||||
.inChat = ((tags.empty() || inChat.sublist())
|
||||
? inChat
|
||||
|
@ -758,7 +759,7 @@ void MainWidget::searchMessages(const QString &query, Dialogs::Key inChat) {
|
|||
if ((!_mainSection
|
||||
|| !_mainSection->searchInChatEmbedded(inChat, query))
|
||||
&& !_history->searchInChatEmbedded(inChat, query)) {
|
||||
const auto account = &session().account();
|
||||
const auto account = not_null(&session().account());
|
||||
if (const auto window = Core::App().windowFor(account)) {
|
||||
if (const auto controller = window->sessionController()) {
|
||||
controller->content()->searchMessages(query, inChat);
|
||||
|
@ -1238,36 +1239,35 @@ bool MainWidget::showHistoryInDifferentWindow(
|
|||
PeerId peerId,
|
||||
const SectionShow ¶ms,
|
||||
MsgId showAtMsgId) {
|
||||
if (!peerId) {
|
||||
return false;
|
||||
}
|
||||
const auto peer = session().data().peer(peerId);
|
||||
const auto account = &session().account();
|
||||
auto primary = Core::App().separateWindowForAccount(account);
|
||||
if (const auto separate = Core::App().separateWindowForPeer(peer)) {
|
||||
if (separate == &_controller->window()) {
|
||||
return false;
|
||||
if (const auto separateChat = _controller->windowId().chat()) {
|
||||
if (const auto history = separateChat->asHistory()) {
|
||||
if (history->peer == peer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
separate->sessionController()->showPeerHistory(
|
||||
}
|
||||
const auto window = Core::App().windowForShowingHistory(peer);
|
||||
if (window == &_controller->window()) {
|
||||
return false;
|
||||
} else if (window) {
|
||||
window->sessionController()->showPeerHistory(
|
||||
peerId,
|
||||
params,
|
||||
showAtMsgId);
|
||||
separate->activate();
|
||||
window->activate();
|
||||
return true;
|
||||
} else if (isPrimary()) {
|
||||
if (primary && primary != &_controller->window()) {
|
||||
primary->sessionController()->showPeerHistory(
|
||||
peerId,
|
||||
params,
|
||||
showAtMsgId);
|
||||
primary->activate();
|
||||
return true;
|
||||
}
|
||||
} else if (windowId().hasChatsList()) {
|
||||
return false;
|
||||
} else if (!peerId) {
|
||||
return true;
|
||||
} else if (singlePeer()->id == peerId) {
|
||||
return false;
|
||||
} else if (!primary) {
|
||||
}
|
||||
const auto account = not_null(&session().account());
|
||||
auto primary = Core::App().separateWindowFor(account);
|
||||
if (!primary) {
|
||||
Core::App().domain().activate(account);
|
||||
primary = Core::App().separateWindowForAccount(account);
|
||||
primary = Core::App().separateWindowFor(account);
|
||||
}
|
||||
if (primary && &primary->account() == account) {
|
||||
primary->sessionController()->showPeerHistory(
|
||||
|
@ -1293,7 +1293,7 @@ void MainWidget::showHistory(
|
|||
}
|
||||
const auto unavailable = peer->computeUnavailableReason();
|
||||
if (!unavailable.isEmpty()) {
|
||||
Assert(isPrimary());
|
||||
Assert(isPrimary()); // windows todo
|
||||
if (params.activation != anim::activation::background) {
|
||||
_controller->show(Ui::MakeInformBox(unavailable));
|
||||
_controller->window().activate();
|
||||
|
@ -1510,7 +1510,7 @@ void MainWidget::showMessage(
|
|||
void MainWidget::showForum(
|
||||
not_null<Data::Forum*> forum,
|
||||
const SectionShow ¶ms) {
|
||||
Expects(isPrimary() || (singlePeer() && singlePeer()->forum() == forum));
|
||||
Expects(_dialogs != nullptr);
|
||||
|
||||
_dialogs->showForum(forum, params);
|
||||
|
||||
|
@ -1846,8 +1846,8 @@ void MainWidget::checkMainSectionToLayer() {
|
|||
updateMainSectionShown();
|
||||
}
|
||||
|
||||
PeerData *MainWidget::singlePeer() const {
|
||||
return _controller->singlePeer();
|
||||
Window::SeparateId MainWidget::windowId() const {
|
||||
return _controller->windowId();
|
||||
}
|
||||
|
||||
bool MainWidget::isPrimary() const {
|
||||
|
@ -1957,7 +1957,7 @@ void MainWidget::showBackFromStack(
|
|||
}
|
||||
|
||||
if (_stack.empty()) {
|
||||
if (isPrimary()) {
|
||||
if (_dialogs) {
|
||||
_controller->clearSectionStack(params);
|
||||
}
|
||||
crl::on_main(this, [=] {
|
||||
|
|
|
@ -90,6 +90,7 @@ struct SectionSlideParams;
|
|||
struct SectionShow;
|
||||
enum class Column;
|
||||
class HistoryHider;
|
||||
struct SeparateId;
|
||||
} // namespace Window
|
||||
|
||||
namespace Calls {
|
||||
|
@ -121,7 +122,7 @@ public:
|
|||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] not_null<Window::SessionController*> controller() const;
|
||||
[[nodiscard]] PeerData *singlePeer() const;
|
||||
[[nodiscard]] Window::SeparateId windowId() const;
|
||||
[[nodiscard]] bool isPrimary() const;
|
||||
[[nodiscard]] bool isMainSectionShown() const;
|
||||
[[nodiscard]] bool isThirdSectionShown() const;
|
||||
|
@ -350,10 +351,6 @@ private:
|
|||
int _thirdColumnWidth = 0;
|
||||
Ui::Animations::Simple _a_dialogsWidth;
|
||||
|
||||
const base::unique_qptr<Ui::PlainShadow> _sideShadow;
|
||||
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
|
||||
object_ptr<Ui::ResizeArea> _firstColumnResizeArea = { nullptr };
|
||||
object_ptr<Ui::ResizeArea> _thirdColumnResizeArea = { nullptr };
|
||||
const base::unique_qptr<Dialogs::Widget> _dialogs;
|
||||
const base::unique_qptr<HistoryWidget> _history;
|
||||
object_ptr<Window::SectionWidget> _mainSection = { nullptr };
|
||||
|
@ -361,6 +358,11 @@ private:
|
|||
std::shared_ptr<Window::SectionMemento> _thirdSectionFromStack;
|
||||
std::unique_ptr<Window::ConnectionState> _connecting;
|
||||
|
||||
const base::unique_qptr<Ui::PlainShadow> _sideShadow;
|
||||
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
|
||||
object_ptr<Ui::ResizeArea> _firstColumnResizeArea = { nullptr };
|
||||
object_ptr<Ui::ResizeArea> _thirdColumnResizeArea = { nullptr };
|
||||
|
||||
base::weak_ptr<Calls::Call> _currentCall;
|
||||
base::weak_ptr<Calls::GroupCall> _currentGroupCall;
|
||||
rpl::lifetime _currentCallLifetime;
|
||||
|
|
|
@ -269,13 +269,11 @@ void MainWindow::setupMain(
|
|||
auto created = object_ptr<MainWidget>(bodyWidget(), sessionController());
|
||||
clearWidgets();
|
||||
_main = std::move(created);
|
||||
if (const auto peer = singlePeer()) {
|
||||
updateControlsGeometry();
|
||||
_main->controller()->showPeerHistory(
|
||||
peer,
|
||||
Window::SectionShow::Way::ClearStack,
|
||||
singlePeerShowAtMsgId);
|
||||
}
|
||||
updateControlsGeometry();
|
||||
Ui::SendPendingMoveResizeEvents(_main);
|
||||
_main->controller()->showByInitialId(
|
||||
Window::SectionShow::Way::ClearStack,
|
||||
singlePeerShowAtMsgId);
|
||||
if (_passcodeLock) {
|
||||
_main->hide();
|
||||
} else {
|
||||
|
|
|
@ -6158,7 +6158,7 @@ Window::SessionController *OverlayWidget::findWindow(bool switchTo) const {
|
|||
|
||||
if (switchTo) {
|
||||
auto controllerPtr = (Window::SessionController*)nullptr;
|
||||
const auto account = &_session->account();
|
||||
const auto account = not_null(&_session->account());
|
||||
const auto sessionWindow = Core::App().windowFor(account);
|
||||
const auto anyWindow = (sessionWindow
|
||||
&& &sessionWindow->account() == account)
|
||||
|
|
|
@ -983,13 +983,13 @@ void AccountsList::rebuild() {
|
|||
_reorder->finishReordering();
|
||||
if (newWindow) {
|
||||
_closeRequests.fire({});
|
||||
Core::App().ensureSeparateWindowForAccount(
|
||||
account);
|
||||
Core::App().ensureSeparateWindowFor(account);
|
||||
}
|
||||
Core::App().domain().maybeActivate(account);
|
||||
}
|
||||
};
|
||||
if (const auto window = Core::App().separateWindowForAccount(account)) {
|
||||
if (const auto window = Core::App().separateWindowFor(
|
||||
account)) {
|
||||
_closeRequests.fire({});
|
||||
window->activate();
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/platform/ui_platform_window.h"
|
||||
#include "platform/platform_window_title.h"
|
||||
#include "history/history.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_lock_widgets.h"
|
||||
#include "window/window_controller.h"
|
||||
|
@ -387,8 +388,8 @@ Main::Account &MainWindow::account() const {
|
|||
return _controller->account();
|
||||
}
|
||||
|
||||
PeerData *MainWindow::singlePeer() const {
|
||||
return _controller->singlePeer();
|
||||
Window::SeparateId MainWindow::id() const {
|
||||
return _controller->id();
|
||||
}
|
||||
|
||||
bool MainWindow::isPrimary() const {
|
||||
|
@ -602,20 +603,27 @@ WindowPosition MainWindow::initialPosition() const {
|
|||
? Core::AdjustToScale(
|
||||
Core::App().settings().windowPosition(),
|
||||
u"Window"_q)
|
||||
: active->widget()->nextInitialChildPosition(isPrimary());
|
||||
: active->widget()->nextInitialChildPosition(id());
|
||||
}
|
||||
|
||||
WindowPosition MainWindow::nextInitialChildPosition(bool primary) {
|
||||
WindowPosition MainWindow::nextInitialChildPosition(SeparateId childId) {
|
||||
const auto rect = geometry().marginsRemoved(frameMargins());
|
||||
const auto position = rect.topLeft();
|
||||
const auto adjust = [&](int value) {
|
||||
return primary ? value : (value * 3 / 4);
|
||||
return (value * 3 / 4);
|
||||
};
|
||||
const auto secondaryWithChatsList = !childId.primary() && childId.hasChatsList();
|
||||
const auto width = OptionNewWindowsSizeAsFirst.value()
|
||||
? Core::App().settings().windowPosition().w
|
||||
: childId.primary()
|
||||
? st::windowDefaultWidth
|
||||
: childId.hasChatsList()
|
||||
? (st::columnMinimalWidthLeft + adjust(st::windowDefaultWidth))
|
||||
: adjust(st::windowDefaultWidth);
|
||||
const auto height = OptionNewWindowsSizeAsFirst.value()
|
||||
? Core::App().settings().windowPosition().h
|
||||
: childId.primary()
|
||||
? st::windowDefaultHeight
|
||||
: adjust(st::windowDefaultHeight);
|
||||
const auto skip = ChildSkip();
|
||||
const auto delta = _lastChildIndex
|
||||
|
|
|
@ -33,6 +33,7 @@ class Controller;
|
|||
class SessionController;
|
||||
class TitleWidget;
|
||||
struct TermsLock;
|
||||
struct SeparateId;
|
||||
|
||||
[[nodiscard]] const QImage &Logo();
|
||||
[[nodiscard]] const QImage &LogoNoMargin();
|
||||
|
@ -66,7 +67,7 @@ public:
|
|||
[[nodiscard]] Window::Controller &controller() const {
|
||||
return *_controller;
|
||||
}
|
||||
[[nodiscard]] PeerData *singlePeer() const;
|
||||
[[nodiscard]] Window::SeparateId id() const;
|
||||
[[nodiscard]] bool isPrimary() const;
|
||||
[[nodiscard]] Main::Account &account() const;
|
||||
[[nodiscard]] Window::SessionController *sessionController() const;
|
||||
|
@ -200,7 +201,7 @@ private:
|
|||
|
||||
[[nodiscard]] Core::WindowPosition initialPosition() const;
|
||||
[[nodiscard]] Core::WindowPosition nextInitialChildPosition(
|
||||
bool primary);
|
||||
SeparateId childId);
|
||||
[[nodiscard]] QRect countInitialGeometry(Core::WindowPosition position);
|
||||
|
||||
bool computeIsActive() const;
|
||||
|
|
|
@ -1096,7 +1096,7 @@ void Manager::openNotificationMessage(
|
|||
&& item->isRegular()
|
||||
&& (item->out() || (item->mentionsMe() && !history->peer->isUser()));
|
||||
const auto topic = item ? item->topic() : nullptr;
|
||||
const auto separate = Core::App().separateWindowForPeer(history->peer);
|
||||
const auto separate = Core::App().separateWindowFor(history->peer);
|
||||
const auto window = separate
|
||||
? separate->sessionController()
|
||||
: history->session().tryResolveWindow();
|
||||
|
|
|
@ -28,7 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "window/themes/window_theme_editor.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_thread.h"
|
||||
#include "apiwrap.h" // ApiWrap::acceptTerms.
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
|
@ -93,23 +93,18 @@ Show::operator bool() const {
|
|||
|
||||
} // namespace
|
||||
|
||||
Controller::Controller() : Controller(CreateArgs{}) {
|
||||
Controller::Controller() : Controller(CreateArgs{ nullptr }) {
|
||||
}
|
||||
|
||||
Controller::Controller(not_null<Main::Account*> account)
|
||||
: Controller(CreateArgs{}) {
|
||||
showAccount(account);
|
||||
}
|
||||
|
||||
Controller::Controller(
|
||||
not_null<PeerData*> singlePeer,
|
||||
MsgId showAtMsgId)
|
||||
: Controller(CreateArgs{ singlePeer.get() }) {
|
||||
showAccount(&singlePeer->account(), showAtMsgId);
|
||||
Controller::Controller(SeparateId id, MsgId showAtMsgId)
|
||||
: Controller(CreateArgs{ id }) {
|
||||
if (id) {
|
||||
showAccount(id.account, showAtMsgId);
|
||||
}
|
||||
}
|
||||
|
||||
Controller::Controller(CreateArgs &&args)
|
||||
: _singlePeer(args.singlePeer)
|
||||
: _id(args.id)
|
||||
, _isActiveTimer([=] { updateIsActive(); })
|
||||
, _widget(this)
|
||||
, _adaptive(std::make_unique<Adaptive>()) {
|
||||
|
@ -125,6 +120,20 @@ Controller::~Controller() {
|
|||
_sessionController = nullptr;
|
||||
}
|
||||
|
||||
SeparateId Controller::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
bool Controller::isPrimary() const {
|
||||
return _id.primary();
|
||||
}
|
||||
|
||||
Main::Account &Controller::account() const {
|
||||
Expects(_id.account != nullptr);
|
||||
|
||||
return *_id.account;
|
||||
}
|
||||
|
||||
void Controller::showAccount(not_null<Main::Account*> account) {
|
||||
showAccount(account, ShowAtUnreadMsgId);
|
||||
}
|
||||
|
@ -132,20 +141,22 @@ void Controller::showAccount(not_null<Main::Account*> account) {
|
|||
void Controller::showAccount(
|
||||
not_null<Main::Account*> account,
|
||||
MsgId singlePeerShowAtMsgId) {
|
||||
Expects(isPrimary() || &_singlePeer->account() == account);
|
||||
Expects(isPrimary() || _id.account == account);
|
||||
|
||||
const auto prevSessionUniqueId = (_account && _account->sessionExists())
|
||||
? _account->session().uniqueId()
|
||||
const auto prevAccount = _id.account;
|
||||
const auto prevSession = maybeSession();
|
||||
const auto prevSessionUniqueId = prevSession
|
||||
? prevSession->uniqueId()
|
||||
: 0;
|
||||
_accountLifetime.destroy();
|
||||
_account = account;
|
||||
Core::App().checkWindowAccount(this);
|
||||
_id.account = account;
|
||||
Core::App().checkWindowId(this);
|
||||
|
||||
const auto updateOnlineOfPrevSesssion = crl::guard(_account, [=] {
|
||||
const auto updateOnlineOfPrevSesssion = crl::guard(account, [=] {
|
||||
if (!prevSessionUniqueId) {
|
||||
return;
|
||||
}
|
||||
for (auto &[index, account] : _account->domain().accounts()) {
|
||||
for (auto &[index, account] : _id.account->domain().accounts()) {
|
||||
if (const auto anotherSession = account->maybeSession()) {
|
||||
if (anotherSession->uniqueId() == prevSessionUniqueId) {
|
||||
anotherSession->updates().updateOnline(crl::now());
|
||||
|
@ -155,12 +166,15 @@ void Controller::showAccount(
|
|||
}
|
||||
});
|
||||
|
||||
_account->sessionValue(
|
||||
) | rpl::start_with_next([=](Main::Session *session) {
|
||||
if (!isPrimary() && (&_singlePeer->session() != session)) {
|
||||
if (!isPrimary()) {
|
||||
_id.account->sessionChanges(
|
||||
) | rpl::start_with_next([=](Main::Session *session) {
|
||||
Core::App().closeWindow(this);
|
||||
return;
|
||||
}
|
||||
}, _accountLifetime);
|
||||
}
|
||||
|
||||
_id.account->sessionValue(
|
||||
) | rpl::start_with_next([=](Main::Session *session) {
|
||||
const auto was = base::take(_sessionController);
|
||||
_sessionController = session
|
||||
? std::make_unique<SessionController>(session, this)
|
||||
|
@ -205,10 +219,6 @@ void Controller::showAccount(
|
|||
}, _accountLifetime);
|
||||
}
|
||||
|
||||
PeerData *Controller::singlePeer() const {
|
||||
return _singlePeer;
|
||||
}
|
||||
|
||||
void Controller::setupSideBar() {
|
||||
Expects(_sessionController != nullptr);
|
||||
|
||||
|
@ -321,7 +331,7 @@ void Controller::finishFirstShow() {
|
|||
}
|
||||
|
||||
Main::Session *Controller::maybeSession() const {
|
||||
return _account ? _account->maybeSession() : nullptr;
|
||||
return _id.account ? _id.account->maybeSession() : nullptr;
|
||||
}
|
||||
|
||||
auto Controller::sessionControllerValue() const
|
||||
|
@ -356,7 +366,7 @@ void Controller::setupPasscodeLock() {
|
|||
}
|
||||
|
||||
void Controller::clearPasscodeLock() {
|
||||
if (!_account) {
|
||||
if (!_id) {
|
||||
showAccount(&Core::App().activeAccount());
|
||||
} else {
|
||||
_widget.clearPasscodeLock();
|
||||
|
@ -482,7 +492,7 @@ void Controller::invokeForSessionController(
|
|||
PeerData *singlePeer,
|
||||
Fn<void(not_null<SessionController*>)> &&callback) {
|
||||
const auto separateWindow = singlePeer
|
||||
? Core::App().separateWindowForPeer(singlePeer)
|
||||
? Core::App().separateWindowFor(not_null(singlePeer))
|
||||
: nullptr;
|
||||
const auto separateSession = separateWindow
|
||||
? separateWindow->sessionController()
|
||||
|
@ -490,7 +500,7 @@ void Controller::invokeForSessionController(
|
|||
if (separateSession) {
|
||||
return callback(separateSession);
|
||||
}
|
||||
_account->domain().activate(std::move(account));
|
||||
_id.account->domain().activate(std::move(account));
|
||||
if (_sessionController) {
|
||||
callback(_sessionController.get());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "mainwindow.h"
|
||||
#include "window/window_adaptive.h"
|
||||
#include "window/window_separate_id.h"
|
||||
|
||||
namespace Main {
|
||||
class Account;
|
||||
|
@ -36,32 +37,20 @@ namespace Window {
|
|||
class Controller final : public base::has_weak_ptr {
|
||||
public:
|
||||
Controller();
|
||||
explicit Controller(not_null<Main::Account*> account);
|
||||
Controller(
|
||||
not_null<PeerData*> singlePeer,
|
||||
MsgId showAtMsgId);
|
||||
Controller(SeparateId id, MsgId showAtMsgId);
|
||||
~Controller();
|
||||
|
||||
Controller(const Controller &other) = delete;
|
||||
Controller &operator=(const Controller &other) = delete;
|
||||
|
||||
void showAccount(not_null<Main::Account*> account);
|
||||
[[nodiscard]] PeerData *singlePeer() const;
|
||||
[[nodiscard]] bool isPrimary() const {
|
||||
return (singlePeer() == nullptr);
|
||||
}
|
||||
[[nodiscard]] SeparateId id() const;
|
||||
[[nodiscard]] bool isPrimary() const;
|
||||
|
||||
[[nodiscard]] not_null<::MainWindow*> widget() {
|
||||
return &_widget;
|
||||
}
|
||||
[[nodiscard]] Main::Account &account() const {
|
||||
Expects(_account != nullptr);
|
||||
|
||||
return *_account;
|
||||
}
|
||||
[[nodiscard]] Main::Account *maybeAccount() const {
|
||||
return _account;
|
||||
}
|
||||
[[nodiscard]] Main::Account &account() const;
|
||||
[[nodiscard]] Main::Session *maybeSession() const;
|
||||
[[nodiscard]] SessionController *sessionController() const {
|
||||
return _sessionController.get();
|
||||
|
@ -155,7 +144,7 @@ public:
|
|||
|
||||
private:
|
||||
struct CreateArgs {
|
||||
PeerData *singlePeer = nullptr;
|
||||
SeparateId id;
|
||||
};
|
||||
explicit Controller(CreateArgs &&args);
|
||||
|
||||
|
@ -173,8 +162,7 @@ private:
|
|||
void showTermsDecline();
|
||||
void showTermsDelete();
|
||||
|
||||
PeerData *_singlePeer = nullptr;
|
||||
Main::Account *_account = nullptr;
|
||||
SeparateId _id;
|
||||
base::Timer _isActiveTimer;
|
||||
::MainWindow _widget;
|
||||
const std::unique_ptr<Adaptive> _adaptive;
|
||||
|
|
|
@ -47,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/unread_badge_paint.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
|
@ -551,9 +552,15 @@ void MainMenu::setupArchive() {
|
|||
const auto folder = [=] {
|
||||
return controller->session().data().folderLoaded(Data::Folder::kId);
|
||||
};
|
||||
const auto showArchive = [=] {
|
||||
const auto showArchive = [=](Qt::KeyboardModifiers modifiers) {
|
||||
if (const auto f = folder()) {
|
||||
controller->openFolder(f);
|
||||
if (modifiers & Qt::ControlModifier) {
|
||||
controller->showInNewWindow(Window::SeparateId(
|
||||
Window::SeparateType::Archive,
|
||||
&controller->session()));
|
||||
} else {
|
||||
controller->openFolder(f);
|
||||
}
|
||||
controller->window().hideSettingsAndLayer();
|
||||
}
|
||||
};
|
||||
|
@ -583,7 +590,7 @@ void MainMenu::setupArchive() {
|
|||
button->clicks(
|
||||
) | rpl::start_with_next([=](Qt::MouseButton which) {
|
||||
if (which == Qt::LeftButton) {
|
||||
showArchive();
|
||||
showArchive(button->clickModifiers());
|
||||
return;
|
||||
} else if (which != Qt::RightButton) {
|
||||
return;
|
||||
|
@ -591,35 +598,13 @@ void MainMenu::setupArchive() {
|
|||
_contextMenu = base::make_unique_q<Ui::PopupMenu>(
|
||||
this,
|
||||
st::popupMenuExpandedSeparator);
|
||||
const auto addAction = PeerMenuCallback([&](
|
||||
PeerMenuCallback::Args a) {
|
||||
return _contextMenu->addAction(
|
||||
a.text,
|
||||
std::move(a.handler),
|
||||
a.icon);
|
||||
});
|
||||
|
||||
const auto hide = [=] {
|
||||
controller->session().settings().setArchiveInMainMenu(false);
|
||||
controller->session().saveSettingsDelayed();
|
||||
controller->window().hideSettingsAndLayer();
|
||||
};
|
||||
addAction(
|
||||
tr::lng_context_archive_to_list(tr::now),
|
||||
std::move(hide),
|
||||
&st::menuIconFromMainMenu);
|
||||
|
||||
MenuAddMarkAsReadChatListAction(
|
||||
controller,
|
||||
[f = folder()] { return f->chatsList(); },
|
||||
addAction);
|
||||
|
||||
_contextMenu->addSeparator();
|
||||
Settings::PreloadArchiveSettings(&controller->session());
|
||||
addAction(tr::lng_context_archive_settings(tr::now), [=] {
|
||||
controller->show(Box(Settings::ArchiveSettingsBox, controller));
|
||||
}, &st::menuIconManage);
|
||||
|
||||
Window::FillDialogsEntryMenu(
|
||||
_controller,
|
||||
Dialogs::EntryState{
|
||||
.key = folder(),
|
||||
.section = Dialogs::EntryState::Section::ContextMenu,
|
||||
},
|
||||
Ui::Menu::CreateAddActionCallback(_contextMenu));
|
||||
_contextMenu->popup(QCursor::pos());
|
||||
}, button->lifetime());
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history.h"
|
||||
#include "history/history_item_helpers.h" // GetErrorTextForSending.
|
||||
#include "history/view/history_view_context_menu.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "settings/settings_advanced.h"
|
||||
|
@ -650,20 +651,48 @@ void Filler::addToggleUnreadMark() {
|
|||
}
|
||||
|
||||
void Filler::addNewWindow() {
|
||||
const auto controller = _controller;
|
||||
if (_folder) {
|
||||
_addAction(tr::lng_context_new_window(tr::now), [=] {
|
||||
Ui::PreventDelayedActivation();
|
||||
controller->showInNewWindow(SeparateId(
|
||||
SeparateType::Archive,
|
||||
&controller->session()));
|
||||
}, &st::menuIconNewWindow);
|
||||
AddSeparatorAndShiftUp(_addAction);
|
||||
return;
|
||||
} else if (const auto weak = base::make_weak(_sublist)) {
|
||||
_addAction(tr::lng_context_new_window(tr::now), [=] {
|
||||
Ui::PreventDelayedActivation();
|
||||
if (const auto sublist = weak.get()) {
|
||||
const auto peer = sublist->peer();
|
||||
controller->showInNewWindow(SeparateId(
|
||||
SeparateType::SavedSublist,
|
||||
peer->owner().history(peer)));
|
||||
}
|
||||
}, &st::menuIconNewWindow);
|
||||
AddSeparatorAndShiftUp(_addAction);
|
||||
return;
|
||||
}
|
||||
const auto history = _request.key.history();
|
||||
if (!_peer
|
||||
|| _topic
|
||||
|| _peer->isForum()
|
||||
|| (history
|
||||
&& history->useTopPromotion()
|
||||
&& !history->topPromotionType().isEmpty())) {
|
||||
return;
|
||||
}
|
||||
const auto peer = _peer;
|
||||
const auto controller = _controller;
|
||||
const auto thread = _topic
|
||||
? not_null<Data::Thread*>(_topic)
|
||||
: _peer->owner().history(_peer);
|
||||
const auto weak = base::make_weak(thread);
|
||||
_addAction(tr::lng_context_new_window(tr::now), [=] {
|
||||
Ui::PreventDelayedActivation();
|
||||
controller->showInNewWindow(peer);
|
||||
if (const auto strong = weak.get()) {
|
||||
controller->showInNewWindow(SeparateId(
|
||||
peer->isForum() ? SeparateType::Forum : SeparateType::Chat,
|
||||
strong));
|
||||
}
|
||||
}, &st::menuIconNewWindow);
|
||||
AddSeparatorAndShiftUp(_addAction);
|
||||
}
|
||||
|
@ -1253,6 +1282,12 @@ void Filler::addViewAsMessages() {
|
|||
FullMsgId(),
|
||||
}, callback, QApplication::activePopupWidget());
|
||||
return true;
|
||||
} else if (base::IsCtrlPressed()) {
|
||||
Ui::PreventDelayedActivation();
|
||||
controller->showInNewWindow(SeparateId(
|
||||
SeparateType::Chat,
|
||||
peer->owner().history(peer)));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
@ -1432,27 +1467,39 @@ void Filler::fillArchiveActions() {
|
|||
if (_folder->id() != Data::Folder::kId) {
|
||||
return;
|
||||
}
|
||||
addNewWindow();
|
||||
|
||||
const auto controller = _controller;
|
||||
const auto hidden = controller->session().settings().archiveCollapsed();
|
||||
const auto text = hidden
|
||||
? tr::lng_context_archive_expand(tr::now)
|
||||
: tr::lng_context_archive_collapse(tr::now);
|
||||
_addAction(text, [=] {
|
||||
controller->session().settings().setArchiveCollapsed(!hidden);
|
||||
controller->session().saveSettingsDelayed();
|
||||
}, hidden ? &st::menuIconExpand : &st::menuIconCollapse);
|
||||
|
||||
_addAction(tr::lng_context_archive_to_menu(tr::now), [=] {
|
||||
controller->showToast({
|
||||
.text = { tr::lng_context_archive_to_menu_info(tr::now) },
|
||||
.st = &st::windowArchiveToast,
|
||||
.duration = kArchivedToastDuration,
|
||||
});
|
||||
|
||||
controller->session().settings().setArchiveInMainMenu(
|
||||
!controller->session().settings().archiveInMainMenu());
|
||||
controller->session().saveSettingsDelayed();
|
||||
}, &st::menuIconToMainMenu);
|
||||
{
|
||||
const auto text = hidden
|
||||
? tr::lng_context_archive_expand(tr::now)
|
||||
: tr::lng_context_archive_collapse(tr::now);
|
||||
_addAction(text, [=] {
|
||||
controller->session().settings().setArchiveCollapsed(!hidden);
|
||||
controller->session().saveSettingsDelayed();
|
||||
}, hidden ? &st::menuIconExpand : &st::menuIconCollapse);
|
||||
}
|
||||
const auto inmenu = controller->session().settings().archiveInMainMenu();
|
||||
{
|
||||
const auto text = inmenu
|
||||
? tr::lng_context_archive_to_list(tr::now)
|
||||
: tr::lng_context_archive_to_menu(tr::now);
|
||||
_addAction(text, [=] {
|
||||
if (!inmenu) {
|
||||
controller->showToast({
|
||||
.text = {
|
||||
tr::lng_context_archive_to_menu_info(tr::now)
|
||||
},
|
||||
.st = &st::windowArchiveToast,
|
||||
.duration = kArchivedToastDuration,
|
||||
});
|
||||
}
|
||||
controller->session().settings().setArchiveInMainMenu(!inmenu);
|
||||
controller->session().saveSettingsDelayed();
|
||||
controller->window().hideSettingsAndLayer();
|
||||
}, inmenu ? &st::menuIconFromMainMenu : &st::menuIconToMainMenu);
|
||||
}
|
||||
|
||||
MenuAddMarkAsReadChatListAction(
|
||||
controller,
|
||||
|
@ -1460,6 +1507,7 @@ void Filler::fillArchiveActions() {
|
|||
_addAction);
|
||||
|
||||
_addAction({ .isSeparator = true });
|
||||
|
||||
Settings::PreloadArchiveSettings(&controller->session());
|
||||
_addAction(tr::lng_context_archive_settings(tr::now), [=] {
|
||||
controller->show(Box(Settings::ArchiveSettingsBox, controller));
|
||||
|
@ -1467,6 +1515,7 @@ void Filler::fillArchiveActions() {
|
|||
}
|
||||
|
||||
void Filler::fillSavedSublistActions() {
|
||||
addNewWindow();
|
||||
addTogglePin();
|
||||
}
|
||||
|
||||
|
@ -1983,17 +2032,17 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
ForwardToSelf(show, draft);
|
||||
return true;
|
||||
}
|
||||
auto controller = Core::App().windowFor(peer);
|
||||
const auto id = SeparateId(
|
||||
(peer->isForum()
|
||||
? SeparateType::Forum
|
||||
: SeparateType::Chat),
|
||||
thread);
|
||||
auto controller = Core::App().windowFor(id);
|
||||
if (!controller) {
|
||||
return false;
|
||||
}
|
||||
if (controller->maybeSession() != &peer->session()) {
|
||||
controller = peer->isForum()
|
||||
? Core::App().ensureSeparateWindowForAccount(
|
||||
&peer->account())
|
||||
: Core::App().ensureSeparateWindowForPeer(
|
||||
peer,
|
||||
ShowAtUnreadMsgId);
|
||||
controller = Core::App().ensureSeparateWindowFor(id);
|
||||
if (controller->maybeSession() != &peer->session()) {
|
||||
return false;
|
||||
}
|
||||
|
|
77
Telegram/SourceFiles/window/window_separate_id.cpp
Normal file
77
Telegram/SourceFiles/window/window_separate_id.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
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 "window/window_separate_id.h"
|
||||
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_thread.h"
|
||||
#include "history/history.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Window {
|
||||
|
||||
SeparateId::SeparateId(std::nullptr_t) {
|
||||
}
|
||||
|
||||
SeparateId::SeparateId(not_null<Main::Account*> account)
|
||||
: account(account) {
|
||||
}
|
||||
|
||||
SeparateId::SeparateId(SeparateType type, not_null<Main::Session*> session)
|
||||
: type(type)
|
||||
, account(&session->account()) {
|
||||
}
|
||||
|
||||
SeparateId::SeparateId(SeparateType type, not_null<Data::Thread*> thread)
|
||||
: type(type)
|
||||
, account(&thread->session().account())
|
||||
, thread(thread) {
|
||||
}
|
||||
|
||||
SeparateId::SeparateId(not_null<Data::Thread*> thread)
|
||||
: SeparateId(SeparateType::Chat, thread) {
|
||||
}
|
||||
|
||||
SeparateId::SeparateId(not_null<PeerData*> peer)
|
||||
: SeparateId(SeparateType::Chat, peer->owner().history(peer)) {
|
||||
}
|
||||
|
||||
bool SeparateId::primary() const {
|
||||
return (type == SeparateType::Primary);
|
||||
}
|
||||
|
||||
Data::Thread *SeparateId::chat() const {
|
||||
return (type == SeparateType::Chat) ? thread : nullptr;
|
||||
}
|
||||
|
||||
Data::Forum *SeparateId::forum() const {
|
||||
return (type == SeparateType::Forum) ? thread->asForum() : nullptr;
|
||||
}
|
||||
|
||||
Data::Folder *SeparateId::folder() const {
|
||||
return (type == SeparateType::Archive)
|
||||
? account->session().data().folder(Data::Folder::kId).get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
Data::SavedSublist *SeparateId::sublist() const {
|
||||
return (type == SeparateType::SavedSublist)
|
||||
? thread->owner().savedMessages().sublist(thread->peer()).get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool SeparateId::hasChatsList() const {
|
||||
return (type == SeparateType::Primary)
|
||||
|| (type == SeparateType::Archive)
|
||||
|| (type == SeparateType::Forum);
|
||||
}
|
||||
|
||||
} // namespace Window
|
69
Telegram/SourceFiles/window/window_separate_id.h
Normal file
69
Telegram/SourceFiles/window/window_separate_id.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
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
|
||||
|
||||
class PeerData;
|
||||
|
||||
namespace Data {
|
||||
class Thread;
|
||||
class Folder;
|
||||
class Forum;
|
||||
class SavedSublist;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class Account;
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Window {
|
||||
|
||||
enum class SeparateType {
|
||||
Primary,
|
||||
Archive,
|
||||
Chat,
|
||||
Forum,
|
||||
SavedSublist,
|
||||
};
|
||||
|
||||
struct SeparateId {
|
||||
SeparateId(std::nullptr_t);
|
||||
SeparateId(not_null<Main::Account*> account);
|
||||
SeparateId(SeparateType type, not_null<Main::Session*> session);
|
||||
SeparateId(SeparateType type, not_null<Data::Thread*> thread);
|
||||
SeparateId(not_null<Data::Thread*> thread);
|
||||
SeparateId(not_null<PeerData*> peer);
|
||||
|
||||
SeparateType type = SeparateType::Primary;
|
||||
Main::Account *account = nullptr;
|
||||
Data::Thread *thread = nullptr; // For types except Main and Archive.
|
||||
|
||||
[[nodiscard]] bool valid() const {
|
||||
return account != nullptr;
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool primary() const;
|
||||
[[nodiscard]] Data::Thread *chat() const;
|
||||
[[nodiscard]] Data::Forum *forum() const;
|
||||
[[nodiscard]] Data::Folder *folder() const;
|
||||
[[nodiscard]] Data::SavedSublist *sublist() const;
|
||||
|
||||
[[nodiscard]] bool hasChatsList() const;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
const SeparateId &,
|
||||
const SeparateId &) = default;
|
||||
friend inline bool operator==(
|
||||
const SeparateId &,
|
||||
const SeparateId &) = default;
|
||||
};
|
||||
|
||||
} // namespace Window
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_chat_preview.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/window_filters_menu.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "info/channel_statistics/earn/info_earn_inner_widget.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "info/info_controller.h"
|
||||
|
@ -26,11 +27,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
//#include "history/view/reactions/history_view_reactions_button.h"
|
||||
#include "history/view/history_view_replies_section.h"
|
||||
#include "history/view/history_view_scheduled_section.h"
|
||||
#include "history/view/history_view_sublist_section.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "media/view/media_view_open_common.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/data_document_resolver.h"
|
||||
#include "data/data_download_manager.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_folder.h"
|
||||
|
@ -1100,6 +1103,36 @@ void SessionNavigation::showPeerHistory(
|
|||
showPeerHistory(history->peer->id, params, msgId);
|
||||
}
|
||||
|
||||
void SessionNavigation::showByInitialId(
|
||||
const SectionShow ¶ms,
|
||||
MsgId msgId) {
|
||||
const auto parent = parentController();
|
||||
const auto id = parent->window().id();
|
||||
auto instant = params;
|
||||
instant.animated = anim::type::instant;
|
||||
switch (id.type) {
|
||||
case SeparateType::Archive:
|
||||
clearSectionStack(instant);
|
||||
parent->openFolder(id.folder());
|
||||
break;
|
||||
case SeparateType::Forum:
|
||||
clearSectionStack(instant);
|
||||
parent->showForum(id.forum(), instant);
|
||||
break;
|
||||
case SeparateType::Primary:
|
||||
clearSectionStack(instant);
|
||||
break;
|
||||
case SeparateType::Chat:
|
||||
showThread(id.thread, msgId, instant);
|
||||
break;
|
||||
case SeparateType::SavedSublist:
|
||||
showSection(
|
||||
std::make_shared<HistoryView::SublistMemento>(id.sublist()),
|
||||
instant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SessionNavigation::showSettings(
|
||||
Settings::Type type,
|
||||
const SectionShow ¶ms) {
|
||||
|
@ -1182,6 +1215,7 @@ SessionController::SessionController(
|
|||
std::make_unique<ChatHelpers::EmojiInteractions>(session))
|
||||
, _chatPreviewManager(std::make_unique<ChatPreviewManager>(this))
|
||||
, _isPrimary(window->isPrimary())
|
||||
, _hasDialogs(window->id().hasChatsList())
|
||||
, _sendingAnimation(
|
||||
std::make_unique<Ui::MessageSendingAnimationController>(this))
|
||||
, _tabbedSelector(
|
||||
|
@ -1191,6 +1225,7 @@ SessionController::SessionController(
|
|||
GifPauseReason::TabbedPanel))
|
||||
, _invitePeekTimer([=] { checkInvitePeek(); })
|
||||
, _activeChatsFilter(session->data().chatsFilters().defaultId())
|
||||
, _openedFolder(window->id().folder())
|
||||
, _defaultChatTheme(std::make_shared<Ui::ChatTheme>())
|
||||
, _chatStyle(std::make_unique<Ui::ChatStyle>(session->colorIndicesValue()))
|
||||
, _giftPremiumValidator(this) {
|
||||
|
@ -1373,8 +1408,8 @@ void SessionController::suggestArchiveAndMute() {
|
|||
}));
|
||||
}
|
||||
|
||||
PeerData *SessionController::singlePeer() const {
|
||||
return _window->singlePeer();
|
||||
SeparateId SessionController::windowId() const {
|
||||
return _window->id();
|
||||
}
|
||||
|
||||
bool SessionController::isPrimary() const {
|
||||
|
@ -1466,7 +1501,7 @@ void SessionController::setupShortcuts() {
|
|||
if (account == &session().account()) {
|
||||
return false;
|
||||
}
|
||||
const auto window = app->separateWindowForAccount(account);
|
||||
const auto window = app->separateWindowFor(account);
|
||||
if (window) {
|
||||
window->activate();
|
||||
} else {
|
||||
|
@ -1523,7 +1558,9 @@ void SessionController::checkOpenedFilter() {
|
|||
}
|
||||
|
||||
void SessionController::activateFirstChatsFilter() {
|
||||
if (_filtersActivated || !session().data().chatsFilters().loaded()) {
|
||||
if (_filtersActivated
|
||||
|| !isPrimary()
|
||||
|| !session().data().chatsFilters().loaded()) {
|
||||
return;
|
||||
}
|
||||
_filtersActivated = true;
|
||||
|
@ -1536,8 +1573,24 @@ bool SessionController::uniqueChatsInSearchResults() const {
|
|||
&& !_searchInChat.current();
|
||||
}
|
||||
|
||||
bool SessionController::openFolderInDifferentWindow(
|
||||
not_null<Data::Folder*> folder) {
|
||||
const auto id = SeparateId(SeparateType::Archive, &session());
|
||||
if (const auto separate = Core::App().separateWindowFor(id)) {
|
||||
if (separate == _window) {
|
||||
return false;
|
||||
}
|
||||
separate->sessionController()->showByInitialId();
|
||||
separate->activate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SessionController::openFolder(not_null<Data::Folder*> folder) {
|
||||
if (_openedFolder.current() != folder) {
|
||||
if (openFolderInDifferentWindow(folder)) {
|
||||
return;
|
||||
} else if (_openedFolder.current() != folder) {
|
||||
resetFakeUnreadWhileOpened();
|
||||
}
|
||||
if (activeChatsFilterCurrent() != 0) {
|
||||
|
@ -1550,22 +1603,44 @@ void SessionController::openFolder(not_null<Data::Folder*> folder) {
|
|||
}
|
||||
|
||||
void SessionController::closeFolder() {
|
||||
if (_openedFolder.current()
|
||||
&& windowId().type == SeparateType::Archive) {
|
||||
Core::App().closeWindow(_window);
|
||||
return;
|
||||
}
|
||||
_openedFolder = nullptr;
|
||||
}
|
||||
|
||||
bool SessionController::showForumInDifferentWindow(
|
||||
not_null<Data::Forum*> forum,
|
||||
const SectionShow ¶ms) {
|
||||
const auto window = Core::App().windowForShowingForum(forum);
|
||||
if (window == _window) {
|
||||
return false;
|
||||
} else if (window) {
|
||||
window->sessionController()->showForum(forum, params);
|
||||
window->activate();
|
||||
return true;
|
||||
} else if (windowId().hasChatsList()) {
|
||||
return false;
|
||||
}
|
||||
const auto account = not_null(&session().account());
|
||||
auto primary = Core::App().separateWindowFor(account);
|
||||
if (!primary) {
|
||||
Core::App().domain().activate(account);
|
||||
primary = Core::App().separateWindowFor(account);
|
||||
}
|
||||
if (primary && &primary->account() == account) {
|
||||
primary->sessionController()->showForum(forum, params);
|
||||
primary->activate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SessionController::showForum(
|
||||
not_null<Data::Forum*> forum,
|
||||
const SectionShow ¶ms) {
|
||||
if (!isPrimary()) {
|
||||
auto primary = Core::App().windowFor(&session().account());
|
||||
if (&primary->account() != &session().account()) {
|
||||
Core::App().domain().activate(&session().account());
|
||||
primary = Core::App().windowFor(&session().account());
|
||||
}
|
||||
if (&primary->account() == &session().account()) {
|
||||
primary->sessionController()->showForum(forum, params);
|
||||
}
|
||||
primary->activate();
|
||||
if (showForumInDifferentWindow(forum, params)) {
|
||||
return;
|
||||
}
|
||||
_shownForumLifetime.destroy();
|
||||
|
@ -1598,6 +1673,18 @@ void SessionController::showForum(
|
|||
}
|
||||
|
||||
void SessionController::closeForum() {
|
||||
if (const auto forum = _shownForum.current()) {
|
||||
const auto id = windowId();
|
||||
if (id.type == SeparateType::Forum) {
|
||||
const auto initial = id.thread->asForum();
|
||||
if (!initial || initial == forum) {
|
||||
Core::App().closeWindow(_window);
|
||||
} else {
|
||||
showForum(initial);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
_shownForumLifetime.destroy();
|
||||
_shownForum = nullptr;
|
||||
}
|
||||
|
@ -1889,7 +1976,7 @@ int SessionController::dialogsSmallColumnWidth() const {
|
|||
}
|
||||
|
||||
int SessionController::minimalThreeColumnWidth() const {
|
||||
return (_isPrimary ? st::columnMinimalWidthLeft : 0)
|
||||
return (_hasDialogs ? st::columnMinimalWidthLeft : 0)
|
||||
+ st::columnMinimalWidthMain
|
||||
+ st::columnMinimalWidthThird;
|
||||
}
|
||||
|
@ -1903,7 +1990,7 @@ auto SessionController::computeColumnLayout() const -> ColumnLayout {
|
|||
auto useOneColumnLayout = [&] {
|
||||
auto minimalNormal = st::columnMinimalWidthLeft
|
||||
+ st::columnMinimalWidthMain;
|
||||
if (_isPrimary && bodyWidth < minimalNormal) {
|
||||
if (_hasDialogs && bodyWidth < minimalNormal) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1945,7 +2032,7 @@ auto SessionController::computeColumnLayout() const -> ColumnLayout {
|
|||
}
|
||||
|
||||
int SessionController::countDialogsWidthFromRatio(int bodyWidth) const {
|
||||
if (!_isPrimary) {
|
||||
if (!_hasDialogs) {
|
||||
return 0;
|
||||
}
|
||||
const auto nochat = !mainSectionShown();
|
||||
|
@ -1979,8 +2066,8 @@ SessionController::ShrinkResult SessionController::shrinkDialogsAndThirdColumns(
|
|||
if (thirdWidthNew < st::columnMinimalWidthThird) {
|
||||
thirdWidthNew = st::columnMinimalWidthThird;
|
||||
dialogsWidthNew = bodyWidth - thirdWidthNew - chatWidth;
|
||||
Assert(!_isPrimary || dialogsWidthNew >= st::columnMinimalWidthLeft);
|
||||
} else if (_isPrimary && dialogsWidthNew < st::columnMinimalWidthLeft) {
|
||||
Assert(!_hasDialogs || dialogsWidthNew >= st::columnMinimalWidthLeft);
|
||||
} else if (_hasDialogs && dialogsWidthNew < st::columnMinimalWidthLeft) {
|
||||
dialogsWidthNew = st::columnMinimalWidthLeft;
|
||||
thirdWidthNew = bodyWidth - dialogsWidthNew - chatWidth;
|
||||
Assert(thirdWidthNew >= st::columnMinimalWidthThird);
|
||||
|
@ -2089,9 +2176,11 @@ void SessionController::closeThirdSection() {
|
|||
}
|
||||
}
|
||||
|
||||
bool SessionController::canShowSeparateWindow(
|
||||
not_null<PeerData*> peer) const {
|
||||
return !peer->isForum() && peer->computeUnavailableReason().isEmpty();
|
||||
bool SessionController::canShowSeparateWindow(SeparateId id) const {
|
||||
if (const auto thread = id.thread) {
|
||||
return thread->peer()->computeUnavailableReason().isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SessionController::showPeer(not_null<PeerData*> peer, MsgId msgId) {
|
||||
|
@ -2314,21 +2403,20 @@ void SessionController::clearChooseReportMessages() const {
|
|||
}
|
||||
|
||||
void SessionController::showInNewWindow(
|
||||
not_null<PeerData*> peer,
|
||||
SeparateId id,
|
||||
MsgId msgId) {
|
||||
if (!canShowSeparateWindow(peer)) {
|
||||
showThread(
|
||||
peer->owner().history(peer),
|
||||
msgId,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
if (!canShowSeparateWindow(id)) {
|
||||
Assert(id.thread != nullptr);
|
||||
showThread(id.thread, msgId, SectionShow::Way::ClearStack);
|
||||
return;
|
||||
}
|
||||
const auto active = activeChatCurrent();
|
||||
const auto fromActive = active.history()
|
||||
? (active.history()->peer == peer)
|
||||
// windows check active forum / active archive
|
||||
const auto fromActive = active.thread()
|
||||
? (active.thread() == id.thread)
|
||||
: false;
|
||||
const auto toSeparate = [=] {
|
||||
Core::App().ensureSeparateWindowForPeer(peer, msgId);
|
||||
Core::App().ensureSeparateWindowFor(id, msgId);
|
||||
};
|
||||
if (fromActive) {
|
||||
window().preventOrInvoke([=] {
|
||||
|
@ -2485,6 +2573,9 @@ FilterId SessionController::activeChatsFilterCurrent() const {
|
|||
void SessionController::setActiveChatsFilter(
|
||||
FilterId id,
|
||||
const SectionShow ¶ms) {
|
||||
if (!isPrimary()) {
|
||||
return;
|
||||
}
|
||||
const auto changed = (activeChatsFilterCurrent() != id);
|
||||
if (changed) {
|
||||
resetFakeUnreadWhileOpened();
|
||||
|
|
|
@ -91,6 +91,7 @@ class FiltersMenu;
|
|||
class ChatPreviewManager;
|
||||
|
||||
struct PeerByLinkInfo;
|
||||
struct SeparateId;
|
||||
|
||||
struct PeerThemeOverride {
|
||||
PeerData *peer = nullptr;
|
||||
|
@ -232,6 +233,10 @@ public:
|
|||
ShowAtUnreadMsgId);
|
||||
}
|
||||
|
||||
void showByInitialId(
|
||||
const SectionShow ¶ms = SectionShow::Way::ClearStack,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
|
||||
void showSettings(
|
||||
Settings::Type type,
|
||||
const SectionShow ¶ms = SectionShow());
|
||||
|
@ -326,7 +331,7 @@ public:
|
|||
[[nodiscard]] Controller &window() const {
|
||||
return *_window;
|
||||
}
|
||||
[[nodiscard]] PeerData *singlePeer() const;
|
||||
[[nodiscard]] SeparateId windowId() const;
|
||||
[[nodiscard]] bool isPrimary() const;
|
||||
[[nodiscard]] not_null<::MainWindow*> widget() const;
|
||||
[[nodiscard]] not_null<MainWidget*> content() const;
|
||||
|
@ -432,7 +437,7 @@ public:
|
|||
void resizeForThirdSection();
|
||||
void closeThirdSection();
|
||||
|
||||
[[nodiscard]] bool canShowSeparateWindow(not_null<PeerData*> peer) const;
|
||||
[[nodiscard]] bool canShowSeparateWindow(SeparateId id) const;
|
||||
void showPeer(not_null<PeerData*> peer, MsgId msgId = ShowAtUnreadMsgId);
|
||||
|
||||
void startOrJoinGroupCall(not_null<PeerData*> peer);
|
||||
|
@ -509,7 +514,7 @@ public:
|
|||
void clearChooseReportMessages() const;
|
||||
|
||||
void showInNewWindow(
|
||||
not_null<PeerData*> peer,
|
||||
SeparateId id,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
|
||||
void toggleChooseChatTheme(
|
||||
|
@ -667,10 +672,16 @@ private:
|
|||
void checkNonPremiumLimitToastDownload(DocumentId id);
|
||||
void checkNonPremiumLimitToastUpload(FullMsgId id);
|
||||
|
||||
bool openFolderInDifferentWindow(not_null<Data::Folder*> folder);
|
||||
bool showForumInDifferentWindow(
|
||||
not_null<Data::Forum*> forum,
|
||||
const SectionShow ¶ms);
|
||||
|
||||
const not_null<Controller*> _window;
|
||||
const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions;
|
||||
const std::unique_ptr<ChatPreviewManager> _chatPreviewManager;
|
||||
const bool _isPrimary = false;
|
||||
const bool _hasDialogs = false;
|
||||
|
||||
mutable std::shared_ptr<ChatHelpers::Show> _cachedShow;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue