mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
Improve preloading
This commit is contained in:
+33
-32
@@ -171,6 +171,30 @@ class App extends BaseApp with DataModelMixin<App> {
|
||||
mixin AppAdapter on Adapter<App> {
|
||||
final _queriedAtMap = <String, DateTime>{};
|
||||
|
||||
@override
|
||||
Future<List<App>> findAll(
|
||||
{bool? remote = true,
|
||||
bool? background,
|
||||
Map<String, dynamic>? params = const {},
|
||||
Map<String, String>? headers,
|
||||
bool? syncLocal,
|
||||
OnSuccessAll<App>? onSuccess,
|
||||
OnErrorAll<App>? onError,
|
||||
DataRequestLabel? label}) async {
|
||||
return await fetchAppModels(params ?? {});
|
||||
}
|
||||
|
||||
Future<List<App>> findInstalled() async {
|
||||
final appIds = await _installedIdentifiers();
|
||||
if (appIds.isNotEmpty) {
|
||||
final apps = await fetchAppModels({'#d': appIds});
|
||||
// Once apps are loaded, check for installed status
|
||||
await ref.localApps.localAppAdapter.refreshUpdateStatus();
|
||||
return apps;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
Future<List<App>> fetchAppModels(Map<String, dynamic> params) async {
|
||||
final byRelease = params.remove('by-release') != null;
|
||||
|
||||
@@ -214,6 +238,7 @@ mixin AppAdapter on Adapter<App> {
|
||||
'since': earliestQueryAt,
|
||||
},
|
||||
);
|
||||
// print('cached ${cachedApps.length} ($earliestQueryAt)');
|
||||
}
|
||||
|
||||
// For apps not in cache, query without a since
|
||||
@@ -304,38 +329,6 @@ mixin AppAdapter on Adapter<App> {
|
||||
return apps;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<App>> findAll(
|
||||
{bool? remote = true,
|
||||
bool? background,
|
||||
Map<String, dynamic>? params = const {},
|
||||
Map<String, String>? headers,
|
||||
bool? syncLocal,
|
||||
OnSuccessAll<App>? onSuccess,
|
||||
OnErrorAll<App>? onError,
|
||||
DataRequestLabel? label}) async {
|
||||
if (params!.containsKey('installed')) {
|
||||
final appIds = await _installedIdentifiers();
|
||||
if (appIds.isNotEmpty) {
|
||||
params['#d'] = appIds;
|
||||
params.remove('installed');
|
||||
final apps = await fetchAppModels(params);
|
||||
// Once apps are loaded, check for installed status
|
||||
await ref.localApps.localAppAdapter.refreshUpdateStatus();
|
||||
return apps;
|
||||
}
|
||||
}
|
||||
return await fetchAppModels(params);
|
||||
}
|
||||
|
||||
List<App> findWhereIdInLocal(Iterable<String> appIds) {
|
||||
const len = 5 + 64 + 3; // kind + pubkey + separators length
|
||||
final result = db.select(
|
||||
'SELECT key, data, substr(json_extract(data, \'\$.id\'), $len) AS id from apps where id in (${appIds.map((_) => '?').join(', ')})',
|
||||
appIds.toList());
|
||||
return deserializeFromResult(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<App?> findOne(Object id,
|
||||
{bool remote = true,
|
||||
@@ -359,6 +352,14 @@ mixin AppAdapter on Adapter<App> {
|
||||
return apps.first;
|
||||
}
|
||||
|
||||
List<App> findWhereIdInLocal(Iterable<String> appIds) {
|
||||
const len = 5 + 64 + 3; // kind + pubkey + separators length
|
||||
final result = db.select(
|
||||
'SELECT key, data, substr(json_extract(data, \'\$.id\'), $len) AS id from apps where id in (${appIds.map((_) => '?').join(', ')})',
|
||||
appIds.toList());
|
||||
return deserializeFromResult(result);
|
||||
}
|
||||
|
||||
Future<Set<String>> _installedIdentifiers() async {
|
||||
if (!Platform.isAndroid) {
|
||||
return {};
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:zapstore/models/local_app.dart';
|
||||
import 'package:zapstore/models/nostr_adapter.dart';
|
||||
import 'package:zapstore/navigation/router.dart';
|
||||
import 'package:zapstore/widgets/app_curation_container.dart';
|
||||
import 'package:zapstore/widgets/latest_releases_container.dart';
|
||||
|
||||
AppLifecycleListener? _lifecycleListener;
|
||||
|
||||
@@ -48,17 +49,17 @@ final appInitializer = FutureProvider<void>((ref) async {
|
||||
},
|
||||
);
|
||||
|
||||
// In this initial phase, load there more or less fixed curation sets here
|
||||
// Load curation sets (here for now)
|
||||
await ref.appCurationSets.findAll();
|
||||
|
||||
// Preload zapstore's nostr curation set
|
||||
await ref.read(appCurationSetProvider(kNostrCurationSet).future);
|
||||
|
||||
await ref.apps.findAll(
|
||||
params: {
|
||||
'by-release': true,
|
||||
'limit': 10,
|
||||
},
|
||||
);
|
||||
// Preload latest releases
|
||||
await ref.read(latestReleasesAppProvider.notifier).fetch();
|
||||
|
||||
// Prefetch updates in the background
|
||||
ref.apps.appAdapter.findInstalled();
|
||||
|
||||
// Handle deep links
|
||||
final appLinksSub = appLinks.uriLinkStream.listen((uri) async {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/widgets/app_card.dart';
|
||||
|
||||
class UpdatesScreen extends HookConsumerWidget {
|
||||
@@ -12,8 +13,8 @@ class UpdatesScreen extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// TODO: Workaround for bug in watchAll (when remote=true)
|
||||
final snapshot = useFuture(useMemoized(
|
||||
() => ref.apps.findAll(remote: true, params: {'installed': true})));
|
||||
final snapshot =
|
||||
useFuture(useMemoized(() => ref.apps.appAdapter.findInstalled()));
|
||||
final state = ref.apps.watchAll();
|
||||
ref.localApps.watchAll();
|
||||
|
||||
@@ -29,7 +30,7 @@ class UpdatesScreen extends HookConsumerWidget {
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () {
|
||||
return ref.apps.findAll(remote: true, params: {'installed': true});
|
||||
return ref.apps.appAdapter.findInstalled();
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
physics: AlwaysScrollableScrollPhysics(),
|
||||
|
||||
@@ -94,9 +94,6 @@ class LatestReleasesAppNotifier extends AutoDisposeAsyncNotifier<List<App>> {
|
||||
// TODO: Should be ref.watching a pool state change (from purplebase)
|
||||
final timer = Timer.periodic(Duration(minutes: 10), (_) => fetch());
|
||||
ref.onDispose(timer.cancel);
|
||||
|
||||
// Do not fetch here as first 10 are preloaded
|
||||
// await fetch();
|
||||
return localFetch();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user