diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index 096f8a7..bf4e808 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -193,10 +193,7 @@ class ActivityListNotifier extends _$ActivityListNotifier final response = await client.get( '/activities', - queryParameters: { - if (cursor != null) 'reading_cursor': cursor, - 'take': take, - }, + queryParameters: {if (cursor != null) 'cursor': cursor, 'take': take}, ); final List items = @@ -206,7 +203,12 @@ class ActivityListNotifier extends _$ActivityListNotifier final hasMore = (items.firstOrNull?.type ?? 'empty') != 'empty'; final nextCursor = - items.map((x) => x.createdAt).lastOrNull?.toIso8601String().toString(); + items + .map((x) => x.createdAt) + .lastOrNull + ?.toUtc() + .toIso8601String() + .toString(); return CursorPagingData( items: items, diff --git a/lib/screens/explore.g.dart b/lib/screens/explore.g.dart index 1020078..bfda7ef 100644 --- a/lib/screens/explore.g.dart +++ b/lib/screens/explore.g.dart @@ -7,7 +7,7 @@ part of 'explore.dart'; // ************************************************************************** String _$activityListNotifierHash() => - r'2ca8fe14686d7f4fb09ab26f2978eb2de7184565'; + r'1ac57c33c7a65700116a9698209f52cd4be932cc'; /// See also [ActivityListNotifier]. @ProviderFor(ActivityListNotifier) diff --git a/lib/widgets/account/account_pfc.dart b/lib/widgets/account/account_pfc.dart new file mode 100644 index 0000000..5c5c88a --- /dev/null +++ b/lib/widgets/account/account_pfc.dart @@ -0,0 +1,130 @@ +import 'dart:math' as math; + +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_popup_card/flutter_popup_card.dart'; +import 'package:gap/gap.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:island/screens/account/profile.dart'; +import 'package:island/widgets/account/account_name.dart'; +import 'package:island/widgets/account/badge.dart'; +import 'package:island/widgets/account/leveling_progress.dart'; +import 'package:island/widgets/account/status.dart'; +import 'package:island/widgets/content/cloud_files.dart'; +import 'package:island/widgets/response.dart'; +import 'package:styled_widget/styled_widget.dart'; + +class AccountProfileCard extends HookConsumerWidget { + final String uname; + const AccountProfileCard({super.key, required this.uname}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final account = ref.watch(accountProvider(uname)); + final width = + math.max(MediaQuery.of(context).size.width - 80, 360).toDouble(); + return PopupCard( + elevation: 8, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)), + child: SizedBox( + width: width, + child: account.when( + data: + (data) => Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ClipRRect( + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12), + ), + child: AspectRatio( + aspectRatio: 16 / 9, + child: CloudImageWidget(file: data.profile.background), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + ProfilePictureWidget(file: data.profile.picture), + const Gap(12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AccountName( + account: data, + style: TextStyle(fontWeight: FontWeight.bold), + ), + Text('@${data.name}').fontSize(12), + ], + ), + ), + ], + ), + const Gap(12), + AccountStatusWidget( + uname: data.name, + padding: EdgeInsets.zero, + ), + if (data.badges.isNotEmpty) + BadgeList(badges: data.badges).padding(top: 12), + LevelingProgressCard( + level: data.profile.level, + experience: data.profile.experience, + progress: data.profile.levelingProgress, + ).padding(top: 12), + ], + ).padding(horizontal: 24, vertical: 16), + ], + ), + error: + (err, _) => ResponseErrorWidget( + error: err, + onRetry: () => ref.invalidate(accountProvider(uname)), + ), + loading: + () => Padding( + padding: const EdgeInsets.all(24), + child: CircularProgressIndicator(), + ), + ), + ), + ); + } +} + +class AccountPfcGestureDetector extends StatelessWidget { + final String uname; + final Widget child; + const AccountPfcGestureDetector({ + super.key, + required this.uname, + required this.child, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: child, + onTapDown: (details) { + showAccountProfileCard(context, uname, offset: details.localPosition); + }, + ); + } +} + +Future showAccountProfileCard( + BuildContext context, + String uname, { + Offset? offset, +}) async { + await showPopupCard( + offset: offset ?? Offset.zero, + context: context, + builder: (context) => AccountProfileCard(uname: uname), + dimBackground: true, + ); +} diff --git a/lib/widgets/chat/message_item.dart b/lib/widgets/chat/message_item.dart index f500fe0..4edcca1 100644 --- a/lib/widgets/chat/message_item.dart +++ b/lib/widgets/chat/message_item.dart @@ -10,6 +10,7 @@ import 'package:island/database/message.dart'; import 'package:island/models/chat.dart'; import 'package:island/pods/call.dart'; import 'package:island/screens/chat/room.dart'; +import 'package:island/widgets/account/account_pfc.dart'; import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/content/cloud_file_collection.dart'; import 'package:island/widgets/content/cloud_files.dart'; @@ -129,9 +130,12 @@ class MessageItem extends HookConsumerWidget { spacing: 8, mainAxisSize: MainAxisSize.min, children: [ - ProfilePictureWidget( - fileId: sender.account.profile.picture?.id, - radius: 16, + AccountPfcGestureDetector( + uname: sender.account.name, + child: ProfilePictureWidget( + fileId: sender.account.profile.picture?.id, + radius: 16, + ), ), Column( crossAxisAlignment: CrossAxisAlignment.start,