♻️ Refactored post loading

This commit is contained in:
2025-12-06 18:20:47 +08:00
parent 240509ceff
commit 16c7b7e764
11 changed files with 745 additions and 971 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/pods/post/post_list.dart';
@@ -17,21 +18,7 @@ enum PostItemType {
}
class SliverPostList extends HookConsumerWidget {
final String? pubName;
final String? realm;
final int? type;
final List<String>? categories;
final List<String>? tags;
final bool shuffle;
final bool? pinned;
final bool? includeReplies;
final bool? mediaOnly;
final String? queryTerm;
// Can be "populaurity", other value will be treated as "date"
final String? order;
final int? periodStart;
final int? periodEnd;
final bool? orderDesc;
final PostListQuery? query;
final PostItemType itemType;
final Color? backgroundColor;
final EdgeInsets? padding;
@@ -39,23 +26,11 @@ class SliverPostList extends HookConsumerWidget {
final Function? onRefresh;
final Function(SnPost)? onUpdate;
final double? maxWidth;
final String? queryKey;
const SliverPostList({
super.key,
this.pubName,
this.realm,
this.type,
this.categories,
this.tags,
this.shuffle = false,
this.pinned,
this.includeReplies,
this.mediaOnly,
this.queryTerm,
this.order,
this.orderDesc = true,
this.periodStart,
this.periodEnd,
this.query,
this.itemType = PostItemType.regular,
this.backgroundColor,
this.padding,
@@ -63,29 +38,19 @@ class SliverPostList extends HookConsumerWidget {
this.onRefresh,
this.onUpdate,
this.maxWidth,
this.queryKey,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final params = PostListQuery(
pubName: pubName,
realm: realm,
type: type,
categories: categories,
tags: tags,
shuffle: shuffle,
pinned: pinned,
includeReplies: includeReplies,
mediaOnly: mediaOnly,
queryTerm: queryTerm,
order: order,
periodStart: periodStart,
periodEnd: periodEnd,
orderDesc: orderDesc ?? true,
);
final provider = postListNotifierProvider(params);
final provider = postListProvider(queryKey);
final notifier = provider.notifier;
useEffect(() {
ref.read(notifier).applyFilter(query!);
return null;
}, [query]);
return PaginationList(
provider: provider,
notifier: notifier,

View File

@@ -3,26 +3,29 @@ import 'package:flutter/material.dart';
import 'package:flutter_card_swiper/flutter_card_swiper.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/post/post_list.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/post/post_item.dart';
import 'package:island/widgets/post/post_list.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart';
const kShufflePostListId = 'shuffle';
class PostShuffleScreen extends HookConsumerWidget {
const PostShuffleScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
const params = PostListQuery(shuffle: true);
final postListState = ref.watch(postListNotifierProvider(params));
const query = PostListQuery(shuffle: true);
final postListState = ref.watch(postListProvider(kShufflePostListId));
final postListNotifier = ref.watch(
postListNotifierProvider(params).notifier,
postListProvider(kShufflePostListId).notifier,
);
final cardSwiperController = useMemoized(() => CardSwiperController(), []);
useEffect(() {
postListNotifier.applyFilter(query);
return cardSwiperController.dispose;
}, []);
@@ -46,29 +49,32 @@ class PostShuffleScreen extends HookConsumerWidget {
controller: cardSwiperController,
cardsCount: items.length,
isLoop: false,
cardBuilder: (
context,
index,
horizontalOffsetPercentage,
verticalOffsetPercentage,
) {
return Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 540),
child: SingleChildScrollView(
child: Card(
margin: EdgeInsets.zero,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(8),
cardBuilder:
(
context,
index,
horizontalOffsetPercentage,
verticalOffsetPercentage,
) {
return Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 540),
child: SingleChildScrollView(
child: Card(
margin: EdgeInsets.zero,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(8),
),
child: PostActionableItem(
item: items[index],
),
),
),
child: PostActionableItem(item: items[index]),
),
),
),
),
);
},
);
},
onEnd: () async {
if (!postListNotifier.fetchedAll) {
postListNotifier.fetchFurther();
@@ -91,24 +97,23 @@ class PostShuffleScreen extends HookConsumerWidget {
bottom: MediaQuery.of(context).padding.bottom,
),
height: kBottomControlHeight,
child:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {
cardSwiperController.undo();
},
icon: const Icon(Symbols.arrow_left_alt),
),
IconButton(
onPressed: () {
cardSwiperController.swipe(CardSwiperDirection.right);
},
icon: const Icon(Symbols.arrow_right_alt),
),
],
).padding(all: 8).center(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () {
cardSwiperController.undo();
},
icon: const Icon(Symbols.arrow_left_alt),
),
IconButton(
onPressed: () {
cardSwiperController.swipe(CardSwiperDirection.right);
},
icon: const Icon(Symbols.arrow_right_alt),
),
],
).padding(all: 8).center(),
),
),
],