Prefix subscriptions with app- (we need it for the relay)

This commit is contained in:
franzap
2026-01-23 17:10:38 -03:00
parent 8197355cd3
commit e4cc62ec0b
8 changed files with 55 additions and 37 deletions
+1 -1
View File
@@ -172,7 +172,7 @@ class _SearchResultsSection extends HookConsumerWidget {
// Force the search to hit the default relay group (relay.zapstore.dev)
// so a connection appears in Debug Info when searching.
source: const RemoteSource(relays: 'AppCatalog', stream: false),
subscriptionPrefix: 'search-results',
subscriptionPrefix: 'app-search-results',
),
);
+3 -3
View File
@@ -40,9 +40,9 @@ class _ConnectionStatusIndicator extends ConsumerWidget {
final poolState = ref.watch(poolStateProvider);
final subscriptions = poolState?.subscriptions ?? {};
// Filter to only "updates" subscription
// Filter to only "app-updates" subscription
final updatesSubs = subscriptions.entries
.where((e) => e.key.startsWith('updates'))
.where((e) => e.key.startsWith('app-updates'))
.map((e) => e.value);
// Check relay status for updates subscription only
@@ -189,7 +189,7 @@ class _UpdatesListBodyWithInstallingAppIds extends ConsumerWidget {
tags: {'#d': installingAppIds},
and: (app) => {app.latestRelease.query()},
source: const LocalAndRemoteSource(relays: 'AppCatalog'),
subscriptionPrefix: 'installing-apps',
subscriptionPrefix: 'app-installing-apps',
),
);
+1 -1
View File
@@ -49,7 +49,7 @@ class UserScreen extends HookConsumerWidget {
),
},
source: const LocalAndRemoteSource(relays: 'AppCatalog', stream: false),
subscriptionPrefix: 'user-apps',
subscriptionPrefix: 'app-user-apps',
),
);
+1 -1
View File
@@ -104,7 +104,7 @@ class CategorizedAppsNotifier extends Notifier<CategorizedApps> {
),
},
source: const LocalAndRemoteSource(relays: 'AppCatalog', stream: true),
subscriptionPrefix: 'updates',
subscriptionPrefix: 'app-updates',
),
);
+1 -1
View File
@@ -735,7 +735,7 @@ class DebugVersionsSection extends HookConsumerWidget {
tags: app.event.addressableIdTagMap,
and: (release) => {release.latestMetadata.query(), release.latestAsset.query()},
source: LocalAndRemoteSource(relays: 'AppCatalog', stream: false),
subscriptionPrefix: 'debug-releases',
subscriptionPrefix: 'app-debug-releases',
),
);
+41 -27
View File
@@ -31,11 +31,7 @@ String? _extractIdentifier(String addressableId) {
List<String> _getPreviewIdentifiers(AppStack stack) {
final rawTags = _getRawAppTagValues(stack).toList()
..shuffle(Random(stack.id.hashCode));
return rawTags
.take(3)
.map(_extractIdentifier)
.whereType<String>()
.toList();
return rawTags.take(3).map(_extractIdentifier).whereType<String>().toList();
}
/// Sort app stacks: franzap/following first, then by recency
@@ -67,10 +63,12 @@ List<AppStack> _sortStacks(
others.sort((a, b) => b.event.createdAt.compareTo(a.event.createdAt));
return [...followed, ...others];
} else {
final franzapStacks =
stacks.where((s) => s.pubkey == kFranzapPubkey).toList();
final otherStacks =
stacks.where((s) => s.pubkey != kFranzapPubkey).toList();
final franzapStacks = stacks
.where((s) => s.pubkey == kFranzapPubkey)
.toList();
final otherStacks = stacks
.where((s) => s.pubkey != kFranzapPubkey)
.toList();
franzapStacks.shuffle(random);
otherStacks.sort((a, b) => b.event.createdAt.compareTo(a.event.createdAt));
@@ -198,8 +196,10 @@ class AppStackContainer extends HookConsumerWidget {
scrollController.position.maxScrollExtent - 200) {
// Load more if we haven't shown all stacks yet
if (visibleCount.value < sortedStacks.length) {
visibleCount.value = (visibleCount.value + _kBatchSize)
.clamp(0, sortedStacks.length);
visibleCount.value = (visibleCount.value + _kBatchSize).clamp(
0,
sortedStacks.length,
);
}
}
}
@@ -231,9 +231,13 @@ class AppStackContainer extends HookConsumerWidget {
if (col * 2 < displayedStacks.length)
_StackCard(
stack: displayedStacks[col * 2],
author: authorsMap[displayedStacks[col * 2].event.pubkey],
isAuthorLoading: isAuthorLoading(displayedStacks[col * 2].event.pubkey),
previewIdentifiers: stackPreviewIds[displayedStacks[col * 2].id] ?? [],
author:
authorsMap[displayedStacks[col * 2].event.pubkey],
isAuthorLoading: isAuthorLoading(
displayedStacks[col * 2].event.pubkey,
),
previewIdentifiers:
stackPreviewIds[displayedStacks[col * 2].id] ?? [],
appsMap: appsMap,
),
// Bottom item
@@ -241,9 +245,16 @@ class AppStackContainer extends HookConsumerWidget {
const SizedBox(height: 10),
_StackCard(
stack: displayedStacks[col * 2 + 1],
author: authorsMap[displayedStacks[col * 2 + 1].event.pubkey],
isAuthorLoading: isAuthorLoading(displayedStacks[col * 2 + 1].event.pubkey),
previewIdentifiers: stackPreviewIds[displayedStacks[col * 2 + 1].id] ?? [],
author:
authorsMap[displayedStacks[col * 2 + 1]
.event
.pubkey],
isAuthorLoading: isAuthorLoading(
displayedStacks[col * 2 + 1].event.pubkey,
),
previewIdentifiers:
stackPreviewIds[displayedStacks[col * 2 + 1].id] ??
[],
appsMap: appsMap,
),
],
@@ -450,9 +461,7 @@ class _AppIconsRow extends StatelessWidget {
aspectRatio: 1,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.surfaceContainerHighest
color: Theme.of(context).colorScheme.surfaceContainerHighest
.withValues(alpha: 0.8),
borderRadius: BorderRadius.circular(10),
),
@@ -481,10 +490,9 @@ class _AppIconsRow extends StatelessWidget {
aspectRatio: 1,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.surfaceContainerHighest
.withValues(alpha: 0.5),
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(10),
),
),
@@ -520,10 +528,14 @@ class _AppIconTile extends StatelessWidget {
fit: BoxFit.cover,
fadeInDuration: const Duration(milliseconds: 200),
placeholder: (_, __) => Container(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
),
errorWidget: (_, __, ___) => Container(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: const Icon(
Icons.broken_image_outlined,
size: 16,
@@ -532,7 +544,9 @@ class _AppIconTile extends StatelessWidget {
),
)
: Container(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: const Icon(
Icons.apps_outlined,
size: 16,
+3 -3
View File
@@ -321,7 +321,7 @@ class LatestReleasesNotifier extends StateNotifier<LatestReleasesState> {
},
// NOTE: It must stream=true
source: const LocalAndRemoteSource(relays: 'AppCatalog', stream: true),
subscriptionPrefix: 'latest',
subscriptionPrefix: 'app-latest',
),
(previous, next) async {
// Always mirror storage state and ensure olderApps don't duplicate the live head
@@ -446,9 +446,9 @@ class _LatestReleasesStatusDot extends ConsumerWidget {
final poolState = ref.watch(poolStateProvider);
final subscriptions = poolState?.subscriptions ?? {};
// Filter to only "latest" subscription
// Filter to only "app-latest" subscription
final latestSubs = subscriptions.entries
.where((e) => e.key.startsWith('latest'))
.where((e) => e.key.startsWith('app-latest'))
.map((e) => e.value);
// Check relay status for latest subscription
+4
View File
@@ -95,4 +95,8 @@ onPressed: () async {
}
```
### Subscription prefix naming
All queries using the `AppCatalog` relay group MUST prefix their `subscriptionPrefix` with `app-`. This is used in the backend.
For detailed API, see models/purplebase READMEs in pub cache.