From bab602d98b2bfebc4a5833ca7e411b28fab95652 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 22 Aug 2025 01:41:25 +0800 Subject: [PATCH] :sparkles: Shuffle post --- assets/i18n/en-US.json | 3 ++- lib/route.dart | 6 +++++ lib/screens/explore.dart | 12 +++++++++ lib/screens/posts/post_categories_list.dart | 4 +-- lib/widgets/post/post_list.dart | 7 ++++++ lib/widgets/post/post_list.g.dart | 28 ++++++++++++++++++--- lib/widgets/post/post_shuffle.dart | 17 +++++++++++++ 7 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 lib/widgets/post/post_shuffle.dart diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index faeff2e7..71e01b3b 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -864,5 +864,6 @@ "mimeType": "MIME Type", "fileSize": "File Size", "fileHash": "File Hash", - "exifData": "EXIF Data" + "exifData": "EXIF Data", + "postShuffle": "Shuffle Posts" } diff --git a/lib/route.dart b/lib/route.dart index 89a1dbb6..5bcbde7b 100644 --- a/lib/route.dart +++ b/lib/route.dart @@ -53,6 +53,7 @@ import 'package:island/screens/account/event_calendar.dart'; import 'package:island/screens/discovery/realms.dart'; import 'package:island/screens/reports/report_detail.dart'; import 'package:island/screens/reports/report_list.dart'; +import 'package:island/widgets/post/post_shuffle.dart'; // Shell route keys for nested navigation final rootNavigatorKey = GlobalKey(); @@ -376,6 +377,11 @@ final routerProvider = Provider((ref) { path: '/posts/search', builder: (context, state) => const PostSearchScreen(), ), + GoRoute( + name: 'postShuffle', + path: '/posts/shuffle', + builder: (context, state) => const PostShuffleScreen(), + ), GoRoute( name: 'postCategories', path: '/posts/categories', diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index be1644cd..ca3b1662 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -200,6 +200,18 @@ class ExploreScreen extends HookConsumerWidget { context.pushNamed('postTags'); }, ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Symbols.shuffle), + const Gap(12), + Text('postShuffle').tr(), + ], + ), + onTap: () { + context.pushNamed('postShuffle'); + }, + ), PopupMenuItem( child: Row( children: [ diff --git a/lib/screens/posts/post_categories_list.dart b/lib/screens/posts/post_categories_list.dart index f0f7393e..5640efc1 100644 --- a/lib/screens/posts/post_categories_list.dart +++ b/lib/screens/posts/post_categories_list.dart @@ -145,7 +145,7 @@ class PostCategoriesListScreen extends ConsumerWidget { final categoriesState = ref.watch(postCategoriesNotifierProvider); return AppScaffold( - appBar: AppBar(title: const Text('Categories')), + appBar: AppBar(title: const Text('categories').tr()), body: categoriesState.when( data: (data) { if (data.items.isEmpty) { @@ -197,7 +197,7 @@ class PostTagsListScreen extends ConsumerWidget { final tagsState = ref.watch(postTagsNotifierProvider); return AppScaffold( - appBar: AppBar(title: const Text('Tags')), + appBar: AppBar(title: const Text('tags').tr()), body: tagsState.when( data: (data) { if (data.items.isEmpty) { diff --git a/lib/widgets/post/post_list.dart b/lib/widgets/post/post_list.dart index 14ce8eb4..f5de94e2 100644 --- a/lib/widgets/post/post_list.dart +++ b/lib/widgets/post/post_list.dart @@ -21,6 +21,7 @@ class PostListNotifier extends _$PostListNotifier int? type, List? categories, List? tags, + bool shuffle = false, }) { return fetch(cursor: null); } @@ -38,6 +39,7 @@ class PostListNotifier extends _$PostListNotifier if (type != null) 'type': type, if (tags != null) 'tags': tags, if (categories != null) 'categories': categories, + if (shuffle) 'shuffle': true, }; final response = await client.get( @@ -74,6 +76,7 @@ class SliverPostList extends HookConsumerWidget { final int? type; final List? categories; final List? tags; + final bool shuffle; final PostItemType itemType; final Color? backgroundColor; final EdgeInsets? padding; @@ -88,6 +91,7 @@ class SliverPostList extends HookConsumerWidget { this.type, this.categories, this.tags, + this.shuffle = false, this.itemType = PostItemType.regular, this.backgroundColor, this.padding, @@ -105,6 +109,7 @@ class SliverPostList extends HookConsumerWidget { type: type, categories: categories, tags: tags, + shuffle: shuffle, ), futureRefreshable: postListNotifierProvider( @@ -113,6 +118,7 @@ class SliverPostList extends HookConsumerWidget { type: type, categories: categories, tags: tags, + shuffle: shuffle, ).future, notifierRefreshable: postListNotifierProvider( @@ -121,6 +127,7 @@ class SliverPostList extends HookConsumerWidget { type: type, categories: categories, tags: tags, + shuffle: shuffle, ).notifier, contentBuilder: (data, widgetCount, endItemView) => SliverList.builder( diff --git a/lib/widgets/post/post_list.g.dart b/lib/widgets/post/post_list.g.dart index c8944439..3aa004bc 100644 --- a/lib/widgets/post/post_list.g.dart +++ b/lib/widgets/post/post_list.g.dart @@ -6,7 +6,7 @@ part of 'post_list.dart'; // RiverpodGenerator // ************************************************************************** -String _$postListNotifierHash() => r'9784b282b3ee14b7109e263c5841a082cf0be78e'; +String _$postListNotifierHash() => r'27dc73b92a057b396e8ac026d4392508aedea4f5'; /// Copied from Dart SDK class _SystemHash { @@ -36,6 +36,7 @@ abstract class _$PostListNotifier late final int? type; late final List? categories; late final List? tags; + late final bool shuffle; FutureOr> build({ String? pubName, @@ -43,6 +44,7 @@ abstract class _$PostListNotifier int? type, List? categories, List? tags, + bool shuffle = false, }); } @@ -63,6 +65,7 @@ class PostListNotifierFamily int? type, List? categories, List? tags, + bool shuffle = false, }) { return PostListNotifierProvider( pubName: pubName, @@ -70,6 +73,7 @@ class PostListNotifierFamily type: type, categories: categories, tags: tags, + shuffle: shuffle, ); } @@ -83,6 +87,7 @@ class PostListNotifierFamily type: provider.type, categories: provider.categories, tags: provider.tags, + shuffle: provider.shuffle, ); } @@ -115,6 +120,7 @@ class PostListNotifierProvider int? type, List? categories, List? tags, + bool shuffle = false, }) : this._internal( () => PostListNotifier() @@ -122,7 +128,8 @@ class PostListNotifierProvider ..realm = realm ..type = type ..categories = categories - ..tags = tags, + ..tags = tags + ..shuffle = shuffle, from: postListNotifierProvider, name: r'postListNotifierProvider', debugGetCreateSourceHash: @@ -137,6 +144,7 @@ class PostListNotifierProvider type: type, categories: categories, tags: tags, + shuffle: shuffle, ); PostListNotifierProvider._internal( @@ -151,6 +159,7 @@ class PostListNotifierProvider required this.type, required this.categories, required this.tags, + required this.shuffle, }) : super.internal(); final String? pubName; @@ -158,6 +167,7 @@ class PostListNotifierProvider final int? type; final List? categories; final List? tags; + final bool shuffle; @override FutureOr> runNotifierBuild( @@ -169,6 +179,7 @@ class PostListNotifierProvider type: type, categories: categories, tags: tags, + shuffle: shuffle, ); } @@ -183,7 +194,8 @@ class PostListNotifierProvider ..realm = realm ..type = type ..categories = categories - ..tags = tags, + ..tags = tags + ..shuffle = shuffle, from: from, name: null, dependencies: null, @@ -194,6 +206,7 @@ class PostListNotifierProvider type: type, categories: categories, tags: tags, + shuffle: shuffle, ), ); } @@ -214,7 +227,8 @@ class PostListNotifierProvider other.realm == realm && other.type == type && other.categories == categories && - other.tags == tags; + other.tags == tags && + other.shuffle == shuffle; } @override @@ -225,6 +239,7 @@ class PostListNotifierProvider hash = _SystemHash.combine(hash, type.hashCode); hash = _SystemHash.combine(hash, categories.hashCode); hash = _SystemHash.combine(hash, tags.hashCode); + hash = _SystemHash.combine(hash, shuffle.hashCode); return _SystemHash.finish(hash); } @@ -248,6 +263,9 @@ mixin PostListNotifierRef /// The parameter `tags` of this provider. List? get tags; + + /// The parameter `shuffle` of this provider. + bool get shuffle; } class _PostListNotifierProviderElement @@ -270,6 +288,8 @@ class _PostListNotifierProviderElement (origin as PostListNotifierProvider).categories; @override List? get tags => (origin as PostListNotifierProvider).tags; + @override + bool get shuffle => (origin as PostListNotifierProvider).shuffle; } // ignore_for_file: type=lint diff --git a/lib/widgets/post/post_shuffle.dart b/lib/widgets/post/post_shuffle.dart new file mode 100644 index 00000000..1ec67472 --- /dev/null +++ b/lib/widgets/post/post_shuffle.dart @@ -0,0 +1,17 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:island/widgets/app_scaffold.dart'; +import 'package:island/widgets/post/post_list.dart'; + +class PostShuffleScreen extends HookConsumerWidget { + const PostShuffleScreen({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return AppScaffold( + appBar: AppBar(title: const Text('postShuffle').tr()), + body: CustomScrollView(slivers: [SliverPostList(shuffle: true)]), + ); + } +}