switch to top recent sites

This commit is contained in:
Fabian Freund
2026-03-09 12:30:58 +01:00
parent 62aed84fd8
commit 0fa526b1cb
9 changed files with 2205 additions and 2801 deletions
@@ -70,6 +70,17 @@ class HistoryRepository extends _$HistoryRepository {
); );
} }
Future<List<TopFrecentSiteInfo>> getTopFrecentSites({
required int limit,
FrecencyThresholdOption frecencyThreshold =
FrecencyThresholdOption.skipOneTimePages,
}) {
return _service.getTopFrecentSites(
limit: limit,
frecencyThreshold: frecencyThreshold,
);
}
@override @override
void build() {} void build() {}
} }
@@ -631,10 +631,9 @@ class SearchScreen extends HookConsumerWidget {
for (final entry in emptyStateOrder) for (final entry in emptyStateOrder)
if (emptyStateWidgets.containsKey(entry.type)) if (emptyStateWidgets.containsKey(entry.type))
emptyStateWidgets[entry.type]!, emptyStateWidgets[entry.type]!,
if (!emptyStateOrder.any((e) => e.visible)) const _CustomizeSectionsButton(
const _CustomizeSectionsButton( group: SearchModuleGroup.emptyState,
group: SearchModuleGroup.emptyState, ),
),
] else ...[ ] else ...[
FullSearchTermSuggestions( FullSearchTermSuggestions(
searchTextController: searchTextController, searchTextController: searchTextController,
@@ -645,10 +644,9 @@ class SearchScreen extends HookConsumerWidget {
for (final entry in searchOrder) for (final entry in searchOrder)
if (searchWidgets.containsKey(entry.type)) if (searchWidgets.containsKey(entry.type))
searchWidgets[entry.type]!, searchWidgets[entry.type]!,
if (!searchOrder.any((e) => e.visible)) const _CustomizeSectionsButton(
const _CustomizeSectionsButton( group: SearchModuleGroup.search,
group: SearchModuleGroup.search, ),
),
], ],
], ],
), ),
@@ -248,32 +248,25 @@ class TopSiteRepository extends _$TopSiteRepository {
required int limit, required int limit,
required Set<String> excludeUrls, required Set<String> excludeUrls,
}) async { }) async {
final highlights = await ref final frecentSites = await ref
.read(historyRepositoryProvider.notifier) .read(historyRepositoryProvider.notifier)
.getHistoryHighlights(limit: limit + excludeUrls.length); .getTopFrecentSites(limit: limit + excludeUrls.length);
final items = <TopSiteItem>[]; final items = <TopSiteItem>[];
for (final h in highlights) { for (final site in frecentSites) {
if (items.length >= limit) break; if (items.length >= limit) break;
final uri = Uri.tryParse(h.url); final uri = Uri.tryParse(site.url);
if (uri == null) continue; if (uri == null) continue;
if (excludeUrls.contains(uri.toString())) continue; if (excludeUrls.contains(uri.toString())) continue;
final title = (h.title?.trim().isNotEmpty == true) final title = (site.title?.trim().isNotEmpty == true)
? h.title!.trim() ? site.title!.trim()
: uri.host; : uri.host;
items.add( items.add(
TopSiteItem( TopSiteItem(title: title, url: uri, source: TopSiteSource.history),
title: title,
url: uri,
source: TopSiteSource.history,
previewImageUrl: h.previewImageUrl,
historyScore: h.score,
historyPlaceId: h.placeId,
),
); );
} }
@@ -2,8 +2,10 @@ package eu.weblibre.flutter_mozilla_components.api
import eu.weblibre.flutter_mozilla_components.GlobalComponents import eu.weblibre.flutter_mozilla_components.GlobalComponents
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHistoryApi import eu.weblibre.flutter_mozilla_components.pigeons.GeckoHistoryApi
import eu.weblibre.flutter_mozilla_components.pigeons.FrecencyThresholdOption
import eu.weblibre.flutter_mozilla_components.pigeons.HistoryHighlight import eu.weblibre.flutter_mozilla_components.pigeons.HistoryHighlight
import eu.weblibre.flutter_mozilla_components.pigeons.HistoryHighlightWeights import eu.weblibre.flutter_mozilla_components.pigeons.HistoryHighlightWeights
import eu.weblibre.flutter_mozilla_components.pigeons.TopFrecentSiteInfo
import eu.weblibre.flutter_mozilla_components.pigeons.VisitInfo import eu.weblibre.flutter_mozilla_components.pigeons.VisitInfo
import eu.weblibre.flutter_mozilla_components.pigeons.VisitType import eu.weblibre.flutter_mozilla_components.pigeons.VisitType
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -236,4 +238,31 @@ class GeckoHistoryApiImpl() : GeckoHistoryApi {
} }
} }
} }
}
override fun getTopFrecentSites(
limit: Long,
frecencyThreshold: FrecencyThresholdOption,
callback: (Result<List<TopFrecentSiteInfo>>) -> Unit
) {
coroutineScope.launch {
withContext(Dispatchers.Main) {
val conceptThreshold = when (frecencyThreshold) {
FrecencyThresholdOption.NONE ->
mozilla.components.concept.storage.FrecencyThresholdOption.NONE
FrecencyThresholdOption.SKIP_ONE_TIME_PAGES ->
mozilla.components.concept.storage.FrecencyThresholdOption.SKIP_ONE_TIME_PAGES
}
val sites = components.core.historyStorage.getTopFrecentSites(
limit.toInt(),
conceptThreshold,
).map {
TopFrecentSiteInfo(
url = it.url,
title = it.title,
)
}
callback(Result.success(sites))
}
}
}
}
@@ -54,6 +54,7 @@ export 'src/pigeons/gecko.g.dart'
DohSettings, DohSettings,
DohSettingsMode, DohSettingsMode,
EmailHitResult, EmailHitResult,
FrecencyThresholdOption,
GeckoDeleteBrowsingDataController, GeckoDeleteBrowsingDataController,
GeckoEngineSettings, GeckoEngineSettings,
GeckoFetchResponse, GeckoFetchResponse,
@@ -97,6 +98,7 @@ export 'src/pigeons/gecko.g.dart'
TabContent, TabContent,
TabContentState, TabContentState,
TabTranslationStateData, TabTranslationStateData,
TopFrecentSiteInfo,
TrackingProtectionException, TrackingProtectionException,
TrackingProtectionPolicy, TrackingProtectionPolicy,
TrackingScope, TrackingScope,
@@ -67,4 +67,11 @@ class GeckoHistoryService {
}) { }) {
return _api.getHistoryHighlights(weights, limit); return _api.getHistoryHighlights(weights, limit);
} }
Future<List<TopFrecentSiteInfo>> getTopFrecentSites({
required int limit,
required FrecencyThresholdOption frecencyThreshold,
}) {
return _api.getTopFrecentSites(limit, frecencyThreshold);
}
} }
File diff suppressed because it is too large Load Diff
@@ -557,6 +557,15 @@ class HistoryHighlight {
); );
} }
class TopFrecentSiteInfo {
final String url;
final String? title;
TopFrecentSiteInfo(this.url, this.title);
}
enum FrecencyThresholdOption { none, skipOneTimePages }
class HistoryItem { class HistoryItem {
final String url; final String url;
final String title; final String title;
@@ -1823,6 +1832,12 @@ abstract class GeckoHistoryApi {
HistoryHighlightWeights weights, HistoryHighlightWeights weights,
int limit, int limit,
); );
@async
List<TopFrecentSiteInfo> getTopFrecentSites(
int limit,
FrecencyThresholdOption frecencyThreshold,
);
} }
@HostApi() @HostApi()