mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
Fix latest releases bug
This commit is contained in:
@@ -31,12 +31,12 @@ class LatestReleasesState {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory LatestReleasesState.loading() => const LatestReleasesState(
|
factory LatestReleasesState.loading() => const LatestReleasesState(
|
||||||
firstPage: [],
|
firstPage: [],
|
||||||
olderPages: [],
|
olderPages: [],
|
||||||
appsByIdentifier: {},
|
appsByIdentifier: {},
|
||||||
isLoadingMore: false,
|
isLoadingMore: false,
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool get isLoading =>
|
bool get isLoading =>
|
||||||
firstPage.isEmpty && olderPages.isEmpty && error == null;
|
firstPage.isEmpty && olderPages.isEmpty && error == null;
|
||||||
@@ -50,15 +50,14 @@ class LatestReleasesState {
|
|||||||
bool? isLoadingMore,
|
bool? isLoadingMore,
|
||||||
bool? hasMore,
|
bool? hasMore,
|
||||||
Object? error,
|
Object? error,
|
||||||
}) =>
|
}) => LatestReleasesState(
|
||||||
LatestReleasesState(
|
firstPage: firstPage ?? this.firstPage,
|
||||||
firstPage: firstPage ?? this.firstPage,
|
olderPages: olderPages ?? this.olderPages,
|
||||||
olderPages: olderPages ?? this.olderPages,
|
appsByIdentifier: appsByIdentifier ?? this.appsByIdentifier,
|
||||||
appsByIdentifier: appsByIdentifier ?? this.appsByIdentifier,
|
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
||||||
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
hasMore: hasMore ?? this.hasMore,
|
||||||
hasMore: hasMore ?? this.hasMore,
|
error: error,
|
||||||
error: error,
|
);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -78,18 +77,19 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
_sub = ref.listen(
|
_sub = ref.listen(
|
||||||
query<Release>(
|
query<Release>(
|
||||||
limit: _kPageSize,
|
limit: _kPageSize,
|
||||||
where: (r) => r.event.getTagSetValues('f').contains('android-arm64-v8a'),
|
|
||||||
source: const LocalAndRemoteSource(relays: 'AppCatalog', stream: true),
|
source: const LocalAndRemoteSource(relays: 'AppCatalog', stream: true),
|
||||||
subscriptionPrefix: 'app-latest-releases',
|
subscriptionPrefix: 'app-latest-releases',
|
||||||
),
|
),
|
||||||
(_, next) async {
|
(_, next) async {
|
||||||
if (next is StorageData<Release>) {
|
if (next is StorageData<Release>) {
|
||||||
final liveIds = next.models.map((r) => r.id).toSet();
|
final liveIds = next.models.map((r) => r.id).toSet();
|
||||||
final filteredOlder =
|
final filteredOlder = state.olderPages
|
||||||
state.olderPages.where((r) => !liveIds.contains(r.id)).toList();
|
.where((r) => !liveIds.contains(r.id))
|
||||||
|
.toList();
|
||||||
final unresolved = next.models
|
final unresolved = next.models
|
||||||
.where((r) =>
|
.where(
|
||||||
!state.appsByIdentifier.containsKey(r.appIdentifier))
|
(r) => !state.appsByIdentifier.containsKey(r.appIdentifier),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final apps = await _resolveRelated(unresolved);
|
final apps = await _resolveRelated(unresolved);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
@@ -127,20 +127,17 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
subscriptionPrefix: 'app-latest-releases-older',
|
subscriptionPrefix: 'app-latest-releases-older',
|
||||||
);
|
);
|
||||||
|
|
||||||
final filtered = releases
|
if (releases.isEmpty) {
|
||||||
.where((r) => r.event.getTagSetValues('f').contains('android-arm64-v8a'))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (filtered.isEmpty) {
|
|
||||||
state = state.copyWith(isLoadingMore: false, hasMore: false);
|
state = state.copyWith(isLoadingMore: false, hasMore: false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final apps = await _resolveRelated(filtered);
|
final apps = await _resolveRelated(releases);
|
||||||
|
|
||||||
final existingIds = all.map((r) => r.id).toSet();
|
final existingIds = all.map((r) => r.id).toSet();
|
||||||
final unique =
|
final unique = releases
|
||||||
filtered.where((r) => !existingIds.contains(r.id)).toList();
|
.where((r) => !existingIds.contains(r.id))
|
||||||
|
.toList();
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
olderPages: [...state.olderPages, ...unique],
|
olderPages: [...state.olderPages, ...unique],
|
||||||
appsByIdentifier: {...state.appsByIdentifier, ...apps},
|
appsByIdentifier: {...state.appsByIdentifier, ...apps},
|
||||||
@@ -158,8 +155,9 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
if (releases.isEmpty) return const {};
|
if (releases.isEmpty) return const {};
|
||||||
final storage = ref.read(storageNotifierProvider.notifier);
|
final storage = ref.read(storageNotifierProvider.notifier);
|
||||||
|
|
||||||
final assetIds =
|
final assetIds = releases
|
||||||
releases.expand((r) => r.event.getTagSetValues('e')).toSet();
|
.expand((r) => r.event.getTagSetValues('e'))
|
||||||
|
.toSet();
|
||||||
final appIds = releases
|
final appIds = releases
|
||||||
.map((r) => r.appIdentifier)
|
.map((r) => r.appIdentifier)
|
||||||
.where((id) => id.isNotEmpty)
|
.where((id) => id.isNotEmpty)
|
||||||
@@ -170,7 +168,9 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
storage.query(
|
storage.query(
|
||||||
RequestFilter<SoftwareAsset>(
|
RequestFilter<SoftwareAsset>(
|
||||||
ids: assetIds,
|
ids: assetIds,
|
||||||
tags: {'#f': {'android-arm64-v8a'}},
|
tags: {
|
||||||
|
'#f': {'android-arm64-v8a'},
|
||||||
|
},
|
||||||
).toRequest(),
|
).toRequest(),
|
||||||
source: const LocalAndRemoteSource(
|
source: const LocalAndRemoteSource(
|
||||||
relays: 'AppCatalog',
|
relays: 'AppCatalog',
|
||||||
@@ -180,9 +180,7 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
),
|
),
|
||||||
if (appIds.isNotEmpty)
|
if (appIds.isNotEmpty)
|
||||||
storage.query(
|
storage.query(
|
||||||
RequestFilter<App>(
|
RequestFilter<App>(tags: {'#d': appIds}).toRequest(),
|
||||||
tags: {'#d': appIds, '#f': {'android-arm64-v8a'}},
|
|
||||||
).toRequest(),
|
|
||||||
source: const LocalAndRemoteSource(
|
source: const LocalAndRemoteSource(
|
||||||
relays: 'AppCatalog',
|
relays: 'AppCatalog',
|
||||||
stream: false,
|
stream: false,
|
||||||
@@ -194,11 +192,19 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
if (appIds.isEmpty) return const {};
|
if (appIds.isEmpty) return const {};
|
||||||
|
|
||||||
final apps = appIds
|
final apps = appIds
|
||||||
.expand((id) => storage.querySync(
|
.expand(
|
||||||
RequestFilter<App>(tags: {'#d': {id}}, limit: 1).toRequest(),
|
(id) => storage.querySync(
|
||||||
))
|
RequestFilter<App>(
|
||||||
|
tags: {
|
||||||
|
'#d': {id},
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
).toRequest(),
|
||||||
|
),
|
||||||
|
)
|
||||||
.cast<App>()
|
.cast<App>()
|
||||||
.toList();
|
.toList();
|
||||||
|
'${apps.map((a) => a.identifier).toList()}';
|
||||||
await loadAuthors(storage, apps, 'app-latest-releases-authors');
|
await loadAuthors(storage, apps, 'app-latest-releases-authors');
|
||||||
|
|
||||||
return {for (final app in apps) app.identifier: app};
|
return {for (final app in apps) app.identifier: app};
|
||||||
@@ -213,8 +219,8 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
|
|||||||
|
|
||||||
final latestReleasesProvider =
|
final latestReleasesProvider =
|
||||||
StateNotifierProvider<LatestReleasesNotifier, LatestReleasesState>((ref) {
|
StateNotifierProvider<LatestReleasesNotifier, LatestReleasesState>((ref) {
|
||||||
return LatestReleasesNotifier(ref);
|
return LatestReleasesNotifier(ref);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Widget
|
// Widget
|
||||||
@@ -264,6 +270,7 @@ class LatestReleasesContainer extends HookConsumerWidget {
|
|||||||
ref.read(latestReleasesProvider.notifier).loadMore();
|
ref.read(latestReleasesProvider.notifier).loadMore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollController.addListener(onScroll);
|
scrollController.addListener(onScroll);
|
||||||
return () => scrollController.removeListener(onScroll);
|
return () => scrollController.removeListener(onScroll);
|
||||||
}, [scrollController, state]);
|
}, [scrollController, state]);
|
||||||
@@ -288,7 +295,13 @@ class LatestReleasesContainer extends HookConsumerWidget {
|
|||||||
if (state.isLoadingMore)
|
if (state.isLoadingMore)
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.all(16.0),
|
padding: EdgeInsets.all(16.0),
|
||||||
child: Center(child: CircularProgressIndicator()),
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 5),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
@@ -313,10 +326,9 @@ class LatestReleasesContainer extends HookConsumerWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'LATEST RELEASES',
|
'LATEST RELEASES',
|
||||||
style: context.textTheme.labelLarge?.copyWith(
|
style: context.textTheme.labelLarge?.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(
|
||||||
.colorScheme
|
context,
|
||||||
.onSurface
|
).colorScheme.onSurface.withValues(alpha: 0.85),
|
||||||
.withValues(alpha: 0.85),
|
|
||||||
letterSpacing: 1.5,
|
letterSpacing: 1.5,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user