Allow profile picture (avatar & banner) upload gif

This commit is contained in:
2025-03-03 20:53:42 +08:00
parent 73777fe74e
commit 2b61c372f5
3 changed files with 143 additions and 198 deletions

View File

@ -58,18 +58,12 @@ class _NotificationScreenState extends State<NotificationScreen> {
try {
final sn = context.read<SnNetworkProvider>();
final nty = context.read<NotificationProvider>();
final resp =
await sn.client.get('/cgi/id/notifications', queryParameters: {
'take': 10,
'offset': _notifications.length,
});
_totalCount = resp.data['count'];
_notifications.addAll(
resp.data['data']
?.map((e) => SnNotification.fromJson(e))
.cast<SnNotification>() ??
[],
final resp = await sn.client.get(
'/cgi/id/notifications',
queryParameters: {'take': 10, 'offset': _notifications.length},
);
_totalCount = resp.data['count'];
_notifications.addAll(resp.data['data']?.map((e) => SnNotification.fromJson(e)).cast<SnNotification>() ?? []);
nty.updateTray();
} catch (err) {
if (!mounted) return;
@ -104,9 +98,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
nty.clear();
if (!mounted) return;
context.showSnackbar(
'notificationMarkAllReadPrompt'.plural(resp.data['count']),
);
context.showSnackbar('notificationMarkAllReadPrompt'.plural(resp.data['count']));
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
@ -130,9 +122,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
_fetchNotifications();
if (!mounted) return;
context.showSnackbar(
'notificationMarkOneReadPrompt'.tr(args: ['#${notification.id}']),
);
context.showSnackbar('notificationMarkOneReadPrompt'.tr(args: ['#${notification.id}']));
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
@ -153,13 +143,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
if (!ua.isAuthorized) {
return AppScaffold(
appBar: AppBar(
leading: AutoAppBarLeading(),
title: Text('screenNotification').tr(),
),
body: Center(
child: UnauthorizedHint(),
),
appBar: AppBar(leading: AutoAppBarLeading(), title: Text('screenNotification').tr()),
body: Center(child: UnauthorizedHint()),
);
}
@ -168,10 +153,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
leading: AutoAppBarLeading(),
title: Text('screenNotification').tr(),
actions: [
IconButton(
icon: const Icon(Symbols.checklist),
onPressed: _isSubmitting ? null : _markAllAsRead,
),
IconButton(icon: const Icon(Symbols.checklist), onPressed: _isSubmitting ? null : _markAllAsRead),
const Gap(8),
],
),
@ -185,17 +167,13 @@ class _NotificationScreenState extends State<NotificationScreen> {
return _fetchNotifications();
},
child: InfiniteList(
padding: EdgeInsets.only(
top: 16,
bottom: math.max(MediaQuery.of(context).padding.bottom, 16),
),
padding: EdgeInsets.only(top: 16, bottom: math.max(MediaQuery.of(context).padding.bottom, 16)),
itemCount: _notifications.length,
onFetchData: () {
_fetchNotifications();
},
isLoading: _isBusy,
hasReachedMax: _totalCount != null &&
_notifications.length >= _totalCount!,
hasReachedMax: _totalCount != null && _notifications.length >= _totalCount!,
itemBuilder: (context, idx) {
final nty = _notifications[idx];
return Row(
@ -208,45 +186,26 @@ class _NotificationScreenState extends State<NotificationScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (nty.readAt == null)
StyledWidget(Badge(
label: Text('notificationUnread').tr(),
)).padding(bottom: 4),
Text(
nty.title,
style: Theme.of(context).textTheme.titleMedium,
),
StyledWidget(Badge(label: Text('notificationUnread').tr())).padding(bottom: 4),
Text(nty.title, style: Theme.of(context).textTheme.titleMedium),
if (nty.subtitle != null)
Text(
nty.subtitle!,
style: Theme.of(context).textTheme.titleSmall,
),
Text(nty.subtitle!, style: Theme.of(context).textTheme.titleSmall),
if (nty.subtitle != null) const Gap(4),
SelectionArea(
child: MarkdownTextContent(
content: nty.body,
isAutoWarp: true,
),
),
SelectionArea(child: MarkdownTextContent(content: nty.body, isAutoWarp: true)),
if ([
'interactive.reply',
'interactive.feedback',
'interactive.subscription'
'interactive.subscription',
].contains(nty.topic) &&
nty.metadata['related_post'] != null)
GestureDetector(
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(
Radius.circular(8)),
border: Border.all(
color: Theme.of(context).dividerColor,
width: 1,
),
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(color: Theme.of(context).dividerColor, width: 1),
),
child: PostItem(
data: SnPost.fromJson(
nty.metadata['related_post']!,
),
data: SnPost.fromJson(nty.metadata['related_post']!),
showComments: false,
showReactions: false,
showMenu: false,
@ -255,29 +214,18 @@ class _NotificationScreenState extends State<NotificationScreen> {
onTap: () {
GoRouter.of(context).pushNamed(
'postDetail',
pathParameters: {
'slug': nty
.metadata['related_post']!['id']
.toString(),
},
pathParameters: {'slug': nty.metadata['related_post']!['id'].toString()},
);
},
).padding(top: 8),
const Gap(8),
Row(
children: [
Text(
DateFormat('yy/MM/dd').format(nty.createdAt),
).fontSize(12),
Text(DateFormat('yy/MM/dd').format(nty.createdAt)).fontSize(12),
const Gap(4),
Text(
'·',
style: TextStyle(fontSize: 12),
),
Text('·', style: TextStyle(fontSize: 12)),
const Gap(4),
Text(
RelativeTime(context).format(nty.createdAt),
).fontSize(12),
Text(RelativeTime(context).format(nty.createdAt)).fontSize(12),
],
).opacity(0.75),
],
@ -287,10 +235,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
IconButton(
icon: const Icon(Symbols.check),
padding: EdgeInsets.all(0),
visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
onPressed:
_isSubmitting ? null : () => _markOneAsRead(nty),
visualDensity: const VisualDensity(horizontal: -4, vertical: -4),
onPressed: _isSubmitting ? null : () => _markOneAsRead(nty),
),
],
).padding(horizontal: 16);