Implement simple sub-column for topics list.

This commit is contained in:
John Preston 2022-11-30 10:31:33 +04:00
parent beaea9c57d
commit 5d8a2bc7b7
16 changed files with 321 additions and 182 deletions

View file

@ -116,14 +116,11 @@ void CheckChatInvite(
} }
Core::App().hideMediaView(); Core::App().hideMediaView();
const auto show = [&](not_null<PeerData*> chat) { const auto show = [&](not_null<PeerData*> chat) {
const auto way = Window::SectionShow::Way::Forward;
if (const auto forum = chat->forum()) { if (const auto forum = chat->forum()) {
strong->openForum( strong->showForum(forum, way);
forum->channel(),
Window::SectionShow::Way::Forward);
} else { } else {
strong->showPeerHistory( strong->showPeerHistory(chat, way);
chat,
Window::SectionShow::Way::Forward);
} }
}; };
result.match([=](const MTPDchatInvite &data) { result.match([=](const MTPDchatInvite &data) {

View file

@ -1241,8 +1241,10 @@ void Application::closeChatFromWindows(not_null<PeerData*> peer) {
PeerId(0), PeerId(0),
Window::SectionShow::Way::ClearStack); Window::SectionShow::Way::ClearStack);
} }
if (primary->openedForum().current() == peer) { if (const auto forum = primary->shownForum().current()) {
primary->closeForum(); if (peer->forum() == forum) {
primary->closeForum();
}
} }
} }
} }

View file

@ -149,6 +149,9 @@ InnerWidget::InnerWidget(
, _pinnedShiftAnimation([=](crl::time now) { , _pinnedShiftAnimation([=](crl::time now) {
return pinnedShiftAnimationCallback(now); return pinnedShiftAnimationCallback(now);
}) })
, _narrowWidth(st::defaultDialogRow.padding.left()
+ st::defaultDialogRow.photoSize
+ st::defaultDialogRow.padding.left())
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer) , _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) { , _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
setAttribute(Qt::WA_OpaquePaintEvent, true); setAttribute(Qt::WA_OpaquePaintEvent, true);
@ -487,9 +490,8 @@ void InnerWidget::changeOpenedFolder(Data::Folder *folder) {
} }
} }
void InnerWidget::changeOpenedForum(ChannelData *forum) { void InnerWidget::changeOpenedForum(Data::Forum *forum) {
const auto now = _openedForum ? _openedForum->channel().get() : nullptr; if (_openedForum == forum) {
if (now == forum) {
return; return;
} }
stopReorderPinned(); stopReorderPinned();
@ -501,19 +503,19 @@ void InnerWidget::changeOpenedForum(ChannelData *forum) {
_filterId = forum _filterId = forum
? 0 ? 0
: _controller->activeChatsFilterCurrent(); : _controller->activeChatsFilterCurrent();
if (const auto old = now ? now->forum() : nullptr) { if (_openedForum) {
// If we close it inside forum destruction we should not schedule. // If we close it inside forum destruction we should not schedule.
old->owner().forumIcons().scheduleUserpicsReset(old); session().data().forumIcons().scheduleUserpicsReset(_openedForum);
} }
_openedForum = forum ? forum->forum() : nullptr; _openedForum = forum;
_st = forum ? &st::forumTopicRow : &st::defaultDialogRow; _st = forum ? &st::forumTopicRow : &st::defaultDialogRow;
refreshShownList(); refreshShownList();
_openedForumLifetime.destroy(); _openedForumLifetime.destroy();
if (forum) { if (forum) {
rpl::merge( rpl::merge(
forum->forum()->chatsListChanges(), forum->chatsListChanges(),
forum->forum()->chatsListLoadedEvents() forum->chatsListLoadedEvents()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
refresh(); refresh();
}, _openedForumLifetime); }, _openedForumLifetime);
@ -571,7 +573,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
&& _selectedTopicJump && _selectedTopicJump
&& (!_pressed || _pressedTopicJump)), && (!_pressed || _pressedTopicJump)),
.paused = videoPaused, .paused = videoPaused,
.narrow = (fullWidth < st::columnMinimalWidthLeft), .narrow = (fullWidth < st::columnMinimalWidthLeft / 2),
}); });
}; };
if (_state == WidgetState::Default) { if (_state == WidgetState::Default) {
@ -826,7 +828,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
.selected = selected, .selected = selected,
.paused = videoPaused, .paused = videoPaused,
.search = true, .search = true,
.narrow = (fullWidth < st::columnMinimalWidthLeft), .narrow = (fullWidth < st::columnMinimalWidthLeft / 2),
.displayUnreadInfo = showUnreadInSearchResults, .displayUnreadInfo = showUnreadInSearchResults,
}); });
p.translate(0, _st->height); p.translate(0, _st->height);
@ -896,7 +898,7 @@ void InnerWidget::paintCollapsedRow(
.st = _st, .st = _st,
.width = fullWidth, .width = fullWidth,
.selected = selected, .selected = selected,
.narrow = (fullWidth < st::columnMinimalWidthLeft), .narrow = (fullWidth < st::columnMinimalWidthLeft / 2),
}); });
} }
@ -1698,7 +1700,9 @@ void InnerWidget::resizeEvent(QResizeEvent *e) {
} }
void InnerWidget::moveCancelSearchButtons() { void InnerWidget::moveCancelSearchButtons() {
const auto widthForCancelButton = qMax(width(), st::columnMinimalWidthLeft); const auto widthForCancelButton = qMax(
width(),
st::columnMinimalWidthLeft - _narrowWidth);
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width(); const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width();
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2; const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
_cancelSearchInChat->moveToLeft(left, st::searchedBarHeight + top); _cancelSearchInChat->moveToLeft(left, st::searchedBarHeight + top);

View file

@ -102,7 +102,7 @@ public:
void clearSelection(); void clearSelection();
void changeOpenedFolder(Data::Folder *folder); void changeOpenedFolder(Data::Folder *folder);
void changeOpenedForum(ChannelData *forum); void changeOpenedForum(Data::Forum *forum);
void selectSkip(int32 direction); void selectSkip(int32 direction);
void selectSkipPage(int32 pixels, int32 direction); void selectSkipPage(int32 pixels, int32 direction);
@ -422,6 +422,7 @@ private:
// Remember the last currently dragged row top shift for updating area. // Remember the last currently dragged row top shift for updating area.
int _aboveTopShift = -1; int _aboveTopShift = -1;
int _narrowWidth = 0;
int _visibleTop = 0; int _visibleTop = 0;
int _visibleBottom = 0; int _visibleBottom = 0;

View file

@ -178,10 +178,15 @@ void Widget::BottomButton::paintEvent(QPaintEvent *e) {
Widget::Widget( Widget::Widget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller,
Layout layout)
: Window::AbstractSectionWidget(parent, controller, nullptr) : Window::AbstractSectionWidget(parent, controller, nullptr)
, _api(&controller->session().mtp()) , _api(&controller->session().mtp())
, _chooseByDragTimer([=] { _inner->chooseRow(); }) , _chooseByDragTimer([=] { _inner->chooseRow(); })
, _layout(layout)
, _narrowWidth(st::defaultDialogRow.padding.left()
+ st::defaultDialogRow.photoSize
+ st::defaultDialogRow.padding.left())
, _searchControls(this) , _searchControls(this)
, _mainMenuToggle(_searchControls, st::dialogsMenuToggle) , _mainMenuToggle(_searchControls, st::dialogsMenuToggle)
, _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters) , _searchForNarrowFilters(_searchControls, st::dialogsSearchForNarrowFilters)
@ -216,7 +221,7 @@ Widget::Widget(
Data::HistoryUpdate::Flag::MessageSent Data::HistoryUpdate::Flag::MessageSent
) | rpl::filter([=](const Data::HistoryUpdate &update) { ) | rpl::filter([=](const Data::HistoryUpdate &update) {
if (_openedForum) { if (_openedForum) {
return (update.history->peer == _openedForum); return (update.history == _openedForum->history());
} else if (_openedFolder) { } else if (_openedFolder) {
return (update.history->folder() == _openedFolder) return (update.history->folder() == _openedFolder)
&& !update.history->isPinnedDialog(FilterId()); && !update.history->isPinnedDialog(FilterId());
@ -273,7 +278,7 @@ Widget::Widget(
_inner->cancelSearchFromUserRequests( _inner->cancelSearchFromUserRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
setSearchInChat((_openedForum && !_searchInChat) setSearchInChat((_openedForum && !_searchInChat)
? Key(_openedForum->forum()->history()) ? Key(_openedForum->history())
: _searchInChat, nullptr); : _searchInChat, nullptr);
applyFilterUpdate(true); applyFilterUpdate(true);
}, lifetime()); }, lifetime());
@ -346,7 +351,10 @@ Widget::Widget(
setupShortcuts(); setupShortcuts();
_searchForNarrowFilters->setClickedCallback([=] { _searchForNarrowFilters->setClickedCallback([=] {
Ui::showChatsList(&session()); if (_childList) {
controller->closeForum();
}
_filter->setFocus();
}); });
setAcceptDrops(true); setAcceptDrops(true);
@ -368,7 +376,7 @@ Widget::Widget(
&& !_searchFullMigrated))) { && !_searchFullMigrated))) {
searchMore(); searchMore();
} else if (_openedForum && state == WidgetState::Default) { } else if (_openedForum && state == WidgetState::Default) {
_openedForum->forum()->requestTopics(); _openedForum->requestTopics();
} else { } else {
const auto folder = _inner->shownFolder(); const auto folder = _inner->shownFolder();
if (!folder || !folder->chatsList()->loaded()) { if (!folder || !folder->chatsList()->loaded()) {
@ -399,14 +407,19 @@ Widget::Widget(
changeOpenedFolder(folder, anim::type::normal); changeOpenedFolder(folder, anim::type::normal);
}, lifetime()); }, lifetime());
changeOpenedForum( if (_layout != Layout::Child) {
controller->openedForum().current(), controller->shownForum().changes(
anim::type::instant); ) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] {
if (_openedForum) {
controller->openedForum().changes( changeOpenedForum(nullptr, anim::type::normal);
) | rpl::start_with_next([=](ChannelData *forum) { } else if (_childList) {
changeOpenedForum(forum, anim::type::normal); _childList = nullptr;
}, lifetime()); _childListShadow = nullptr;
updateControlsGeometry();
updateControlsVisibility(true);
}
}, lifetime());
}
setupDownloadBar(); setupDownloadBar();
} }
@ -420,7 +433,9 @@ void Widget::chosenRow(const ChosenRow &row) {
: nullptr; : nullptr;
if (topicJump) { if (topicJump) {
if (!controller()->adaptive().isOneColumn()) { if (!controller()->adaptive().isOneColumn()) {
controller()->openForum(history->peer->asChannel()); controller()->showForum(
topicJump->forum(),
Window::SectionShow().withChildColumn());
} }
controller()->content()->chooseThread( controller()->content()->chooseThread(
topicJump, topicJump,
@ -431,7 +446,9 @@ void Widget::chosenRow(const ChosenRow &row) {
topic, topic,
row.message.fullId.msg); row.message.fullId.msg);
} else if (history && history->peer->isForum() && !row.message.fullId) { } else if (history && history->peer->isForum() && !row.message.fullId) {
controller()->openForum(history->peer->asChannel()); controller()->showForum(
history->peer->forum(),
Window::SectionShow().withChildColumn());
return; return;
} else if (history) { } else if (history) {
const auto peer = history->peer; const auto peer = history->peer;
@ -450,19 +467,18 @@ void Widget::chosenRow(const ChosenRow &row) {
}; };
if (fromActive) { if (fromActive) {
controller()->window().preventOrInvoke([=] { controller()->window().preventOrInvoke([=] {
controller()->content()->ui_showPeerHistory( controller()->clearSectionStack();
0,
Window::SectionShow::Way::ClearStack,
0);
toSeparate(); toSeparate();
}); });
} else { } else {
toSeparate(); toSeparate();
} }
} else { } else {
hideChildList();
controller()->content()->chooseThread(history, showAtMsgId); controller()->content()->chooseThread(history, showAtMsgId);
} }
} else if (const auto folder = row.key.folder()) { } else if (const auto folder = row.key.folder()) {
hideChildList();
controller()->openFolder(folder); controller()->openFolder(folder);
} }
if (openSearchResult && !session().supportMode()) { if (openSearchResult && !session().supportMode()) {
@ -576,7 +592,8 @@ void Widget::updateScrollUpVisibility() {
} }
void Widget::startScrollUpButtonAnimation(bool shown) { void Widget::startScrollUpButtonAnimation(bool shown) {
const auto smallColumn = (width() < st::columnMinimalWidthLeft); const auto smallColumn = (width() < st::columnMinimalWidthLeft)
|| _childList;
shown &= !smallColumn; shown &= !smallColumn;
if (_scrollToTopIsShown == shown) { if (_scrollToTopIsShown == shown) {
return; return;
@ -659,7 +676,7 @@ void Widget::setupShortcuts() {
} }
if (_openedForum && !controller()->activeChatCurrent()) { if (_openedForum && !controller()->activeChatCurrent()) {
request->check(Command::Search) && request->handle([=] { request->check(Command::Search) && request->handle([=] {
const auto history = _openedForum->forum()->history(); const auto history = _openedForum->history();
controller()->content()->searchInChat(history); controller()->content()->searchInChat(history);
return true; return true;
}); });
@ -723,6 +740,10 @@ void Widget::updateControlsVisibility(bool fast) {
updateSearchFromVisibility(fast); updateSearchFromVisibility(fast);
} }
_connecting->setForceHidden(false); _connecting->setForceHidden(false);
if (_childList) {
_childList->show();
_childListShadow->show();
}
} }
void Widget::changeOpenedSubsection( void Widget::changeOpenedSubsection(
@ -761,7 +782,7 @@ void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
}, (folder != nullptr), animated); }, (folder != nullptr), animated);
} }
void Widget::changeOpenedForum(ChannelData *forum, anim::type animated) { void Widget::changeOpenedForum(Data::Forum *forum, anim::type animated) {
changeOpenedSubsection([&] { changeOpenedSubsection([&] {
cancelSearch(); cancelSearch();
_openedForum = forum; _openedForum = forum;
@ -770,6 +791,12 @@ void Widget::changeOpenedForum(ChannelData *forum, anim::type animated) {
}, (forum != nullptr), animated); }, (forum != nullptr), animated);
} }
void Widget::hideChildList() {
if (_childList) {
controller()->closeForum();
}
}
void Widget::refreshTopBars() { void Widget::refreshTopBars() {
if (_openedFolder || _openedForum) { if (_openedFolder || _openedForum) {
if (!_subsectionTopBar) { if (!_subsectionTopBar) {
@ -797,7 +824,7 @@ void Widget::refreshTopBars() {
updateControlsGeometry(); updateControlsGeometry();
} }
const auto history = _openedForum const auto history = _openedForum
? session().data().history(_openedForum).get() ? _openedForum->history().get()
: nullptr; : nullptr;
_subsectionTopBar->setActiveChat( _subsectionTopBar->setActiveChat(
HistoryView::TopBarWidget::ActiveChat{ HistoryView::TopBarWidget::ActiveChat{
@ -817,23 +844,24 @@ void Widget::refreshTopBars() {
} }
_forumSearchRequested = false; _forumSearchRequested = false;
if (_openedForum) { if (_openedForum) {
_openedForum->updateFull(); const auto channel = _openedForum->channel();
channel->updateFull();
_forumReportBar = std::make_unique<HistoryView::ContactStatus>( _forumReportBar = std::make_unique<HistoryView::ContactStatus>(
controller(), controller(),
this, this,
_openedForum, channel,
true); true);
_forumRequestsBar = std::make_unique<Ui::RequestsBar>( _forumRequestsBar = std::make_unique<Ui::RequestsBar>(
this, this,
HistoryView::RequestsBarContentByPeer( HistoryView::RequestsBarContentByPeer(
_openedForum, channel,
st::historyRequestsUserpics.size, st::historyRequestsUserpics.size,
true)); true));
_forumGroupCallBar = std::make_unique<Ui::GroupCallBar>( _forumGroupCallBar = std::make_unique<Ui::GroupCallBar>(
this, this,
HistoryView::GroupCallBarContentByPeer( HistoryView::GroupCallBarContentByPeer(
_openedForum, channel,
st::historyGroupCallUserpics.size, st::historyGroupCallUserpics.size,
true), true),
Core::App().appDeactivatedValue()); Core::App().appDeactivatedValue());
@ -841,15 +869,15 @@ void Widget::refreshTopBars() {
_forumRequestsBar->barClicks( _forumRequestsBar->barClicks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
RequestsBoxController::Start(controller(), _openedForum); RequestsBoxController::Start(controller(), channel);
}, _forumRequestsBar->lifetime()); }, _forumRequestsBar->lifetime());
rpl::merge( rpl::merge(
_forumGroupCallBar->barClicks(), _forumGroupCallBar->barClicks(),
_forumGroupCallBar->joinClicks() _forumGroupCallBar->joinClicks()
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (_openedForum->groupCall()) { if (channel->groupCall()) {
controller()->startOrJoinGroupCall(_openedForum); controller()->startOrJoinGroupCall(channel);
} }
}, _forumGroupCallBar->lifetime()); }, _forumGroupCallBar->lifetime());
@ -959,7 +987,7 @@ void Widget::jumpToTop(bool belowPinned) {
auto to = 0; auto to = 0;
if (belowPinned) { if (belowPinned) {
const auto list = _openedForum const auto list = _openedForum
? _openedForum->forum()->topicsList() ? _openedForum->topicsList()
: controller()->activeChatsFilterCurrent() : controller()->activeChatsFilterCurrent()
? session().data().chatsFilters().chatsList( ? session().data().chatsFilters().chatsList(
controller()->activeChatsFilterCurrent()) controller()->activeChatsFilterCurrent())
@ -1113,7 +1141,7 @@ void Widget::animationCallback() {
void Widget::escape() { void Widget::escape() {
if (!cancelSearch()) { if (!cancelSearch()) {
if (controller()->openedForum().current()) { if (controller()->shownForum().current()) {
controller()->closeForum(); controller()->closeForum();
} else if (controller()->openedFolder().current()) { } else if (controller()->openedFolder().current()) {
controller()->closeFolder(); controller()->closeFolder();
@ -1351,7 +1379,7 @@ bool Widget::searchForTopicsRequired(const QString &query) const {
&& _openedForum && _openedForum
&& !query.isEmpty() && !query.isEmpty()
&& (query[0] != '#') && (query[0] != '#')
&& !_openedForum->forum()->topicsList()->loaded(); && !_openedForum->topicsList()->loaded();
} }
void Widget::needSearchMessages() { void Widget::needSearchMessages() {
@ -1370,7 +1398,7 @@ void Widget::searchMessages(
const auto inChatChanged = [&] { const auto inChatChanged = [&] {
const auto inPeer = inChat.peer(); const auto inPeer = inChat.peer();
const auto inTopic = inChat.topic(); const auto inTopic = inChat.topic();
if (!inTopic && inPeer == _openedForum) { if (!inTopic && _openedForum && inPeer == _openedForum->channel()) {
return false; return false;
} else if ((inTopic || (inPeer && !inPeer->isForum())) } else if ((inTopic || (inPeer && !inPeer->isForum()))
&& (inChat == _searchInChat)) { && (inChat == _searchInChat)) {
@ -1404,7 +1432,7 @@ void Widget::searchTopics() {
_api.request(base::take(_topicSearchRequest)).cancel(); _api.request(base::take(_topicSearchRequest)).cancel();
_topicSearchRequest = _api.request(MTPchannels_GetForumTopics( _topicSearchRequest = _api.request(MTPchannels_GetForumTopics(
MTP_flags(MTPchannels_GetForumTopics::Flag::f_q), MTP_flags(MTPchannels_GetForumTopics::Flag::f_q),
_openedForum->inputChannel, _openedForum->channel()->inputChannel,
MTP_string(_topicSearchQuery), MTP_string(_topicSearchQuery),
MTP_int(_topicSearchOffsetDate), MTP_int(_topicSearchOffsetDate),
MTP_int(_topicSearchOffsetId), MTP_int(_topicSearchOffsetId),
@ -1414,7 +1442,7 @@ void Widget::searchTopics() {
_topicSearchRequest = 0; _topicSearchRequest = 0;
const auto savedTopicId = _topicSearchOffsetTopicId; const auto savedTopicId = _topicSearchOffsetTopicId;
const auto byCreation = result.data().is_order_by_create_date(); const auto byCreation = result.data().is_order_by_create_date();
_openedForum->forum()->applyReceivedTopics(result, [&]( _openedForum->applyReceivedTopics(result, [&](
not_null<Data::ForumTopic*> topic) { not_null<Data::ForumTopic*> topic) {
_topicSearchOffsetTopicId = topic->rootId(); _topicSearchOffsetTopicId = topic->rootId();
if (byCreation) { if (byCreation) {
@ -1826,6 +1854,9 @@ void Widget::dropEvent(QDropEvent *e) {
const auto point = mapToGlobal(e->pos()); const auto point = mapToGlobal(e->pos());
if (const auto thread = _inner->updateFromParentDrag(point)) { if (const auto thread = _inner->updateFromParentDrag(point)) {
e->acceptProposedAction(); e->acceptProposedAction();
if (!thread->owningHistory()->peer->isForum()) {
hideChildList();
}
controller()->content()->onFilesOrForwardDrop( controller()->content()->onFilesOrForwardDrop(
thread, thread,
e->mimeData()); e->mimeData());
@ -1877,6 +1908,39 @@ void Widget::applyFilterUpdate(bool force) {
_lastFilterText = filterText; _lastFilterText = filterText;
} }
void Widget::showForum(
not_null<Data::Forum*> forum,
const Window::SectionShow &params) {
if (!params.childColumn
|| !Core::App().settings().dialogsWidthRatio()
|| (_layout != Layout::Main)) {
changeOpenedForum(forum, params.animated);
return;
}
cancelSearch();
auto copy = params;
copy.childColumn = false;
copy.animated = anim::type::instant;
_childList = std::make_unique<Widget>(
this,
controller(),
Layout::Child);
_childList->showForum(forum, copy);
_childListShadow = std::make_unique<Ui::RpWidget>(this);
_childListShadow->setAttribute(Qt::WA_TransparentForMouseEvents);
_childListShadow->paintRequest(
) | rpl::start_with_next([=] {
auto p = QPainter(_childListShadow.get());
st::slideShadow.fill(p, QRect(
_childListShadow->width() - st::slideShadow.width(),
0,
st::slideShadow.width(),
_childListShadow->height()));
}, _childListShadow->lifetime());
updateControlsGeometry();
updateControlsVisibility(true);
}
void Widget::searchInChat(Key chat) { void Widget::searchInChat(Key chat) {
if (_openedForum && !chat.peer()->forum()) { if (_openedForum && !chat.peer()->forum()) {
controller()->closeForum(); controller()->closeForum();
@ -1889,7 +1953,13 @@ void Widget::searchInChat(Key chat) {
applyFilterUpdate(true); applyFilterUpdate(true);
} }
void Widget::setSearchInChat(Key chat, PeerData *from) { bool Widget::setSearchInChat(Key chat, PeerData *from) {
if (_childList) {
if (_childList->setSearchInChat(chat, from)) {
return true;
}
hideChildList();
}
const auto peer = chat.peer(); const auto peer = chat.peer();
const auto topic = chat.topic(); const auto topic = chat.topic();
const auto forum = peer ? peer->forum() : nullptr; const auto forum = peer ? peer->forum() : nullptr;
@ -1907,11 +1977,13 @@ void Widget::setSearchInChat(Key chat, PeerData *from) {
_searchFromAuthor = from; _searchFromAuthor = from;
if (forum) { if (forum) {
if (controller()->openedForum().current() == peer) { if (_openedForum == forum) {
showSearchInTopBar(anim::type::normal); showSearchInTopBar(anim::type::normal);
} else { } else if (_layout == Layout::Main) {
_forumSearchRequested = true; _forumSearchRequested = true;
controller()->openForum(forum->channel()); controller()->showForum(forum);
} else {
return false;
} }
} }
_searchInMigrated = nullptr; _searchInMigrated = nullptr;
@ -1943,6 +2015,7 @@ void Widget::setSearchInChat(Key chat, PeerData *from) {
cancelSearch(); cancelSearch();
} }
_filter->setFocus(); _filter->setFocus();
return true;
} }
void Widget::clearSearchCache() { void Widget::clearSearchCache() {
@ -1971,7 +2044,7 @@ void Widget::showSearchFrom() {
if (const auto peer = searchInPeer()) { if (const auto peer = searchInPeer()) {
const auto weak = base::make_weak(_searchInChat.topic()); const auto weak = base::make_weak(_searchInChat.topic());
const auto chat = (!_searchInChat && _openedForum) const auto chat = (!_searchInChat && _openedForum)
? Key(_openedForum->forum()->history()) ? Key(_openedForum->history())
: _searchInChat; : _searchInChat;
auto box = SearchFromBox( auto box = SearchFromBox(
peer, peer,
@ -2107,25 +2180,37 @@ void Widget::updateControlsGeometry() {
_forwardCancel->moveToLeft(0, filterAreaTop); _forwardCancel->moveToLeft(0, filterAreaTop);
filterAreaTop += st::dialogsForwardHeight; filterAreaTop += st::dialogsForwardHeight;
} }
auto smallLayoutWidth = (st::defaultDialogRow.padding.left() + st::defaultDialogRow.photoSize + st::defaultDialogRow.padding.left()); const auto usew = _childList ? _narrowWidth : width();
auto smallLayoutRatio = (width() < st::columnMinimalWidthLeft) ? (st::columnMinimalWidthLeft - width()) / float64(st::columnMinimalWidthLeft - smallLayoutWidth) : 0.; const auto childw = std::max(_narrowWidth, width() - usew);
auto filterLeft = (controller()->filtersWidth() ? st::dialogsFilterSkip : st::dialogsFilterPadding.x() + _mainMenuToggle->width()) + st::dialogsFilterPadding.x(); const auto smallw = st::columnMinimalWidthLeft - _narrowWidth;
auto filterRight = (session().domain().local().hasLocalPasscode() ? (st::dialogsFilterPadding.x() + _lockUnlock->width()) : st::dialogsFilterSkip) + st::dialogsFilterPadding.x(); const auto smallLayoutRatio = (usew < smallw)
auto filterWidth = qMax(width(), st::columnMinimalWidthLeft) - filterLeft - filterRight; ? ((smallw - usew) / float64(smallw - _narrowWidth))
: 0.;
auto filterLeft = (controller()->filtersWidth()
? st::dialogsFilterSkip
: (st::dialogsFilterPadding.x() + _mainMenuToggle->width()))
+ st::dialogsFilterPadding.x();
auto filterRight = (session().domain().local().hasLocalPasscode()
? (st::dialogsFilterPadding.x() + _lockUnlock->width())
: st::dialogsFilterSkip) + st::dialogsFilterPadding.x();
auto filterWidth = qMax(usew, smallw) - filterLeft - filterRight;
auto filterAreaHeight = st::topBarHeight; auto filterAreaHeight = st::topBarHeight;
_searchControls->setGeometry(0, filterAreaTop, width(), filterAreaHeight); _searchControls->setGeometry(0, filterAreaTop, usew, filterAreaHeight);
if (_subsectionTopBar) { if (_subsectionTopBar) {
_subsectionTopBar->setGeometry(_searchControls->geometry()); _subsectionTopBar->setGeometry(_searchControls->geometry());
} }
auto filterTop = (filterAreaHeight - _filter->height()) / 2; auto filterTop = (filterAreaHeight - _filter->height()) / 2;
filterLeft = anim::interpolate(filterLeft, smallLayoutWidth, smallLayoutRatio); filterLeft = anim::interpolate(filterLeft, _narrowWidth, smallLayoutRatio);
_filter->setGeometryToLeft(filterLeft, filterTop, filterWidth, _filter->height()); _filter->setGeometryToLeft(filterLeft, filterTop, filterWidth, _filter->height());
auto mainMenuLeft = anim::interpolate(st::dialogsFilterPadding.x(), (smallLayoutWidth - _mainMenuToggle->width()) / 2, smallLayoutRatio); auto mainMenuLeft = anim::interpolate(
st::dialogsFilterPadding.x(),
(_narrowWidth - _mainMenuToggle->width()) / 2,
smallLayoutRatio);
_mainMenuToggle->moveToLeft(mainMenuLeft, st::dialogsFilterPadding.y()); _mainMenuToggle->moveToLeft(mainMenuLeft, st::dialogsFilterPadding.y());
const auto searchLeft = anim::interpolate( const auto searchLeft = anim::interpolate(
-_searchForNarrowFilters->width(), -_searchForNarrowFilters->width(),
(smallLayoutWidth - _searchForNarrowFilters->width()) / 2, (_narrowWidth - _searchForNarrowFilters->width()) / 2,
smallLayoutRatio); smallLayoutRatio);
_searchForNarrowFilters->moveToLeft(searchLeft, st::dialogsFilterPadding.y()); _searchForNarrowFilters->moveToLeft(searchLeft, st::dialogsFilterPadding.y());
@ -2139,19 +2224,19 @@ void Widget::updateControlsGeometry() {
_forumTopShadow->setGeometry( _forumTopShadow->setGeometry(
0, 0,
filterAreaTop + filterAreaHeight, filterAreaTop + filterAreaHeight,
width(), usew,
st::lineWidth); st::lineWidth);
} }
const auto forumGroupCallTop = filterAreaTop + filterAreaHeight; const auto forumGroupCallTop = filterAreaTop + filterAreaHeight;
if (_forumGroupCallBar) { if (_forumGroupCallBar) {
_forumGroupCallBar->move(0, forumGroupCallTop); _forumGroupCallBar->move(0, forumGroupCallTop);
_forumGroupCallBar->resizeToWidth(width()); _forumGroupCallBar->resizeToWidth(usew);
} }
const auto forumRequestsTop = forumGroupCallTop const auto forumRequestsTop = forumGroupCallTop
+ (_forumGroupCallBar ? _forumGroupCallBar->height() : 0); + (_forumGroupCallBar ? _forumGroupCallBar->height() : 0);
if (_forumRequestsBar) { if (_forumRequestsBar) {
_forumRequestsBar->move(0, forumRequestsTop); _forumRequestsBar->move(0, forumRequestsTop);
_forumRequestsBar->resizeToWidth(width()); _forumRequestsBar->resizeToWidth(usew);
} }
const auto forumReportTop = forumRequestsTop const auto forumReportTop = forumRequestsTop
+ (_forumRequestsBar ? _forumRequestsBar->height() : 0); + (_forumRequestsBar ? _forumRequestsBar->height() : 0);
@ -2169,7 +2254,7 @@ void Widget::updateControlsGeometry() {
button->setGeometry( button->setGeometry(
0, 0,
scrollTop + scrollHeight, scrollTop + scrollHeight,
width(), usew,
buttonHeight); buttonHeight);
} }
}; };
@ -2182,8 +2267,8 @@ void Widget::updateControlsGeometry() {
} }
controller()->setConnectingBottomSkip(bottomSkip); controller()->setConnectingBottomSkip(bottomSkip);
auto wasScrollHeight = _scroll->height(); auto wasScrollHeight = _scroll->height();
_scroll->setGeometry(0, scrollTop, width(), scrollHeight); _scroll->setGeometry(0, scrollTop, usew, scrollHeight);
_inner->resize(width(), _inner->height()); _inner->resize(usew, _inner->height());
if (scrollHeight != wasScrollHeight) { if (scrollHeight != wasScrollHeight) {
controller()->floatPlayerAreaUpdated(); controller()->floatPlayerAreaUpdated();
} }
@ -2195,6 +2280,13 @@ void Widget::updateControlsGeometry() {
if (_scrollToTopIsShown) { if (_scrollToTopIsShown) {
updateScrollUpPosition(); updateScrollUpPosition();
} }
if (_childList) {
_childList->setGeometryWithTopMoved(
{ width() - childw, 0, childw, height() },
_topDelta);
_childListShadow->setGeometry(0, 0, (width() - childw), height());
}
} }
rpl::producer<> Widget::closeForwardBarRequests() const { rpl::producer<> Widget::closeForwardBarRequests() const {
@ -2322,7 +2414,9 @@ void Widget::cancelSearchRequest() {
} }
PeerData *Widget::searchInPeer() const { PeerData *Widget::searchInPeer() const {
return _openedForum ? _openedForum : _searchInChat.peer(); return _openedForum
? _openedForum->channel().get()
: _searchInChat.peer();
} }
Data::ForumTopic *Widget::searchInTopic() const { Data::ForumTopic *Widget::searchInTopic() const {

View file

@ -20,6 +20,10 @@ namespace MTP {
class Error; class Error;
} // namespace MTP } // namespace MTP
namespace Data {
class Forum;
} // namespace Data
namespace Main { namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
@ -47,6 +51,7 @@ class FadeWrapScaled;
namespace Window { namespace Window {
class SessionController; class SessionController;
class ConnectionState; class ConnectionState;
struct SectionShow;
} // namespace Window } // namespace Window
namespace Dialogs { namespace Dialogs {
@ -61,7 +66,14 @@ enum class SearchRequestType;
class Widget final : public Window::AbstractSectionWidget { class Widget final : public Window::AbstractSectionWidget {
public: public:
Widget(QWidget *parent, not_null<Window::SessionController*> controller); enum class Layout {
Main,
Child,
};
Widget(
QWidget *parent,
not_null<Window::SessionController*> controller,
Layout layout);
// When resizing the widget with top edge moved up or down and we // When resizing the widget with top edge moved up or down and we
// want to add this top movement to the scroll position, so inner // want to add this top movement to the scroll position, so inner
@ -70,6 +82,9 @@ public:
void updateDragInScroll(bool inScroll); void updateDragInScroll(bool inScroll);
void showForum(
not_null<Data::Forum*> forum,
const Window::SectionShow &params);
void searchInChat(Key chat); void searchInChat(Key chat);
void setInnerFocus(); void setInnerFocus();
@ -81,7 +96,9 @@ public:
bool hasTopBarShadow() const { bool hasTopBarShadow() const {
return true; return true;
} }
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params); void showAnimated(
Window::SlideDirection direction,
const Window::SectionSlideParams &params);
void showFast(); void showFast();
void scrollToEntry(const RowDescriptor &entry); void scrollToEntry(const RowDescriptor &entry);
@ -152,7 +169,7 @@ private:
void setupShortcuts(); void setupShortcuts();
[[nodiscard]] bool searchForPeersRequired(const QString &query) const; [[nodiscard]] bool searchForPeersRequired(const QString &query) const;
[[nodiscard]] bool searchForTopicsRequired(const QString &query) const; [[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
void setSearchInChat(Key chat, PeerData *from = nullptr); bool setSearchInChat(Key chat, PeerData *from = nullptr);
void showCalendar(); void showCalendar();
void showSearchFrom(); void showSearchFrom();
void showMainMenu(); void showMainMenu();
@ -171,8 +188,9 @@ private:
bool fromRight, bool fromRight,
anim::type animated); anim::type animated);
void changeOpenedFolder(Data::Folder *folder, anim::type animated); void changeOpenedFolder(Data::Folder *folder, anim::type animated);
void changeOpenedForum(ChannelData *forum, anim::type animated); void changeOpenedForum(Data::Forum *forum, anim::type animated);
QPixmap grabForFolderSlideAnimation(); void hideChildList();
[[nodiscard]] QPixmap grabForFolderSlideAnimation();
void startSlideAnimation(); void startSlideAnimation();
void fullSearchRefreshOn(rpl::producer<> events); void fullSearchRefreshOn(rpl::producer<> events);
@ -198,6 +216,8 @@ private:
bool _dragForward = false; bool _dragForward = false;
base::Timer _chooseByDragTimer; base::Timer _chooseByDragTimer;
Layout _layout = Layout::Main;
int _narrowWidth = 0;
object_ptr<Ui::IconButton> _forwardCancel = { nullptr }; object_ptr<Ui::IconButton> _forwardCancel = { nullptr };
object_ptr<Ui::RpWidget> _searchControls; object_ptr<Ui::RpWidget> _searchControls;
object_ptr<HistoryView::TopBarWidget> _subsectionTopBar = { nullptr } ; object_ptr<HistoryView::TopBarWidget> _subsectionTopBar = { nullptr } ;
@ -234,7 +254,7 @@ private:
bool _forumSearchRequested = false; bool _forumSearchRequested = false;
Data::Folder *_openedFolder = nullptr; Data::Folder *_openedFolder = nullptr;
ChannelData *_openedForum = nullptr; Data::Forum *_openedForum = nullptr;
Dialogs::Key _searchInChat; Dialogs::Key _searchInChat;
History *_searchInMigrated = nullptr; History *_searchInMigrated = nullptr;
PeerData *_searchFromAuthor = nullptr; PeerData *_searchFromAuthor = nullptr;
@ -277,6 +297,9 @@ private:
rpl::event_stream<> _closeForwardBarRequests; rpl::event_stream<> _closeForwardBarRequests;
std::unique_ptr<Widget> _childList;
std::unique_ptr<Ui::RpWidget> _childListShadow;
}; };
} // namespace Dialogs } // namespace Dialogs

View file

@ -35,46 +35,27 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "styles/style_chat.h" #include "styles/style_chat.h"
namespace {
[[nodiscard]] MainWidget *CheckMainWidget(not_null<Main::Session*> session) {
if (const auto m = App::main()) { // multi good
if (&m->session() == session) {
return m;
}
}
if (&Core::App().domain().active() != &session->account()) {
Core::App().domain().activate(&session->account());
}
if (const auto m = App::main()) { // multi good
if (&m->session() == session) {
return m;
}
}
return nullptr;
}
} // namespace
namespace Ui { namespace Ui {
void showChatsList(not_null<Main::Session*> session) { void showChatsList(not_null<Main::Session*> session) {
if (const auto m = CheckMainWidget(session)) { if (const auto window = session->tryResolveWindow()) {
m->ui_showPeerHistory( window->clearSectionStack();
0,
::Window::SectionShow::Way::ClearStack,
0);
} }
} }
void showPeerHistory(not_null<const History*> history, MsgId msgId) { void showPeerHistory(not_null<History*> history, MsgId msgId) {
showPeerHistory(history->peer, msgId); if (const auto window = history->session().tryResolveWindow()) {
window->showPeerHistory(
history,
::Window::SectionShow::Way::ClearStack,
msgId);
}
} }
void showPeerHistory(not_null<const PeerData*> peer, MsgId msgId) { void showPeerHistory(not_null<PeerData*> peer, MsgId msgId) {
if (const auto m = CheckMainWidget(&peer->session())) { if (const auto window = peer->session().tryResolveWindow()) {
m->ui_showPeerHistory( window->showPeerHistory(
peer->id, peer,
::Window::SectionShow::Way::ClearStack, ::Window::SectionShow::Way::ClearStack,
msgId); msgId);
} }

View file

@ -40,8 +40,8 @@ namespace Ui {
// Legacy global methods. // Legacy global methods.
void showPeerHistory(not_null<const PeerData*> peer, MsgId msgId); void showPeerHistory(not_null<PeerData*> peer, MsgId msgId);
void showPeerHistory(not_null<const History*> history, MsgId msgId); void showPeerHistory(not_null<History*> history, MsgId msgId);
void showChatsList(not_null<Main::Session*> session); void showChatsList(not_null<Main::Session*> session);
bool skipPaintEvent(QWidget *widget, QPaintEvent *event); bool skipPaintEvent(QWidget *widget, QPaintEvent *event);

View file

@ -633,16 +633,16 @@ Ui::MultiSlideTracker DetailsFiller::fillTopicButtons() {
Ui::MultiSlideTracker tracker; Ui::MultiSlideTracker tracker;
const auto window = _controller->parentController(); const auto window = _controller->parentController();
const auto channel = _topic->channel().get(); const auto forum = _topic->forum();
auto showTopicsVisible = rpl::combine( auto showTopicsVisible = rpl::combine(
window->adaptive().oneColumnValue(), window->adaptive().oneColumnValue(),
window->openedForum().value(), window->shownForum().value(),
_1 || (_2 != channel)); _1 || (_2 != forum));
AddMainButton( AddMainButton(
_wrap, _wrap,
tr::lng_forum_show_topics_list(), tr::lng_forum_show_topics_list(),
std::move(showTopicsVisible), std::move(showTopicsVisible),
[=] { window->openForum(channel); }, [=] { window->showForum(forum); },
tracker); tracker);
return tracker; return tracker;
} }

View file

@ -466,6 +466,11 @@ Window::SessionController *Session::tryResolveWindow() const {
return nullptr; return nullptr;
} }
} }
for (const auto &window : _windows) {
if (window->isPrimary()) {
return window;
}
}
return _windows.front(); return _windows.front();
} }

View file

@ -242,7 +242,10 @@ MainWidget::MainWidget(
? base::make_unique_q<Ui::PlainShadow>(this) ? base::make_unique_q<Ui::PlainShadow>(this)
: nullptr) : nullptr)
, _dialogs(isPrimary() , _dialogs(isPrimary()
? base::make_unique_q<Dialogs::Widget>(this, _controller) ? base::make_unique_q<Dialogs::Widget>(
this,
_controller,
Dialogs::Widget::Layout::Main)
: nullptr) : nullptr)
, _history(std::in_place, this, _controller) , _history(std::in_place, this, _controller)
, _playerPlaylist(this, _controller) , _playerPlaylist(this, _controller)
@ -612,12 +615,12 @@ bool MainWidget::sendPaths(not_null<Data::Thread*> thread) {
Ui::show(Ui::MakeInformBox(*error)); Ui::show(Ui::MakeInformBox(*error));
return false; return false;
} else { } else {
controller()->showThread( _controller->showThread(
thread, thread,
ShowAtTheEndMsgId, ShowAtTheEndMsgId,
Window::SectionShow::Way::ClearStack); Window::SectionShow::Way::ClearStack);
} }
return (controller()->activeChatCurrent().thread() == thread) return (_controller->activeChatCurrent().thread() == thread)
&& (_mainSection && (_mainSection
? _mainSection->confirmSendingFiles(cSendPaths()) ? _mainSection->confirmSendingFiles(cSendPaths())
: _history->confirmSendingFiles(cSendPaths())); : _history->confirmSendingFiles(cSendPaths()));
@ -655,11 +658,11 @@ bool MainWidget::onFilesOrForwardDrop(
Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant())); Ui::show(Ui::MakeInformBox(tr::lng_forward_send_files_cant()));
return false; return false;
} else { } else {
controller()->showThread( _controller->showThread(
thread, thread,
ShowAtTheEndMsgId, ShowAtTheEndMsgId,
Window::SectionShow::Way::ClearStack); Window::SectionShow::Way::ClearStack);
if (controller()->activeChatCurrent().thread() != thread) { if (_controller->activeChatCurrent().thread() != thread) {
return false; return false;
} }
(_mainSection (_mainSection
@ -678,7 +681,7 @@ void MainWidget::clearHider(not_null<Window::HistoryHider*> instance) {
return; return;
} }
_hider.release(); _hider.release();
controller()->setSelectingPeer(false); _controller->setSelectingPeer(false);
Assert(_dialogs != nullptr); Assert(_dialogs != nullptr);
if (isOneColumn()) { if (isOneColumn()) {
@ -703,12 +706,12 @@ void MainWidget::clearHider(not_null<Window::HistoryHider*> instance) {
} }
void MainWidget::hiderLayer(base::unique_qptr<Window::HistoryHider> hider) { void MainWidget::hiderLayer(base::unique_qptr<Window::HistoryHider> hider) {
if (!_dialogs || controller()->window().locked()) { if (!_dialogs || _controller->window().locked()) {
return; return;
} }
_hider = std::move(hider); _hider = std::move(hider);
controller()->setSelectingPeer(true); _controller->setSelectingPeer(true);
_dialogs->closeForwardBarRequests( _dialogs->closeForwardBarRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
@ -812,7 +815,7 @@ void MainWidget::clearSelectingPeer() {
if (_hider) { if (_hider) {
_hider->startHide(); _hider->startHide();
_hider.release(); _hider.release();
controller()->setSelectingPeer(false); _controller->setSelectingPeer(false);
} }
} }
@ -821,8 +824,8 @@ void MainWidget::sendBotCommand(Bot::SendCommandRequest request) {
? _mainSection->sendBotCommand(request) ? _mainSection->sendBotCommand(request)
: Window::SectionActionResult::Fallback; : Window::SectionActionResult::Fallback;
if (type == Window::SectionActionResult::Fallback) { if (type == Window::SectionActionResult::Fallback) {
ui_showPeerHistory( _controller->showPeerHistory(
request.peer->id, request.peer,
SectionShow::Way::Forward, SectionShow::Way::Forward,
ShowAtTheEndMsgId); ShowAtTheEndMsgId);
_history->sendBotCommand(request); _history->sendBotCommand(request);
@ -1275,7 +1278,7 @@ void MainWidget::chooseThread(
if (selectingPeer()) { if (selectingPeer()) {
_hider->offerThread(thread); _hider->offerThread(thread);
} else { } else {
controller()->showThread( _controller->showThread(
thread, thread,
showAtMsgId, showAtMsgId,
Window::SectionShow::Way::ClearStack); Window::SectionShow::Way::ClearStack);
@ -1301,8 +1304,8 @@ void MainWidget::showChooseReportMessages(
Ui::ReportReason reason, Ui::ReportReason reason,
Fn<void(MessageIdsList)> done) { Fn<void(MessageIdsList)> done) {
_history->setChooseReportMessagesDetails(reason, std::move(done)); _history->setChooseReportMessagesDetails(reason, std::move(done));
ui_showPeerHistory( _controller->showPeerHistory(
peer->id, peer,
SectionShow::Way::Forward, SectionShow::Way::Forward,
ShowForChooseMessagesMsgId); ShowForChooseMessagesMsgId);
Ui::ShowMultilineToast({ Ui::ShowMultilineToast({
@ -1325,7 +1328,7 @@ bool MainWidget::showHistoryInDifferentWindow(
MsgId showAtMsgId) { MsgId showAtMsgId) {
const auto peer = session().data().peer(peerId); const auto peer = session().data().peer(peerId);
if (const auto separate = Core::App().separateWindowForPeer(peer)) { if (const auto separate = Core::App().separateWindowForPeer(peer)) {
if (separate == &controller()->window()) { if (separate == &_controller->window()) {
return false; return false;
} }
separate->sessionController()->showPeerHistory( separate->sessionController()->showPeerHistory(
@ -1351,7 +1354,7 @@ bool MainWidget::showHistoryInDifferentWindow(
return true; return true;
} }
void MainWidget::ui_showPeerHistory( void MainWidget::showPeerHistory(
PeerId peerId, PeerId peerId,
const SectionShow &params, const SectionShow &params,
MsgId showAtMsgId) { MsgId showAtMsgId) {
@ -1367,7 +1370,7 @@ void MainWidget::ui_showPeerHistory(
if (!unavailable.isEmpty()) { if (!unavailable.isEmpty()) {
Assert(isPrimary()); Assert(isPrimary());
if (params.activation != anim::activation::background) { if (params.activation != anim::activation::background) {
controller()->show(Ui::MakeInformBox(unavailable)); _controller->show(Ui::MakeInformBox(unavailable));
} }
return; return;
} }
@ -1383,7 +1386,7 @@ void MainWidget::ui_showPeerHistory(
if (!(_history->peer() && _history->peer()->id == peerId) if (!(_history->peer() && _history->peer()->id == peerId)
&& preventsCloseSection( && preventsCloseSection(
[=] { ui_showPeerHistory(peerId, params, showAtMsgId); }, [=] { showPeerHistory(peerId, params, showAtMsgId); },
params)) { params)) {
return; return;
} }
@ -1435,7 +1438,7 @@ void MainWidget::ui_showPeerHistory(
const auto wasActivePeer = _controller->activeChatCurrent().peer(); const auto wasActivePeer = _controller->activeChatCurrent().peer();
if (params.activation != anim::activation::background) { if (params.activation != anim::activation::background) {
controller()->window().hideSettingsAndLayer(); _controller->window().hideSettingsAndLayer();
} }
auto animatedShow = [&] { auto animatedShow = [&] {
@ -1484,7 +1487,7 @@ void MainWidget::ui_showPeerHistory(
if (noPeer) { if (noPeer) {
_controller->setActiveChatEntry(Dialogs::Key()); _controller->setActiveChatEntry(Dialogs::Key());
_controller->setChatStyleTheme(controller()->defaultChatTheme()); _controller->setChatStyleTheme(_controller->defaultChatTheme());
} }
if (onlyDialogs) { if (onlyDialogs) {
@ -1547,7 +1550,7 @@ void MainWidget::showMessage(
return; return;
} }
} else if (_history->peer() == item->history()->peer) { } else if (_history->peer() == item->history()->peer) {
ui_showPeerHistory(peerId, params, itemId); showPeerHistory(peerId, params, itemId);
return; return;
} }
} }
@ -1561,6 +1564,18 @@ void MainWidget::showMessage(
} }
} }
void MainWidget::showForum(
not_null<Data::Forum*> forum,
const SectionShow &params) {
Expects(isPrimary() || (singlePeer() && singlePeer()->forum() == forum));
_dialogs->showForum(forum, params);
if (params.activation != anim::activation::background) {
_controller->hideLayer();
}
}
PeerData *MainWidget::peer() const { PeerData *MainWidget::peer() const {
return _history->peer(); return _history->peer();
} }
@ -1749,7 +1764,7 @@ void MainWidget::showNewSection(
} }
if (params.activation != anim::activation::background) { if (params.activation != anim::activation::background) {
controller()->window().hideSettingsAndLayer(); _controller->window().hideSettingsAndLayer();
} }
_controller->setDialogsListFocused(false); _controller->setDialogsListFocused(false);
@ -2657,7 +2672,7 @@ void MainWidget::handleHistoryBack() {
return; return;
} }
const auto openedFolder = _controller->openedFolder().current(); const auto openedFolder = _controller->openedFolder().current();
const auto openedForum = _controller->openedForum().current(); const auto openedForum = _controller->shownForum().current();
const auto rootPeer = !_stack.empty() const auto rootPeer = !_stack.empty()
? _stack.front()->peer() ? _stack.front()->peer()
: _history->peer() : _history->peer()

View file

@ -45,6 +45,7 @@ namespace Data {
class Thread; class Thread;
class WallPaper; class WallPaper;
struct ForwardDraft; struct ForwardDraft;
class Forum;
} // namespace Data } // namespace Data
namespace Dialogs { namespace Dialogs {
@ -216,13 +217,14 @@ public:
void toggleChooseChatTheme(not_null<PeerData*> peer); void toggleChooseChatTheme(not_null<PeerData*> peer);
void ui_showPeerHistory( void showPeerHistory(
PeerId peer, PeerId peer,
const SectionShow &params, const SectionShow &params,
MsgId msgId); MsgId msgId);
void showMessage( void showMessage(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
const SectionShow &params); const SectionShow &params);
void showForum(not_null<Data::Forum*> forum, const SectionShow &params);
bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo); bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo);

View file

@ -248,7 +248,7 @@ void GroupCallBar::setupRightButton(not_null<RoundButton*> button) {
const auto top = (st::historyReplyHeight const auto top = (st::historyReplyHeight
- st::lineWidth - st::lineWidth
- button->height()) / 2 + st::lineWidth; - button->height()) / 2 + st::lineWidth;
const auto narrow = (outerWidth < st::columnMinimalWidthLeft); const auto narrow = (outerWidth < st::columnMinimalWidthLeft / 2);
if (narrow) { if (narrow) {
button->moveToLeft( button->moveToLeft(
(outerWidth - buttonWidth) / 2, (outerWidth - buttonWidth) / 2,
@ -265,7 +265,7 @@ void GroupCallBar::setupRightButton(not_null<RoundButton*> button) {
void GroupCallBar::paint(Painter &p) { void GroupCallBar::paint(Painter &p) {
p.fillRect(_inner->rect(), st::historyComposeAreaBg); p.fillRect(_inner->rect(), st::historyComposeAreaBg);
const auto narrow = (_inner->width() < st::columnMinimalWidthLeft); const auto narrow = (_inner->width() < st::columnMinimalWidthLeft / 2);
if (!narrow) { if (!narrow) {
paintTitleAndStatus(p); paintTitleAndStatus(p);
paintUserpics(p); paintUserpics(p);

View file

@ -151,7 +151,7 @@ void RequestsBar::paint(Painter &p) {
p.setPen(st::defaultMessageBar.titleFg); p.setPen(st::defaultMessageBar.titleFg);
p.setFont(font); p.setFont(font);
if (width >= st::columnMinimalWidthLeft) { if (width >= st::columnMinimalWidthLeft / 2) {
const auto textLeft = userpicsLeft + _userpicsWidth + userpicsLeft; const auto textLeft = userpicsLeft + _userpicsWidth + userpicsLeft;
const auto available = width - textLeft - userpicsLeft; const auto available = width - textLeft - userpicsLeft;
if (_textFull.isEmpty() || available < _textFull.maxWidth()) { if (_textFull.isEmpty() || available < _textFull.maxWidth()) {

View file

@ -372,7 +372,7 @@ void SessionNavigation::showPeerByLinkResolved(
} else if (peer->isForum()) { } else if (peer->isForum()) {
const auto itemId = info.messageId; const auto itemId = info.messageId;
if (!itemId) { if (!itemId) {
parentController()->openForum(peer->asChannel(), params); parentController()->showForum(peer->forum(), params);
} else if (const auto item = peer->owner().message(peer, itemId)) { } else if (const auto item = peer->owner().message(peer, itemId)) {
showMessageByLinkResolved(item, info); showMessageByLinkResolved(item, info);
} else { } else {
@ -974,13 +974,22 @@ void SessionController::closeFolder() {
_openedFolder = nullptr; _openedFolder = nullptr;
} }
void SessionController::openForum( void SessionController::showForum(
not_null<ChannelData*> forum, not_null<Data::Forum*> forum,
const SectionShow &params) { const SectionShow &params) {
Expects(forum->isForum()); if (!isPrimary()) {
const auto primary = Core::App().primaryWindow();
_openedForumLifetime.destroy(); if (&primary->account() != &session().account()) {
if (_openedForum.current() != forum) { primary->showAccount(&session().account());
}
if (&primary->account() == &session().account()) {
primary->sessionController()->showForum(forum, params);
}
primary->activate();
return;
}
_shownForumLifetime.destroy();
if (_shownForum.current() != forum) {
resetFakeUnreadWhileOpened(); resetFakeUnreadWhileOpened();
} }
if (forum if (forum
@ -988,24 +997,23 @@ void SessionController::openForum(
&& adaptive().isOneColumn()) { && adaptive().isOneColumn()) {
clearSectionStack(params); clearSectionStack(params);
} }
_openedForum = forum.get(); _shownForum = forum.get();
if (_openedForum.current() == forum) { if (_shownForum.current() != forum) {
forum->forum()->destroyed( return;
) | rpl::start_with_next([=] {
closeForum();
showPeerHistory(
forum,
{ anim::type::normal, anim::activation::background });
}, _openedForumLifetime);
}
if (params.activation != anim::activation::background) {
hideLayer();
} }
forum->destroyed(
) | rpl::start_with_next([=, history = forum->history()] {
closeForum();
showPeerHistory(
history,
{ anim::type::normal, anim::activation::background });
}, _shownForumLifetime);
content()->showForum(forum, params);
} }
void SessionController::closeForum() { void SessionController::closeForum() {
_openedForumLifetime.destroy(); _shownForumLifetime.destroy();
_openedForum = nullptr; _shownForum = nullptr;
} }
void SessionController::setupPremiumToast() { void SessionController::setupPremiumToast() {
@ -1037,8 +1045,8 @@ const rpl::variable<Data::Folder*> &SessionController::openedFolder() const {
return _openedFolder; return _openedFolder;
} }
const rpl::variable<ChannelData*> &SessionController::openedForum() const { const rpl::variable<Data::Forum*> &SessionController::shownForum() const {
return _openedForum; return _shownForum;
} }
void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) { void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) {
@ -1062,9 +1070,9 @@ void SessionController::setActiveChatEntry(Dialogs::RowDescriptor row) {
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
clearSectionStack( clearSectionStack(
{ anim::type::normal, anim::activation::background }); { anim::type::normal, anim::activation::background });
openForum(channel, showForum(channel->forum(),
{ anim::type::normal, anim::activation::background }); { anim::type::normal, anim::activation::background });
}, _openedForumLifetime); }, _shownForumLifetime);
} }
} }
if (session().supportMode()) { if (session().supportMode()) {
@ -1674,7 +1682,7 @@ void SessionController::showPeerHistory(
PeerId peerId, PeerId peerId,
const SectionShow &params, const SectionShow &params,
MsgId msgId) { MsgId msgId) {
content()->ui_showPeerHistory(peerId, params, msgId); content()->showPeerHistory(peerId, params, msgId);
} }
void SessionController::showMessage( void SessionController::showMessage(

View file

@ -69,6 +69,7 @@ namespace Data {
struct CloudTheme; struct CloudTheme;
enum class CloudThemeType; enum class CloudThemeType;
class Thread; class Thread;
class Forum;
class ForumTopic; class ForumTopic;
} // namespace Data } // namespace Data
@ -151,19 +152,25 @@ struct SectionShow {
, activation(activation) { , activation(activation) {
} }
SectionShow withWay(Way newWay) const { [[nodiscard]] SectionShow withWay(Way newWay) const {
return SectionShow(newWay, animated, activation); return SectionShow(newWay, animated, activation);
} }
SectionShow withThirdColumn() const { [[nodiscard]] SectionShow withThirdColumn() const {
auto copy = *this; auto copy = *this;
copy.thirdColumn = true; copy.thirdColumn = true;
return copy; return copy;
} }
[[nodiscard]] SectionShow withChildColumn() const {
auto copy = *this;
copy.childColumn = true;
return copy;
}
Way way = Way::Forward; Way way = Way::Forward;
anim::type animated = anim::type::normal; anim::type animated = anim::type::normal;
anim::activation activation = anim::activation::normal; anim::activation activation = anim::activation::normal;
bool thirdColumn = false; bool thirdColumn = false;
bool childColumn = false;
Origin origin; Origin origin;
}; };
@ -358,11 +365,11 @@ public:
void closeFolder(); void closeFolder();
const rpl::variable<Data::Folder*> &openedFolder() const; const rpl::variable<Data::Folder*> &openedFolder() const;
void openForum( void showForum(
not_null<ChannelData*> forum, not_null<Data::Forum*> forum,
const SectionShow &params = SectionShow::Way::ClearStack); const SectionShow &params = SectionShow::Way::ClearStack);
void closeForum(); void closeForum();
const rpl::variable<ChannelData*> &openedForum() const; const rpl::variable<Data::Forum*> &shownForum() const;
void setActiveChatEntry(Dialogs::RowDescriptor row); void setActiveChatEntry(Dialogs::RowDescriptor row);
void setActiveChatEntry(Dialogs::Key key); void setActiveChatEntry(Dialogs::Key key);
@ -634,8 +641,8 @@ private:
PeerData *_showEditPeer = nullptr; PeerData *_showEditPeer = nullptr;
rpl::variable<Data::Folder*> _openedFolder; rpl::variable<Data::Folder*> _openedFolder;
rpl::variable<ChannelData*> _openedForum; rpl::variable<Data::Forum*> _shownForum;
rpl::lifetime _openedForumLifetime; rpl::lifetime _shownForumLifetime;
rpl::event_stream<> _filtersMenuChanged; rpl::event_stream<> _filtersMenuChanged;