Compare commits

..

2 Commits

Author SHA1 Message Date
dc1ce94145 Delete post 2024-11-28 22:04:38 +08:00
2261528580 🐛 Bug fixes on daily check in 2024-11-28 13:15:15 +08:00
8 changed files with 76 additions and 16 deletions

View File

@ -211,6 +211,9 @@
"other": "{} results" "other": "{} results"
}, },
"postSearchTook": "Took {}", "postSearchTook": "Took {}",
"postDelete": "Delete post {}",
"postDeleteDescription": "Are you sure you want to delete this post? This operation is irreversible.",
"postDeleted": "Post {} has been deleted.",
"call" : "Call", "call" : "Call",
"callOngoingNotice": "A call is ongoing", "callOngoingNotice": "A call is ongoing",
"callJoin": "Join", "callJoin": "Join",
@ -244,6 +247,8 @@
"dailyCheckAction": "Check in right now!", "dailyCheckAction": "Check in right now!",
"dailyCheckDetail": "Can't understand the symbol? Master, help me understand it!", "dailyCheckDetail": "Can't understand the symbol? Master, help me understand it!",
"dailyCheckDetailTitle": "{}'s fortune details", "dailyCheckDetailTitle": "{}'s fortune details",
"dailyCheckPositiveHint": "Good for {}",
"dailyCheckNegativeHint": "Bad for {}",
"dailyCheckPositiveHint1": "Making friends", "dailyCheckPositiveHint1": "Making friends",
"dailyCheckPositiveHint1Description": "Friendship lasts forever", "dailyCheckPositiveHint1Description": "Friendship lasts forever",
"dailyCheckPositiveHint2": "Drinking", "dailyCheckPositiveHint2": "Drinking",

View File

@ -168,7 +168,7 @@
"fieldChatBelongToRealm": "所属领域", "fieldChatBelongToRealm": "所属领域",
"fieldChatBelongToRealmUnset": "未设置频道所属领域", "fieldChatBelongToRealmUnset": "未设置频道所属领域",
"channelEditingNotice": "您正在编辑频道 {}", "channelEditingNotice": "您正在编辑频道 {}",
"channelDeleted": "聊天频道 {} 已被删除" , "channelDeleted": "聊天频道 {} 已被删除",
"channelDelete": "删除聊天频道 {}", "channelDelete": "删除聊天频道 {}",
"channelDeleteDescription": "你确定要删除这个聊天频道吗?该操作不可撤销,其频道内的所有消息将被永久删除。", "channelDeleteDescription": "你确定要删除这个聊天频道吗?该操作不可撤销,其频道内的所有消息将被永久删除。",
"fieldRealmAlias": "领域别名", "fieldRealmAlias": "领域别名",
@ -176,7 +176,7 @@
"fieldRealmName": "名称", "fieldRealmName": "名称",
"fieldRealmDescription": "描述", "fieldRealmDescription": "描述",
"realmEditingNotice": "您正在编辑领域 {}", "realmEditingNotice": "您正在编辑领域 {}",
"realmDeleted": "领域 {} 已被删除" , "realmDeleted": "领域 {} 已被删除",
"realmDelete": "删除领域 {}", "realmDelete": "删除领域 {}",
"realmDeleteDescription": "你确定要删除这个领域吗?该操作不可撤销,其隶属于该领域的所有资源(帖子、聊天频道、发布者、制品等)都将被永久删除。三思而后行!", "realmDeleteDescription": "你确定要删除这个领域吗?该操作不可撤销,其隶属于该领域的所有资源(帖子、聊天频道、发布者、制品等)都将被永久删除。三思而后行!",
"fieldChatMessage": "在 {} 中发消息", "fieldChatMessage": "在 {} 中发消息",
@ -194,7 +194,7 @@
}, },
"addAttachmentFromAlbum": "从相册中添加附件", "addAttachmentFromAlbum": "从相册中添加附件",
"addAttachmentFromClipboard": "粘贴附件", "addAttachmentFromClipboard": "粘贴附件",
"attachmentPastedImage" : "粘贴的图片", "attachmentPastedImage": "粘贴的图片",
"notificationUnread": "未读", "notificationUnread": "未读",
"notificationRead": "已读", "notificationRead": "已读",
"notificationMarkAllRead": "已读所有通知", "notificationMarkAllRead": "已读所有通知",
@ -211,6 +211,9 @@
"other": "搜索到 {} 个结果" "other": "搜索到 {} 个结果"
}, },
"postSearchTook": "耗时 {}", "postSearchTook": "耗时 {}",
"postDelete": "删除帖子 {}",
"postDeleteDescription": "你确定要删除这个帖子吗?该操作不可撤销。",
"postDeleted": "帖子 {} 已被删除。",
"call": "通话", "call": "通话",
"callOngoingNotice": "一则通话进行中", "callOngoingNotice": "一则通话进行中",
"callJoin": "加入", "callJoin": "加入",
@ -244,8 +247,8 @@
"dailyCheckAction": "现在签到", "dailyCheckAction": "现在签到",
"dailyCheckDetail": "看不懂符?大师帮我解惑!", "dailyCheckDetail": "看不懂符?大师帮我解惑!",
"dailyCheckDetailTitle": "{} 的运势详情", "dailyCheckDetailTitle": "{} 的运势详情",
"dailyCheckPositiveHint": "宜 {}", "dailyCheckPositiveHint": "宜 {}",
"dailyCheckNegativeHint": "忌 {}", "dailyCheckNegativeHint": "忌 {}",
"dailyCheckPositiveHint1": "交友", "dailyCheckPositiveHint1": "交友",
"dailyCheckPositiveHint1Description": "友谊地久天长", "dailyCheckPositiveHint1Description": "友谊地久天长",
"dailyCheckPositiveHint2": "饮酒", "dailyCheckPositiveHint2": "饮酒",

View File

@ -164,6 +164,10 @@ class _ExploreScreenState extends State<ExploreScreen> {
onChanged: (data) { onChanged: (data) {
setState(() => _posts[idx] = data); setState(() => _posts[idx] = data);
}, },
onDeleted: () {
_posts.clear();
_fetchPosts();
},
), ),
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(

View File

@ -1,3 +1,5 @@
import 'dart:math' as math;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
@ -140,9 +142,6 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
final sn = context.read<SnNetworkProvider>(); final sn = context.read<SnNetworkProvider>();
final resp = await sn.client.get('/cgi/id/check-in/today'); final resp = await sn.client.get('/cgi/id/check-in/today');
_todayRecord = SnCheckInRecord.fromJson(resp.data); _todayRecord = SnCheckInRecord.fromJson(resp.data);
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
} finally { } finally {
setState(() => _isBusy = false); setState(() => _isBusy = false);
} }
@ -167,20 +166,19 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
positive ? 'dailyCheckPositiveHint' : 'dailyCheckNegativeHint'; positive ? 'dailyCheckPositiveHint' : 'dailyCheckNegativeHint';
final mod = final mod =
positive ? kSuggestionPositiveHintCount : kSuggestionNegativeHintCount; positive ? kSuggestionPositiveHintCount : kSuggestionNegativeHintCount;
final pos = math.max(1, _todayRecord!.resultModifiers[index] % mod);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
prefix.tr(args: [ prefix.tr(args: ['$prefix$pos'.tr()]),
'$prefix${_todayRecord!.resultModifiers[index] % mod}'.tr()
]),
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.titleMedium! .titleMedium!
.copyWith(fontWeight: FontWeight.bold), .copyWith(fontWeight: FontWeight.bold),
).tr(), ).tr(),
Text( Text(
'$prefix${_todayRecord!.resultModifiers[index] % kSuggestionPositiveHintCount}Description', '$prefix${pos}Description',
style: Theme.of(context).textTheme.bodyMedium, style: Theme.of(context).textTheme.bodyMedium,
).tr(), ).tr(),
], ],

View File

@ -113,6 +113,9 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
onChanged: (data) { onChanged: (data) {
setState(() => _data = data); setState(() => _data = data);
}, },
onDeleted: () {
Navigator.pop(context);
},
), ),
), ),
const SliverToBoxAdapter(child: Divider(height: 1)), const SliverToBoxAdapter(child: Divider(height: 1)),

View File

@ -101,6 +101,10 @@ class _PostSearchScreenState extends State<PostSearchScreen> {
onChanged: (data) { onChanged: (data) {
setState(() => _posts[idx] = data); setState(() => _posts[idx] = data);
}, },
onDeleted: () {
_posts.clear();
_fetchPosts();
},
), ),
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(

View File

@ -74,6 +74,10 @@ class PostCommentSliverListState extends State<PostCommentSliverList> {
onChanged: (data) { onChanged: (data) {
setState(() => _posts[idx] = data); setState(() => _posts[idx] = data);
}, },
onDeleted: () {
_posts.clear();
_fetchPosts();
},
), ),
onTap: () { onTap: () {
GoRouter.of(context).pushNamed( GoRouter.of(context).pushNamed(

View File

@ -5,10 +5,12 @@ import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:relative_time/relative_time.dart'; import 'package:relative_time/relative_time.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/userinfo.dart'; import 'package:surface/providers/userinfo.dart';
import 'package:surface/types/post.dart'; import 'package:surface/types/post.dart';
import 'package:surface/widgets/account/account_image.dart'; import 'package:surface/widgets/account/account_image.dart';
import 'package:surface/widgets/attachment/attachment_list.dart'; import 'package:surface/widgets/attachment/attachment_list.dart';
import 'package:surface/widgets/dialog.dart';
import 'package:surface/widgets/markdown_content.dart'; import 'package:surface/widgets/markdown_content.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:surface/widgets/post/post_comment_list.dart'; import 'package:surface/widgets/post/post_comment_list.dart';
@ -21,6 +23,7 @@ class PostItem extends StatelessWidget {
final bool showMenu; final bool showMenu;
final double? maxWidth; final double? maxWidth;
final Function(SnPost data)? onChanged; final Function(SnPost data)? onChanged;
final Function()? onDeleted;
const PostItem({ const PostItem({
super.key, super.key,
required this.data, required this.data,
@ -29,6 +32,7 @@ class PostItem extends StatelessWidget {
this.showMenu = true, this.showMenu = true,
this.maxWidth, this.maxWidth,
this.onChanged, this.onChanged,
this.onDeleted,
}); });
void _onChanged(SnPost data) { void _onChanged(SnPost data) {
@ -45,8 +49,13 @@ class PostItem extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_PostContentHeader(data: data, showMenu: showMenu) _PostContentHeader(
.padding(horizontal: 12, vertical: 8), data: data,
showMenu: showMenu,
onDeleted: () {
if (onDeleted != null) onDeleted!();
},
).padding(horizontal: 12, vertical: 8),
if (data.body['title'] != null || if (data.body['title'] != null ||
data.body['description'] != null) data.body['description'] != null)
_PostHeadline(data: data).padding(horizontal: 16, bottom: 8), _PostHeadline(data: data).padding(horizontal: 16, bottom: 8),
@ -217,12 +226,37 @@ class _PostContentHeader extends StatelessWidget {
final SnPost data; final SnPost data;
final bool isCompact; final bool isCompact;
final bool showMenu; final bool showMenu;
final Function onDeleted;
const _PostContentHeader({ const _PostContentHeader({
required this.data, required this.data,
this.isCompact = false, this.isCompact = false,
this.showMenu = true, this.showMenu = true,
required this.onDeleted,
}); });
Future<void> _deletePost(BuildContext context) async {
final confirm = await context.showConfirmDialog(
'postDelete'.tr(args: ['#${data.id}']),
'postDeleteDescription'.tr(),
);
if (!confirm) return;
if (!context.mounted) return;
try {
final sn = context.read<SnNetworkProvider>();
await sn.client.delete('/cgi/co/posts/${data.id}', queryParameters: {
'publisherId': data.publisherId,
});
if (!context.mounted) return;
context.showSnackbar('postDeleted'.tr(args: ['#${data.id}']));
} catch (err) {
if (!context.mounted) return;
context.showErrorDialog(err);
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ua = context.read<UserProvider>(); final ua = context.read<UserProvider>();
@ -302,6 +336,7 @@ class _PostContentHeader extends StatelessWidget {
Text('delete').tr(), Text('delete').tr(),
], ],
), ),
onTap: () => _deletePost(context),
), ),
if (isAuthor) const PopupMenuDivider(), if (isAuthor) const PopupMenuDivider(),
PopupMenuItem( PopupMenuItem(
@ -381,8 +416,12 @@ class _PostQuoteContent extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Column( child: Column(
children: [ children: [
_PostContentHeader(data: child, isCompact: true, showMenu: false) _PostContentHeader(
.padding(bottom: 4), data: child,
isCompact: true,
showMenu: false,
onDeleted: () {},
).padding(bottom: 4),
_PostContentBody(data: child.body), _PostContentBody(data: child.body),
], ],
), ),