Auto collapse featured post if read

This commit is contained in:
2025-08-16 02:02:06 +08:00
parent 6007467e7a
commit 0ab908dd2a
2 changed files with 123 additions and 21 deletions

View File

@@ -23,6 +23,8 @@ const kAppSoundEffects = 'app_sound_effects';
const kAppAprilFoolFeatures = 'app_april_fool_features'; const kAppAprilFoolFeatures = 'app_april_fool_features';
const kAppWindowSize = 'app_window_size'; const kAppWindowSize = 'app_window_size';
const kAppEnterToSend = 'app_enter_to_send'; const kAppEnterToSend = 'app_enter_to_send';
const kFeaturedPostsCollapsedId =
'featured_posts_collapsed_id'; // Key for storing the ID of the collapsed featured post
const Map<String, FilterQuality> kImageQualityLevel = { const Map<String, FilterQuality> kImageQualityLevel = {
'settingsImageQualityLowest': FilterQuality.none, 'settingsImageQualityLowest': FilterQuality.none,

View File

@@ -7,6 +7,7 @@ import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:island/widgets/post/post_item.dart'; import 'package:island/widgets/post/post_item.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:island/pods/config.dart'; // Import config.dart for shared preferences keys and provider
part 'post_featured.g.dart'; part 'post_featured.g.dart';
@@ -25,7 +26,13 @@ class PostFeaturedList extends HookConsumerWidget {
final featuredPostsAsync = ref.watch(featuredPostsProvider); final featuredPostsAsync = ref.watch(featuredPostsProvider);
final pageViewController = usePageController(); final pageViewController = usePageController();
final prefs = ref.watch(sharedPreferencesProvider);
final pageViewCurrent = useState(0); final pageViewCurrent = useState(0);
final previousFirstPostId = useState<String?>(null);
final storedCollapsedId = useState<String?>(
prefs.getString(kFeaturedPostsCollapsedId),
);
final isCollapsed = useState(false);
useEffect(() { useEffect(() {
pageViewController.addListener(() { pageViewController.addListener(() {
@@ -34,6 +41,59 @@ class PostFeaturedList extends HookConsumerWidget {
return null; return null;
}, [pageViewController]); }, [pageViewController]);
// Log isCollapsed state changes
useEffect(() {
debugPrint(
'PostFeaturedList: isCollapsed changed to ${isCollapsed.value}',
);
return null;
}, [isCollapsed.value]);
useEffect(() {
if (featuredPostsAsync.hasValue && featuredPostsAsync.value!.isNotEmpty) {
final currentFirstPostId = featuredPostsAsync.value!.first.id;
debugPrint(
'PostFeaturedList: Current first post ID: $currentFirstPostId',
);
debugPrint(
'PostFeaturedList: Previous first post ID: ${previousFirstPostId.value}',
);
debugPrint(
'PostFeaturedList: Stored collapsed ID: ${storedCollapsedId.value}',
);
if (previousFirstPostId.value == null) {
// Initial load
previousFirstPostId.value = currentFirstPostId;
isCollapsed.value = (storedCollapsedId.value == currentFirstPostId);
debugPrint(
'PostFeaturedList: Initial load. isCollapsed set to ${isCollapsed.value}',
);
} else if (previousFirstPostId.value != currentFirstPostId) {
// First post changed, expand by default
previousFirstPostId.value = currentFirstPostId;
isCollapsed.value = false;
prefs.remove(
kFeaturedPostsCollapsedId,
); // Clear stored ID if post changes
debugPrint(
'PostFeaturedList: First post changed. isCollapsed set to false.',
);
} else {
// Same first post, maintain current collapse state
// No change needed for isCollapsed.value unless manually toggled
debugPrint(
'PostFeaturedList: Same first post. Maintaining current collapse state.',
);
}
} else {
debugPrint(
'PostFeaturedList: featuredPostsAsync has no value or is empty.',
);
}
return null;
}, [featuredPostsAsync.value]);
return ClipRRect( return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)), borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Card( child: Card(
@@ -73,10 +133,48 @@ class PostFeaturedList extends HookConsumerWidget {
}, },
icon: const Icon(Symbols.arrow_right), icon: const Icon(Symbols.arrow_right),
), ),
IconButton(
padding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
constraints: const BoxConstraints(),
onPressed: () {
isCollapsed.value = !isCollapsed.value;
debugPrint(
'PostFeaturedList: Manual toggle. isCollapsed set to ${isCollapsed.value}',
);
if (isCollapsed.value &&
featuredPostsAsync.hasValue &&
featuredPostsAsync.value!.isNotEmpty) {
prefs.setString(
kFeaturedPostsCollapsedId,
featuredPostsAsync.value!.first.id,
);
debugPrint(
'PostFeaturedList: Stored collapsed ID: ${featuredPostsAsync.value!.first.id}',
);
} else {
prefs.remove(kFeaturedPostsCollapsedId);
debugPrint(
'PostFeaturedList: Removed stored collapsed ID.',
);
}
},
icon: Icon(
isCollapsed.value
? Symbols.expand_more
: Symbols.expand_less,
),
),
], ],
).padding(horizontal: 16, vertical: 8), ).padding(horizontal: 16, vertical: 8),
featuredPostsAsync.when( AnimatedSize(
loading: () => const Center(child: CircularProgressIndicator()), duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: Visibility(
visible: !isCollapsed.value,
child: featuredPostsAsync.when(
loading:
() => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')), error: (error, stack) => Center(child: Text('Error: $error')),
data: (posts) { data: (posts) {
return SizedBox( return SizedBox(
@@ -97,6 +195,8 @@ class PostFeaturedList extends HookConsumerWidget {
); );
}, },
), ),
),
),
], ],
), ),
), ),