🗑️ Clean up duplicate widget in explore and dashboard

This commit is contained in:
2025-12-21 13:37:35 +08:00
parent cb7eef943c
commit e6338e8a5a
2 changed files with 17 additions and 190 deletions

View File

@@ -16,15 +16,11 @@ import 'package:island/pods/userinfo.dart';
import 'package:island/screens/auth/login_modal.dart';
import 'package:island/screens/notification.dart';
import 'package:island/services/responsive.dart';
import 'package:island/widgets/account/account_name.dart';
import 'package:island/widgets/account/friends_overview.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/models/post.dart';
import 'package:island/widgets/check_in.dart';
import 'package:island/widgets/extended_refresh_indicator.dart';
import 'package:island/widgets/navigation/fab_menu.dart';
import 'package:island/widgets/paging/pagination_list.dart';
import 'package:island/widgets/post/post_featured.dart';
import 'package:island/widgets/post/post_item.dart';
import 'package:island/widgets/post/post_item_skeleton.dart';
import 'package:material_symbols_icons/symbols.dart';
@@ -36,38 +32,6 @@ import 'package:island/widgets/share/share_sheet.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
Widget notificationIndicatorWidget(
BuildContext context, {
required int count,
EdgeInsets? margin,
}) => Card(
margin: margin,
child: ListTile(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
minTileHeight: 48,
leading: const Icon(Symbols.notifications),
title: Row(
children: [
Text('notifications').tr().fontSize(14),
const Gap(8),
Badge(label: Text(count.toString())),
],
),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.only(left: 16, right: 15),
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) => const NotificationSheet(),
);
},
),
);
class ExploreScreen extends HookConsumerWidget {
const ExploreScreen({super.key});
@@ -502,9 +466,6 @@ class ExploreScreen extends HookConsumerWidget {
WidgetRef ref,
String? currentFilter,
) {
final user = ref.watch(userInfoProvider);
final notificationCount = ref.watch(notificationUnreadCountProvider);
final bodyView = _buildActivityList(context, ref);
final notifier = ref.watch(activityListProvider.notifier);
@@ -516,38 +477,7 @@ class ExploreScreen extends HookConsumerWidget {
onRefresh: notifier.refresh,
child: CustomScrollView(
slivers: [
const SliverGap(8),
if (user.value?.activatedAt == null)
SliverToBoxAdapter(
child: AccountUnactivatedCard().padding(bottom: 8),
),
if (user.value != null)
SliverToBoxAdapter(
child: CheckInWidget(
margin: const EdgeInsets.only(bottom: 8),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: PostFeaturedList(),
),
),
SliverToBoxAdapter(
child: FriendsOverviewWidget(
padding: const EdgeInsets.only(bottom: 8),
hideWhenEmpty: true,
),
),
if (notificationCount.value != null &&
notificationCount.value! > 0)
SliverToBoxAdapter(
child: notificationIndicatorWidget(
context,
count: notificationCount.value ?? 0,
margin: const EdgeInsets.only(bottom: 8),
),
),
SliverGap(8 + MediaQuery.paddingOf(context).top),
bodyView,
],
),

View File

@@ -17,7 +17,6 @@ import 'package:island/widgets/content/sheet.dart';
import 'package:island/widgets/account/event_calendar_content.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:slide_countdown/slide_countdown.dart';
import 'package:styled_widget/styled_widget.dart';
part 'check_in.g.dart';
@@ -52,18 +51,11 @@ Future<SnNotableDay?> nextNotableDay(Ref ref) async {
class CheckInWidget extends HookConsumerWidget {
final EdgeInsets? margin;
final VoidCallback? onChecked;
final bool checkInOnly;
const CheckInWidget({
super.key,
this.margin,
this.onChecked,
this.checkInOnly = false,
});
const CheckInWidget({super.key, this.margin, this.onChecked});
@override
Widget build(BuildContext context, WidgetRef ref) {
final todayResult = ref.watch(checkInResultTodayProvider);
final nextNotableDay = ref.watch(nextNotableDayProvider);
// Update time every second for live progress
final currentTime = useState(DateTime.now());
@@ -74,28 +66,6 @@ class CheckInWidget extends HookConsumerWidget {
return timer.cancel;
}, []);
final now = currentTime.value;
final userinfo = ref.watch(userInfoProvider);
final isAdult = useMemoized(() {
final birthday = userinfo.value?.profile.birthday;
if (birthday == null) return false;
final age =
now.year -
birthday.year -
((now.month < birthday.month ||
(now.month == birthday.month && now.day < birthday.day))
? 1
: 0);
return age >= 18;
}, [userinfo]);
final progress = (now.hour * 60.0 + now.minute) / (24 * 60);
final endOfDay = DateTime(now.year, now.month, now.day, 23, 59, 59);
final timeLeft = endOfDay.difference(now);
final timeLeftFormatted =
'${timeLeft.inHours.toString().padLeft(2, '0')}:${(timeLeft.inMinutes % 60).toString().padLeft(2, '0')}:${(timeLeft.inSeconds % 60).toString().padLeft(2, '0')}';
Future<void> checkIn({String? captchatTk}) async {
final client = ref.read(apiClientProvider);
try {
@@ -128,7 +98,6 @@ class CheckInWidget extends HookConsumerWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (checkInOnly)
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: todayResult.when(
@@ -140,66 +109,11 @@ class CheckInWidget extends HookConsumerWidget {
textAlign: TextAlign.start,
).tr().fontSize(15).bold();
},
loading: () =>
Text('checkInNone').tr().fontSize(15).bold(),
loading: () => Text('checkInNone').tr().fontSize(15).bold(),
error: (err, stack) =>
Text('error').tr().fontSize(15).bold(),
),
).padding(right: 4),
if (!checkInOnly)
Row(
spacing: 6,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
switch (DateTime.now().weekday) {
6 || 7 => Symbols.weekend,
_ => isAdult ? Symbols.work : Symbols.school,
},
fill: 1,
size: 16,
).padding(right: 2),
Text(
DateFormat('EEE').format(DateTime.now()),
).fontSize(16).bold(),
Text(
DateFormat('MM/dd').format(DateTime.now()),
).fontSize(16),
Tooltip(
message: timeLeftFormatted,
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
trackGap: 0,
value: progress,
strokeWidth: 2,
),
),
),
],
),
if (!checkInOnly)
Row(
spacing: 5,
children: [
Text('notableDayNext')
.tr(args: [nextNotableDay.value?.localName ?? 'idk'])
.fontSize(12),
if (nextNotableDay.value != null)
SlideCountdown(
decoration: const BoxDecoration(),
style: const TextStyle(fontSize: 12),
separatorStyle: const TextStyle(fontSize: 12),
padding: EdgeInsets.zero,
duration: nextNotableDay.value?.date.difference(
DateTime.now(),
),
),
],
),
const Gap(2),
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: todayResult.when(
@@ -256,23 +170,6 @@ class CheckInWidget extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.end,
spacing: 4,
children: [
if (!checkInOnly)
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: todayResult.when(
data: (result) {
return Text(
result == null
? 'checkInNone'
: 'checkInResultLevel${result.level}',
textAlign: TextAlign.start,
).tr().fontSize(15).bold();
},
loading: () => Text('checkInNone').tr().fontSize(15).bold(),
error: (err, stack) =>
Text('error').tr().fontSize(15).bold(),
),
).padding(right: 4),
IconButton.outlined(
iconSize: 16,
visualDensity: const VisualDensity(