diff --git a/lib/screens/app_detail_screen.dart b/lib/screens/app_detail_screen.dart index bd80e70..20ee78f 100644 --- a/lib/screens/app_detail_screen.dart +++ b/lib/screens/app_detail_screen.dart @@ -117,7 +117,8 @@ class AppDetailScreen extends HookConsumerWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox(child: Text('Source ')), + Text('Source'), + Gap(10), Flexible( child: GestureDetector( onTap: () { @@ -125,7 +126,7 @@ class AppDetailScreen extends HookConsumerWidget { }, child: AutoSizeText( app.repository!, - minFontSize: 11, + minFontSize: 12, maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -155,7 +156,15 @@ class AppDetailScreen extends HookConsumerWidget { MainAxisAlignment.spaceBetween, children: [ Text('App ID'), - Text(app.identifier!) + Gap(10), + Flexible( + child: AutoSizeText( + app.identifier!, + minFontSize: 12, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ) ], ), ), @@ -246,8 +255,10 @@ class AppDetailScreen extends HookConsumerWidget { ), Gap(10), if (app.releases.isEmpty) Text('No available releases'), - if (app.releases.ordered.isNotEmpty) - ReleaseCard(release: app.releases.ordered.first), + if (app.releases.isNotEmpty) + ReleaseCard( + release: + app.releases.toList().sortedByLatest.first), ], ), ), diff --git a/lib/widgets/app_card.dart b/lib/widgets/app_card.dart index d007882..4f0068c 100644 --- a/lib/widgets/app_card.dart +++ b/lib/widgets/app_card.dart @@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:remove_markdown/remove_markdown.dart'; import 'package:skeletonizer/skeletonizer.dart'; import 'package:zapstore/models/app.dart'; +import 'package:zapstore/models/local_app.dart'; import 'package:zapstore/widgets/author_container.dart'; import 'package:zapstore/widgets/pill_widget.dart'; import 'package:zapstore/widgets/rounded_image.dart'; @@ -93,9 +94,31 @@ class AppCard extends HookConsumerWidget { ), if (app!.latestMetadata?.version != null) PillWidget( - text: app!.latestMetadata!.version!, + text: WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Text( + app!.latestMetadata!.version!, + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold), + ), + if (app!.localApp.value?.status == + AppInstallStatus.updatable) + Row(children: [ + Gap(5), + Icon(Icons.update_outlined, size: 15) + ]), + ], + ), + ), size: 10, - color: Colors.grey[800]!, + color: app!.localApp.value?.status == + AppInstallStatus.updatable + ? Color.fromARGB(255, 101, 104, 89) + : Colors.grey[700]!, ), ], ), @@ -116,7 +139,8 @@ class AppCard extends HookConsumerWidget { oneLine: true, size: 12, ), - if (showDate) Text(app!.createdAt!.toIso8601String()), + if (showDate) + Text(app!.latestRelease!.createdAt!.toIso8601String()), ], ), ), @@ -200,7 +224,7 @@ class TagsContainer extends StatelessWidget { for (final tag in tags) Padding( padding: const EdgeInsets.only(right: 6), - child: PillWidget(text: tag), + child: PillWidget(text: TextSpan(text: tag)), ), ], ); diff --git a/lib/widgets/app_curation_container.dart b/lib/widgets/app_curation_container.dart index 5b389c2..e70b959 100644 --- a/lib/widgets/app_curation_container.dart +++ b/lib/widgets/app_curation_container.dart @@ -9,8 +9,8 @@ import 'package:zapstore/models/app.dart'; import 'package:zapstore/models/app_curation_set.dart'; import 'package:zapstore/models/user.dart'; import 'package:zapstore/widgets/app_card.dart'; -import 'package:zapstore/widgets/author_container.dart'; import 'package:zapstore/widgets/pill_widget.dart'; +import 'package:zapstore/widgets/rounded_image.dart'; class AppCurationContainer extends HookConsumerWidget { const AppCurationContainer({super.key}); @@ -36,7 +36,30 @@ class AppCurationContainer extends HookConsumerWidget { onTap: () => ref.read(_selectedIdProvider.notifier).state = appCurationSet.getReplaceableEventLink(), child: PillWidget( - text: appCurationSet.name, + text: WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Text( + appCurationSet.name, + style: TextStyle(fontWeight: FontWeight.bold), + ), + if (appCurationSet.signer.isPresent) + Row( + children: [ + Text( + ' by ${appCurationSet.signer.value!.name}'), + Gap(5), + RoundedImage( + url: appCurationSet + .signer.value!.avatarUrl, + size: 16), + ], + ), + ], + ), + ), color: appCurationSet.getReplaceableEventLink() == selectedAppCurationSet ? Colors.blue[700]! @@ -53,19 +76,8 @@ class AppCurationContainer extends HookConsumerWidget { final state = ref.watch(appCurationSetProvider(selectedAppCurationSet)); return switch (state) { - AsyncData(value: final set) => Column( - children: [ - if (set.signer.isPresent) - Padding( - padding: const EdgeInsets.only(left: 6, bottom: 10), - child: AuthorContainer( - user: set.signer.value!, - text: - '${set.name} (${set.apps.length} apps) curated by'), - ), - HorizontalGrid(apps: set.apps.toList()), - ], - ), + AsyncData(value: final set) => + HorizontalGrid(apps: set.apps.toList()), _ => HorizontalGrid(apps: []), }; }, @@ -119,4 +131,4 @@ final appCurationSetProvider = AsyncNotifierProvider.family< ReplaceableEventLink>(AppCurationSetNotifier.new); final _selectedIdProvider = StateProvider( - (_) => (30267, kZapstorePubkey, 'nostr')); + (_) => (30267, kZapstorePubkey, 'privacy')); diff --git a/lib/widgets/pill_widget.dart b/lib/widgets/pill_widget.dart index 25f953e..ff872f7 100644 --- a/lib/widgets/pill_widget.dart +++ b/lib/widgets/pill_widget.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class PillWidget extends StatelessWidget { - final String text; + final InlineSpan text; final Color color; final double size; const PillWidget( @@ -18,16 +18,19 @@ class PillWidget extends StatelessWidget { color: color, borderRadius: BorderRadius.circular(size * 1.1), ), - child: Text( - text, + child: RichText( + text: TextSpan( + style: TextStyle( + color: Colors.white, + fontSize: size * 1.2, + fontWeight: FontWeight.bold, + fontFamily: 'Inter', + ), + children: [text], + ), maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, - style: TextStyle( - color: Colors.white, - fontSize: size, - fontWeight: FontWeight.bold, - ), ), ); } diff --git a/lib/widgets/versioned_app_header.dart b/lib/widgets/versioned_app_header.dart index 87d58c3..0c1dcb3 100644 --- a/lib/widgets/versioned_app_header.dart +++ b/lib/widgets/versioned_app_header.dart @@ -47,13 +47,14 @@ class VersionedAppHeader extends StatelessWidget { children: [ if (isUpdate) PillWidget( - text: app.localApp.value!.installedVersion!, + text: + TextSpan(text: app.localApp.value!.installedVersion!), color: Colors.grey[800]!, ), if (isUpdate) Icon(Icons.arrow_right), if (app.latestMetadata != null) PillWidget( - text: app.latestMetadata!.version!, + text: TextSpan(text: app.latestMetadata!.version!), color: Colors.grey[800]!, ), ],