mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Added recent search entries to settings.
This commit is contained in:
@@ -1656,6 +1656,8 @@ PRIVATE
|
||||
settings/sections/settings_local_passcode.h
|
||||
settings/sections/settings_main.cpp
|
||||
settings/sections/settings_main.h
|
||||
settings/settings_recent_searches.cpp
|
||||
settings/settings_recent_searches.h
|
||||
settings/settings_search.cpp
|
||||
settings/settings_search.h
|
||||
settings/settings_faq_suggestions.cpp
|
||||
|
||||
@@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/components/top_peers.h"
|
||||
#include "settings/settings_faq_suggestions.h"
|
||||
#include "settings/settings_recent_searches.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_user.h"
|
||||
@@ -159,6 +160,7 @@ Session::Session(
|
||||
}))
|
||||
, _passkeys(std::make_unique<Data::Passkeys>(this))
|
||||
, _faqSuggestions(std::make_unique<Settings::FaqSuggestions>(this))
|
||||
, _recentSettingsSearches(std::make_unique<Settings::RecentSearches>(this))
|
||||
, _cachedReactionIconFactory(std::make_unique<ReactionIconFactory>())
|
||||
, _supportHelper(Support::Helper::Create(this))
|
||||
, _fastButtonsBots(std::make_unique<Support::FastButtonsBots>(this))
|
||||
|
||||
@@ -47,6 +47,7 @@ class Passkeys;
|
||||
|
||||
namespace Settings {
|
||||
class FaqSuggestions;
|
||||
class RecentSearches;
|
||||
} // namespace Settings
|
||||
|
||||
namespace HistoryView::Reactions {
|
||||
@@ -212,6 +213,9 @@ public:
|
||||
[[nodiscard]] Settings::FaqSuggestions &faqSuggestions() const {
|
||||
return *_faqSuggestions;
|
||||
}
|
||||
[[nodiscard]] Settings::RecentSearches &recentSettingsSearches() const {
|
||||
return *_recentSettingsSearches;
|
||||
}
|
||||
[[nodiscard]] auto cachedReactionIconFactory() const
|
||||
-> HistoryView::Reactions::CachedIconFactory & {
|
||||
return *_cachedReactionIconFactory;
|
||||
@@ -318,6 +322,7 @@ private:
|
||||
const std::unique_ptr<Data::PromoSuggestions> _promoSuggestions;
|
||||
const std::unique_ptr<Data::Passkeys> _passkeys;
|
||||
const std::unique_ptr<Settings::FaqSuggestions> _faqSuggestions;
|
||||
const std::unique_ptr<Settings::RecentSearches> _recentSettingsSearches;
|
||||
|
||||
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
|
||||
const std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
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 "settings/settings_recent_searches.h"
|
||||
|
||||
#include "main/main_session.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "storage/storage_account.h"
|
||||
|
||||
namespace Settings {
|
||||
namespace {
|
||||
|
||||
constexpr auto kLimit = 32;
|
||||
|
||||
} // namespace
|
||||
|
||||
RecentSearches::RecentSearches(not_null<Main::Session*> session)
|
||||
: _session(session) {
|
||||
}
|
||||
|
||||
RecentSearches::~RecentSearches() = default;
|
||||
|
||||
const std::vector<QString> &RecentSearches::list() const {
|
||||
_session->local().readSearchSuggestions();
|
||||
|
||||
return _list;
|
||||
}
|
||||
|
||||
void RecentSearches::bump(const QString &entryId) {
|
||||
if (entryId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
_session->local().readSearchSuggestions();
|
||||
|
||||
if (!_list.empty() && _list.front() == entryId) {
|
||||
return;
|
||||
}
|
||||
auto i = ranges::find(_list, entryId);
|
||||
if (i == end(_list)) {
|
||||
if (int(_list.size()) >= kLimit) {
|
||||
_list.pop_back();
|
||||
}
|
||||
_list.push_back(entryId);
|
||||
i = end(_list) - 1;
|
||||
}
|
||||
ranges::rotate(begin(_list), i, i + 1);
|
||||
|
||||
_session->local().writeSearchSuggestionsDelayed();
|
||||
}
|
||||
|
||||
void RecentSearches::remove(const QString &entryId) {
|
||||
const auto i = ranges::find(_list, entryId);
|
||||
if (i != end(_list)) {
|
||||
_list.erase(i);
|
||||
}
|
||||
_session->local().writeSearchSuggestionsDelayed();
|
||||
}
|
||||
|
||||
QByteArray RecentSearches::serialize() const {
|
||||
_session->local().readSearchSuggestions();
|
||||
|
||||
if (_list.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto count = std::min(int(_list.size()), kLimit);
|
||||
auto size = 2 * int(sizeof(quint32));
|
||||
for (auto i = 0; i < count; ++i) {
|
||||
size += Serialize::stringSize(_list[i]);
|
||||
}
|
||||
auto stream = Serialize::ByteArrayWriter(size);
|
||||
stream
|
||||
<< quint32(AppVersion)
|
||||
<< quint32(count);
|
||||
for (auto i = 0; i < count; ++i) {
|
||||
stream << _list[i];
|
||||
}
|
||||
return std::move(stream).result();
|
||||
}
|
||||
|
||||
void RecentSearches::applyLocal(QByteArray serialized) {
|
||||
_list.clear();
|
||||
if (serialized.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
auto stream = Serialize::ByteArrayReader(serialized);
|
||||
auto version = quint32();
|
||||
auto count = quint32();
|
||||
stream >> version >> count;
|
||||
if (!stream.ok()) {
|
||||
return;
|
||||
}
|
||||
_list.reserve(count);
|
||||
for (auto i = quint32(0); i < count; ++i) {
|
||||
auto value = QString();
|
||||
stream >> value;
|
||||
if (!stream.ok()) {
|
||||
_list.clear();
|
||||
return;
|
||||
}
|
||||
_list.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Settings
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class RecentSearches final {
|
||||
public:
|
||||
explicit RecentSearches(not_null<Main::Session*> session);
|
||||
~RecentSearches();
|
||||
|
||||
[[nodiscard]] const std::vector<QString> &list() const;
|
||||
|
||||
void bump(const QString &entryId);
|
||||
void remove(const QString &entryId);
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
void applyLocal(QByteArray serialized);
|
||||
|
||||
private:
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
std::vector<QString> _list;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Settings
|
||||
@@ -15,11 +15,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "settings/settings_builder.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "settings/settings_faq_suggestions.h"
|
||||
#include "settings/settings_recent_searches.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/text/text_entity.h"
|
||||
#include "ui/search_field_controller.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/elastic_scroll.h"
|
||||
#include "ui/widgets/fields/input_field.h"
|
||||
@@ -260,17 +262,22 @@ void Search::setupCustomizations() {
|
||||
void Search::buildIndex() {
|
||||
_entries.clear();
|
||||
_firstLetterIndex.clear();
|
||||
_entryIdToIndex.clear();
|
||||
|
||||
const auto ®istry = Builder::SearchRegistry::Instance();
|
||||
const auto rawEntries = registry.collectAll(&controller()->session());
|
||||
|
||||
_entries.reserve(rawEntries.size());
|
||||
for (const auto &entry : rawEntries) {
|
||||
const auto index = int(_entries.size());
|
||||
auto indexed = IndexedEntry{
|
||||
.entry = entry,
|
||||
.terms = PrepareEntryWords(entry),
|
||||
.depth = CalculateDepth(entry.section, registry),
|
||||
};
|
||||
if (!entry.id.isEmpty()) {
|
||||
_entryIdToIndex[entry.id] = index;
|
||||
}
|
||||
_entries.push_back(std::move(indexed));
|
||||
}
|
||||
|
||||
@@ -402,6 +409,90 @@ void Search::handleKeyNavigation(int key) {
|
||||
}
|
||||
}
|
||||
|
||||
not_null<Ui::SettingsButton*> Search::createEntryButton(
|
||||
int entryIndex,
|
||||
const QString &subtitle) {
|
||||
const auto &indexed = _entries[entryIndex];
|
||||
const auto &entry = indexed.entry;
|
||||
const auto hasIcon = entry.icon.icon != nullptr;
|
||||
const auto hasCheckIcon = !hasIcon
|
||||
&& (entry.checkIcon != Builder::SearchEntryCheckIcon::None);
|
||||
|
||||
const auto it = _customizations.find(entry.id);
|
||||
const auto custom = (it != _customizations.end())
|
||||
? &it->second
|
||||
: nullptr;
|
||||
|
||||
const auto &st = custom && custom->st
|
||||
? *custom->st
|
||||
: (hasIcon || hasCheckIcon)
|
||||
? st::settingsSearchResult
|
||||
: st::settingsSearchResultNoIcon;
|
||||
|
||||
const auto button = CreateSearchResultButtonRaw(
|
||||
this,
|
||||
entry.title,
|
||||
subtitle,
|
||||
st,
|
||||
IconDescriptor{ entry.icon.icon },
|
||||
(hasCheckIcon
|
||||
? entry.checkIcon
|
||||
: Builder::SearchEntryCheckIcon::None));
|
||||
|
||||
if (custom && custom->hook) {
|
||||
custom->hook(button);
|
||||
}
|
||||
|
||||
const auto controlId = entry.id;
|
||||
if (!controlId.isEmpty()) {
|
||||
const auto targetSection = entry.section;
|
||||
const auto deeplink = entry.deeplink;
|
||||
button->addClickHandler([=] {
|
||||
bumpRecentEntry(controlId);
|
||||
if (!deeplink.isEmpty()) {
|
||||
Core::App().openLocalUrl(
|
||||
deeplink,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller()),
|
||||
}));
|
||||
} else {
|
||||
controller()->setHighlightControlId(controlId);
|
||||
showOtherMethod()(targetSection);
|
||||
}
|
||||
});
|
||||
|
||||
base::install_event_filter(button, [=](not_null<QEvent*> e) {
|
||||
if (e->type() != QEvent::ContextMenu) {
|
||||
return base::EventFilterResult::Continue;
|
||||
}
|
||||
const auto &recentIds
|
||||
= controller()->session().recentSettingsSearches().list();
|
||||
if (!ranges::contains(recentIds, controlId)) {
|
||||
return base::EventFilterResult::Continue;
|
||||
}
|
||||
_contextMenu = base::make_unique_q<Ui::PopupMenu>(
|
||||
button,
|
||||
st::popupMenuWithIcons);
|
||||
_contextMenu->addAction(
|
||||
tr::lng_recent_remove(tr::now),
|
||||
[=] {
|
||||
controller()->session().recentSettingsSearches().remove(
|
||||
controlId);
|
||||
const auto query = _searchController
|
||||
? _searchController->query()
|
||||
: QString();
|
||||
rebuildResults(query);
|
||||
},
|
||||
&st::menuIconDelete);
|
||||
_contextMenu->popup(QCursor::pos());
|
||||
return base::EventFilterResult::Cancel;
|
||||
}, button->lifetime());
|
||||
}
|
||||
|
||||
_buttonCache.emplace(entryIndex, button);
|
||||
return button;
|
||||
}
|
||||
|
||||
void Search::rebuildResults(const QString &query) {
|
||||
for (auto i = 0, count = _list->count(); i != count; ++i) {
|
||||
_list->widgetAt(i)->hide();
|
||||
@@ -413,7 +504,9 @@ void Search::rebuildResults(const QString &query) {
|
||||
const auto queryWords = TextUtilities::PrepareSearchWords(query);
|
||||
|
||||
if (queryWords.isEmpty()) {
|
||||
rebuildRecentResults();
|
||||
rebuildFaqResults();
|
||||
_list->resizeToWidth(_list->width());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -475,7 +568,6 @@ void Search::rebuildResults(const QString &query) {
|
||||
st::settingsSearchNoResults),
|
||||
st::settingsSearchNoResultsPadding);
|
||||
} else {
|
||||
const auto showOther = showOtherMethod();
|
||||
const auto ®istry = Builder::SearchRegistry::Instance();
|
||||
const auto faqSubtitle = tr::lng_settings_faq_subtitle(tr::now);
|
||||
const auto weak = base::make_weak(controller());
|
||||
@@ -492,43 +584,18 @@ void Search::rebuildResults(const QString &query) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto subtitle = QString();
|
||||
if (isFaq) {
|
||||
subtitle = faqSubtitle + u" > "_q + indexed.faqSection;
|
||||
} else {
|
||||
const auto parentsOnly = entry.id.isEmpty();
|
||||
subtitle = registry.sectionPath(entry.section, parentsOnly);
|
||||
}
|
||||
const auto hasIcon = entry.icon.icon != nullptr;
|
||||
const auto hasCheckIcon = !hasIcon
|
||||
&& (entry.checkIcon != Builder::SearchEntryCheckIcon::None);
|
||||
const auto subtitle = faqSubtitle
|
||||
+ u" > "_q
|
||||
+ indexed.faqSection;
|
||||
const auto button = CreateSearchResultButtonRaw(
|
||||
this,
|
||||
entry.title,
|
||||
subtitle,
|
||||
st::settingsSearchResultNoIcon,
|
||||
IconDescriptor{},
|
||||
Builder::SearchEntryCheckIcon::None);
|
||||
|
||||
const auto it = _customizations.find(entry.id);
|
||||
const auto custom = (it != _customizations.end())
|
||||
? &it->second
|
||||
: nullptr;
|
||||
|
||||
const auto &st = custom && custom->st
|
||||
? *custom->st
|
||||
: (hasIcon || hasCheckIcon)
|
||||
? st::settingsSearchResult
|
||||
: st::settingsSearchResultNoIcon;
|
||||
|
||||
const auto button = CreateSearchResultButtonRaw(
|
||||
this,
|
||||
entry.title,
|
||||
subtitle,
|
||||
st,
|
||||
IconDescriptor{ entry.icon.icon },
|
||||
(hasCheckIcon
|
||||
? entry.checkIcon
|
||||
: Builder::SearchEntryCheckIcon::None));
|
||||
|
||||
if (custom && custom->hook) {
|
||||
custom->hook(button);
|
||||
}
|
||||
|
||||
if (isFaq) {
|
||||
const auto url = indexed.faqUrl;
|
||||
button->addClickHandler([=] {
|
||||
UrlClickHandler::Open(
|
||||
@@ -537,26 +604,16 @@ void Search::rebuildResults(const QString &query) {
|
||||
.sessionWindow = weak,
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
const auto targetSection = entry.section;
|
||||
const auto controlId = entry.id;
|
||||
const auto deeplink = entry.deeplink;
|
||||
button->addClickHandler([=] {
|
||||
if (!deeplink.isEmpty()) {
|
||||
Core::App().openLocalUrl(
|
||||
deeplink,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller()),
|
||||
}));
|
||||
} else {
|
||||
controller()->setHighlightControlId(controlId);
|
||||
showOther(targetSection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_buttonCache.emplace(entryIndex, button);
|
||||
addButton(button);
|
||||
_buttonCache.emplace(entryIndex, button);
|
||||
addButton(button);
|
||||
} else {
|
||||
const auto parentsOnly = entry.id.isEmpty();
|
||||
const auto subtitle = registry.sectionPath(
|
||||
entry.section,
|
||||
parentsOnly);
|
||||
addButton(createEntryButton(entryIndex, subtitle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,11 +640,55 @@ void Search::sectionRestoreState(const std::any &state) {
|
||||
}
|
||||
}
|
||||
|
||||
void Search::bumpRecentEntry(const QString &entryId) {
|
||||
if (!entryId.isEmpty()) {
|
||||
controller()->session().recentSettingsSearches().bump(entryId);
|
||||
}
|
||||
}
|
||||
|
||||
void Search::rebuildRecentResults() {
|
||||
const auto &recentIds
|
||||
= controller()->session().recentSettingsSearches().list();
|
||||
if (recentIds.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto ®istry = Builder::SearchRegistry::Instance();
|
||||
|
||||
auto added = false;
|
||||
for (const auto &entryId : recentIds) {
|
||||
const auto it = _entryIdToIndex.find(entryId);
|
||||
if (it == _entryIdToIndex.end()) {
|
||||
continue;
|
||||
}
|
||||
if (!added) {
|
||||
Ui::AddSubsectionTitle(_list, tr::lng_recent_title());
|
||||
added = true;
|
||||
}
|
||||
const auto entryIndex = it->second;
|
||||
const auto cached = _buttonCache.find(entryIndex);
|
||||
if (cached != _buttonCache.end()) {
|
||||
addButton(cached->second);
|
||||
continue;
|
||||
}
|
||||
const auto &entry = _entries[entryIndex].entry;
|
||||
const auto parentsOnly = entry.id.isEmpty();
|
||||
const auto subtitle = registry.sectionPath(
|
||||
entry.section,
|
||||
parentsOnly);
|
||||
addButton(createEntryButton(entryIndex, subtitle));
|
||||
}
|
||||
}
|
||||
|
||||
void Search::rebuildFaqResults() {
|
||||
if (_faqStartIndex >= int(_entries.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_visibleButtons.empty()) {
|
||||
Ui::AddSubsectionTitle(_list, tr::lng_settings_faq());
|
||||
}
|
||||
|
||||
const auto faqSubtitle = tr::lng_settings_faq_subtitle(tr::now);
|
||||
const auto weak = base::make_weak(controller());
|
||||
|
||||
@@ -621,7 +722,6 @@ void Search::rebuildFaqResults() {
|
||||
_buttonCache.emplace(i, button);
|
||||
addButton(button);
|
||||
}
|
||||
_list->resizeToWidth(_list->width());
|
||||
}
|
||||
|
||||
void Search::addButton(not_null<Ui::SettingsButton*> button) {
|
||||
|
||||
@@ -19,6 +19,7 @@ class SessionController;
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class PopupMenu;
|
||||
class RpWidget;
|
||||
class SearchFieldController;
|
||||
class VerticalLayout;
|
||||
@@ -60,7 +61,12 @@ private:
|
||||
void setupCustomizations();
|
||||
void buildIndex();
|
||||
void rebuildResults(const QString &query);
|
||||
void rebuildRecentResults();
|
||||
void rebuildFaqResults();
|
||||
void bumpRecentEntry(const QString &entryId);
|
||||
[[nodiscard]] not_null<Ui::SettingsButton*> createEntryButton(
|
||||
int entryIndex,
|
||||
const QString &subtitle);
|
||||
void selectByKeyboard(int newSelected);
|
||||
void clearSelection();
|
||||
void handleKeyNavigation(int key);
|
||||
@@ -72,6 +78,7 @@ private:
|
||||
Ui::InputField *_searchField = nullptr;
|
||||
Ui::VerticalLayout *_list = nullptr;
|
||||
base::flat_map<QString, ResultCustomization> _customizations;
|
||||
base::flat_map<QString, int> _entryIdToIndex;
|
||||
QString _pendingQuery;
|
||||
std::vector<IndexedEntry> _entries;
|
||||
base::flat_map<QChar, base::flat_set<int>> _firstLetterIndex;
|
||||
@@ -79,6 +86,7 @@ private:
|
||||
int _faqStartIndex = 0;
|
||||
std::vector<Ui::SettingsButton*> _visibleButtons;
|
||||
base::flat_set<not_null<Ui::SettingsButton*>> _trackedButtons;
|
||||
base::unique_qptr<Ui::PopupMenu> _contextMenu;
|
||||
int _selected = -1;
|
||||
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "core/core_settings.h"
|
||||
#include "core/file_location.h"
|
||||
#include "data/components/recent_peers.h"
|
||||
#include "settings/settings_recent_searches.h"
|
||||
#include "data/components/top_peers.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_session.h"
|
||||
@@ -3200,7 +3201,9 @@ void Account::writeSearchSuggestions() {
|
||||
|
||||
const auto top = _owner->session().topPeers().serialize();
|
||||
const auto recent = _owner->session().recentPeers().serialize();
|
||||
if (top.isEmpty() && recent.isEmpty()) {
|
||||
const auto settingsSearches
|
||||
= _owner->session().recentSettingsSearches().serialize();
|
||||
if (top.isEmpty() && recent.isEmpty() && settingsSearches.isEmpty()) {
|
||||
if (_searchSuggestionsKey) {
|
||||
ClearKey(_searchSuggestionsKey, _basePath);
|
||||
_searchSuggestionsKey = 0;
|
||||
@@ -3213,9 +3216,10 @@ void Account::writeSearchSuggestions() {
|
||||
writeMapQueued();
|
||||
}
|
||||
quint32 size = Serialize::bytearraySize(top)
|
||||
+ Serialize::bytearraySize(recent);
|
||||
+ Serialize::bytearraySize(recent)
|
||||
+ Serialize::bytearraySize(settingsSearches);
|
||||
EncryptedDescriptor data(size);
|
||||
data.stream << top << recent;
|
||||
data.stream << top << recent << settingsSearches;
|
||||
|
||||
FileWriteDescriptor file(_searchSuggestionsKey, _basePath);
|
||||
file.writeEncrypted(data, _localKey);
|
||||
@@ -3242,10 +3246,16 @@ void Account::readSearchSuggestions() {
|
||||
|
||||
auto top = QByteArray();
|
||||
auto recent = QByteArray();
|
||||
auto settingsSearches = QByteArray();
|
||||
suggestions.stream >> top >> recent;
|
||||
if (!suggestions.stream.atEnd()) {
|
||||
suggestions.stream >> settingsSearches;
|
||||
}
|
||||
if (CheckStreamStatus(suggestions.stream)) {
|
||||
_owner->session().topPeers().applyLocal(top);
|
||||
_owner->session().recentPeers().applyLocal(recent);
|
||||
_owner->session().recentSettingsSearches().applyLocal(
|
||||
settingsSearches);
|
||||
} else {
|
||||
DEBUG_LOG(("Suggestions: Could not read content."));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user