Don't close recommendations.

This commit is contained in:
John Preston 2024-04-19 16:10:42 +04:00
parent da423b5bd2
commit a88770a8ec
6 changed files with 79 additions and 15 deletions

View file

@ -1108,13 +1108,14 @@ void Widget::updateHasFocus(not_null<QWidget*> focused) {
} }
void Widget::processSearchFocusChange() { void Widget::processSearchFocusChange() {
_searchSuggestionsLocked = _suggestions && _suggestions->persist();
updateStoriesVisibility(); updateStoriesVisibility();
updateForceDisplayWide(); updateForceDisplayWide();
updateSuggestions(anim::type::normal); updateSuggestions(anim::type::normal);
} }
void Widget::updateSuggestions(anim::type animated) { void Widget::updateSuggestions(anim::type animated) {
const auto suggest = _searchHasFocus const auto suggest = (_searchHasFocus || _searchSuggestionsLocked)
&& !_searchInChat && !_searchInChat
&& (_inner->state() == WidgetState::Default); && (_inner->state() == WidgetState::Default);
if (anim::Disabled() || !session().data().chatsListLoaded()) { if (anim::Disabled() || !session().data().chatsListLoaded()) {
@ -1148,6 +1149,7 @@ void Widget::updateSuggestions(anim::type animated) {
controller(), controller(),
TopPeersContent(&session()), TopPeersContent(&session()),
RecentPeersContent(&session())); RecentPeersContent(&session()));
_searchSuggestionsLocked = false;
rpl::merge( rpl::merge(
_suggestions->topPeerChosen(), _suggestions->topPeerChosen(),
@ -1155,6 +1157,10 @@ void Widget::updateSuggestions(anim::type animated) {
_suggestions->myChannelChosen(), _suggestions->myChannelChosen(),
_suggestions->recommendationChosen() _suggestions->recommendationChosen()
) | rpl::start_with_next([=](not_null<PeerData*> peer) { ) | rpl::start_with_next([=](not_null<PeerData*> peer) {
if (_searchSuggestionsLocked
&& (!_suggestions || !_suggestions->persist())) {
processSearchFocusChange();
}
chosenRow({ chosenRow({
.key = peer->owner().history(peer), .key = peer->owner().history(peer),
.newWindow = base::IsCtrlPressed(), .newWindow = base::IsCtrlPressed(),
@ -1478,7 +1484,8 @@ void Widget::setInnerFocus() {
return; return;
} else if (!_search->getLastText().isEmpty() } else if (!_search->getLastText().isEmpty()
|| _searchInChat || _searchInChat
|| _searchHasFocus) { || _searchHasFocus
|| _searchSuggestionsLocked) {
_search->setFocus(); _search->setFocus();
} else { } else {
setFocus(); setFocus();
@ -1620,6 +1627,7 @@ void Widget::updateStoriesVisibility() {
|| !_widthAnimationCache.isNull() || !_widthAnimationCache.isNull()
|| _childList || _childList
|| _searchHasFocus || _searchHasFocus
|| _searchSuggestionsLocked
|| !_search->getLastText().isEmpty() || !_search->getLastText().isEmpty()
|| _searchInChat || _searchInChat
|| _stories->empty(); || _stories->empty();
@ -2586,6 +2594,7 @@ void Widget::applySearchUpdate(bool force) {
void Widget::updateForceDisplayWide() { void Widget::updateForceDisplayWide() {
controller()->setChatsForceDisplayWide(_searchHasFocus controller()->setChatsForceDisplayWide(_searchHasFocus
|| _searchSuggestionsLocked
|| !_search->getLastText().isEmpty() || !_search->getLastText().isEmpty()
|| _searchInChat); || _searchInChat);
} }
@ -3342,7 +3351,12 @@ bool Widget::cancelSearch() {
setFocus(); setFocus();
clearingInChat = true; clearingInChat = true;
} }
const auto clearSearchFocus = !_searchInChat && _searchHasFocus; const auto clearSearchFocus = !_searchInChat
&& (_searchHasFocus || _searchSuggestionsLocked);
if (!_searchInChat && _suggestions) {
_suggestions->clearPersistance();
_searchSuggestionsLocked = false;
}
if (!_suggestions && clearSearchFocus) { if (!_suggestions && clearSearchFocus) {
// Don't create suggestions in unfocus case. // Don't create suggestions in unfocus case.
setFocus(); setFocus();

View file

@ -304,6 +304,7 @@ private:
std::vector<Data::ReactionId> _searchTags; std::vector<Data::ReactionId> _searchTags;
rpl::lifetime _searchTagsLifetime; rpl::lifetime _searchTagsLifetime;
QString _lastSearchText; QString _lastSearchText;
bool _searchSuggestionsLocked = false;
bool _searchHasFocus = false; bool _searchHasFocus = false;
rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents; rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents;

View file

@ -115,7 +115,6 @@ private:
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
RecentPeersList _recent; RecentPeersList _recent;
rpl::variable<int> _count; rpl::variable<int> _count;
base::unique_qptr<Ui::PopupMenu> _menu;
rpl::event_stream<not_null<PeerData*>> _chosen; rpl::event_stream<not_null<PeerData*>> _chosen;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
@ -145,14 +144,13 @@ public:
private: private:
void setupDivider(); void setupDivider();
void appendRow(not_null<ChannelData*> channel); void appendRow(not_null<ChannelData*> channel);
void fill(); void fill(bool force = false);
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
std::vector<not_null<History*>> _channels; std::vector<not_null<History*>> _channels;
rpl::variable<Ui::RpWidget*> _toggleExpanded = nullptr; rpl::variable<Ui::RpWidget*> _toggleExpanded = nullptr;
rpl::variable<int> _count = 0; rpl::variable<int> _count = 0;
rpl::variable<bool> _expanded = false; rpl::variable<bool> _expanded = false;
base::unique_qptr<Ui::PopupMenu> _menu;
rpl::event_stream<not_null<PeerData*>> _chosen; rpl::event_stream<not_null<PeerData*>> _chosen;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
@ -185,7 +183,6 @@ private:
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
rpl::variable<int> _count; rpl::variable<int> _count;
base::unique_qptr<Ui::PopupMenu> _menu;
rpl::event_stream<not_null<PeerData*>> _chosen; rpl::event_stream<not_null<PeerData*>> _chosen;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
@ -529,6 +526,27 @@ MyChannelsController::MyChannelsController(
void MyChannelsController::prepare() { void MyChannelsController::prepare() {
setupDivider(); setupDivider();
session().changes().peerUpdates(
Data::PeerUpdate::Flag::ChannelAmIn
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
const auto channel = update.peer->asBroadcast();
if (!channel || channel->amIn()) {
return;
}
const auto history = channel->owner().history(channel);
const auto i = ranges::remove(_channels, history);
if (i == end(_channels)) {
return;
}
_channels.erase(i, end(_channels));
const auto row = delegate()->peerListFindRow(channel->id.value);
if (row) {
delegate()->peerListRemoveRow(row);
}
_count = int(_channels.size());
fill(true);
}, _lifetime);
_channels.reserve(kProbablyMaxChannels); _channels.reserve(kProbablyMaxChannels);
const auto owner = &session().data(); const auto owner = &session().data();
const auto add = [&](not_null<Dialogs::MainList*> list) { const auto add = [&](not_null<Dialogs::MainList*> list) {
@ -579,20 +597,20 @@ void MyChannelsController::prepare() {
}, _lifetime); }, _lifetime);
} }
void MyChannelsController::fill() { void MyChannelsController::fill(bool force) {
const auto count = _count.current(); const auto count = _count.current();
const auto limit = _expanded.current() const auto limit = _expanded.current()
? count ? count
: std::min(count, kCollapsedChannelsCount); : std::min(count, kCollapsedChannelsCount);
const auto already = delegate()->peerListFullRowsCount(); const auto already = delegate()->peerListFullRowsCount();
const auto delta = limit - already; const auto delta = limit - already;
if (!delta) { if (!delta && !force) {
return; return;
} else if (delta > 0) { } else if (delta > 0) {
for (auto i = already; i != limit; ++i) { for (auto i = already; i != limit; ++i) {
appendRow(_channels[i]->peer->asBroadcast()); appendRow(_channels[i]->peer->asBroadcast());
} }
} else { } else if (delta < 0) {
for (auto i = already; i != limit;) { for (auto i = already; i != limit;) {
delegate()->peerListRemoveRow(delegate()->peerListRowAt(--i)); delegate()->peerListRemoveRow(delegate()->peerListRowAt(--i));
} }
@ -620,7 +638,19 @@ void MyChannelsController::rowClicked(not_null<PeerListRow*> row) {
base::unique_qptr<Ui::PopupMenu> MyChannelsController::rowContextMenu( base::unique_qptr<Ui::PopupMenu> MyChannelsController::rowContextMenu(
QWidget *parent, QWidget *parent,
not_null<PeerListRow*> row) { not_null<PeerListRow*> row) {
return nullptr; auto result = base::make_unique_q<Ui::PopupMenu>(
parent,
st::popupMenuWithIcons);
const auto peer = row->peer();
const auto addAction = Ui::Menu::CreateAddActionCallback(result);
Window::FillDialogsEntryMenu(
_window,
Dialogs::EntryState{
.key = peer->owner().history(peer),
.section = Dialogs::EntryState::Section::ContextMenu,
},
addAction);
return result;
} }
Main::Session &MyChannelsController::session() const { Main::Session &MyChannelsController::session() const {
@ -977,6 +1007,7 @@ void Suggestions::switchTab(Tab tab) {
return; return;
} }
_tab = tab; _tab = tab;
_persist = false;
if (_tabs->isHidden()) { if (_tabs->isHidden()) {
return; return;
} }
@ -1215,6 +1246,7 @@ object_ptr<Ui::SlideWrap<>> Suggestions::setupMyChannels() {
controller->chosen( controller->chosen(
) | rpl::start_with_next([=](not_null<PeerData*> peer) { ) | rpl::start_with_next([=](not_null<PeerData*> peer) {
_persist = false;
_myChannelChosen.fire_copy(peer); _myChannelChosen.fire_copy(peer);
}, lifetime); }, lifetime);
@ -1269,6 +1301,7 @@ object_ptr<Ui::SlideWrap<>> Suggestions::setupRecommendations() {
controller->chosen( controller->chosen(
) | rpl::start_with_next([=](not_null<PeerData*> peer) { ) | rpl::start_with_next([=](not_null<PeerData*> peer) {
_persist = true;
_recommendationChosen.fire_copy(peer); _recommendationChosen.fire_copy(peer);
}, lifetime); }, lifetime);
@ -1311,6 +1344,14 @@ object_ptr<Ui::SlideWrap<>> Suggestions::setupRecommendations() {
return object_ptr<Ui::SlideWrap<>>(this, std::move(content)); return object_ptr<Ui::SlideWrap<>>(this, std::move(content));
} }
bool Suggestions::persist() const {
return _persist;
}
void Suggestions::clearPersistance() {
_persist = false;
}
rpl::producer<TopPeersList> TopPeersContent( rpl::producer<TopPeersList> TopPeersContent(
not_null<Main::Session*> session) { not_null<Main::Session*> session) {
return [=](auto consumer) { return [=](auto consumer) {

View file

@ -50,6 +50,9 @@ public:
void hide(anim::type animated, Fn<void()> finish); void hide(anim::type animated, Fn<void()> finish);
[[nodiscard]] float64 shownOpacity() const; [[nodiscard]] float64 shownOpacity() const;
[[nodiscard]] bool persist() const;
void clearPersistance();
[[nodiscard]] rpl::producer<not_null<PeerData*>> topPeerChosen() const { [[nodiscard]] rpl::producer<not_null<PeerData*>> topPeerChosen() const {
return _topPeerChosen.events(); return _topPeerChosen.events();
} }
@ -141,6 +144,7 @@ private:
Fn<void()> _showFinished; Fn<void()> _showFinished;
Tab _tab = Tab::Chats; Tab _tab = Tab::Chats;
bool _hidden = false; bool _hidden = false;
bool _persist = false;
QPixmap _cache; QPixmap _cache;
Ui::Animations::Simple _slideAnimation; Ui::Animations::Simple _slideAnimation;

View file

@ -167,7 +167,8 @@ constexpr auto kStickerSetLines = 3;
: (type == WebPageType::GroupWithRequest : (type == WebPageType::GroupWithRequest
|| type == WebPageType::ChannelWithRequest) || type == WebPageType::ChannelWithRequest)
? tr::lng_view_button_request_join(tr::now) ? tr::lng_view_button_request_join(tr::now)
: (type == WebPageType::ChannelBoost) : (type == WebPageType::GroupBoost
|| type == WebPageType::ChannelBoost)
? tr::lng_view_button_boost(tr::now) ? tr::lng_view_button_boost(tr::now)
: (type == WebPageType::Giftcode) : (type == WebPageType::Giftcode)
? tr::lng_view_button_giftcode(tr::now) ? tr::lng_view_button_giftcode(tr::now)
@ -202,8 +203,11 @@ constexpr auto kStickerSetLines = 3;
return webpage->iv return webpage->iv
|| (type == WebPageType::Message) || (type == WebPageType::Message)
|| (type == WebPageType::Group) || (type == WebPageType::Group)
|| (type == WebPageType::GroupWithRequest)
|| (type == WebPageType::GroupBoost)
|| (type == WebPageType::Channel) || (type == WebPageType::Channel)
|| (type == WebPageType::ChannelBoost) || (type == WebPageType::ChannelBoost)
|| (type == WebPageType::ChannelWithRequest)
|| (type == WebPageType::Giftcode) || (type == WebPageType::Giftcode)
// || (type == WebPageType::Bot) // || (type == WebPageType::Bot)
|| (type == WebPageType::User) || (type == WebPageType::User)

View file

@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/add_bot_to_chat_box.h" #include "boxes/peers/add_bot_to_chat_box.h"
#include "boxes/peers/edit_contact_box.h" #include "boxes/peers/edit_contact_box.h"
#include "boxes/report_messages_box.h" #include "boxes/report_messages_box.h"
#include "boxes/share_box.h"
#include "boxes/translate_box.h" #include "boxes/translate_box.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "menu/menu_mute.h" #include "menu/menu_mute.h"
@ -131,9 +132,8 @@ base::options::toggle ShowPeerIdBelowAbout({
+ addToLink; + addToLink;
} }
if (!link.isEmpty()) { if (!link.isEmpty()) {
QGuiApplication::clipboard()->setText(link); if (const auto strong = weak.get()) {
if (const auto window = weak.get()) { FastShareLink(strong, link);
window->showToast(tr::lng_username_copied(tr::now));
} }
} }
}; };