✨ Punishments
This commit is contained in:
parent
ecc79368a1
commit
c1e89a2ee6
@ -917,5 +917,21 @@
|
|||||||
"accountProgramAlreadyJoined": "Joined",
|
"accountProgramAlreadyJoined": "Joined",
|
||||||
"accountProgramLeft": "Left Program.",
|
"accountProgramLeft": "Left Program.",
|
||||||
"leave": "Leave",
|
"leave": "Leave",
|
||||||
"attachmentFailedToLoadMedia": "Unable to load media file, please try again later. If this error occurs repeatedly, the source file may not exist or the network connection may be abnormal."
|
"attachmentFailedToLoadMedia": "Unable to load media file, please try again later. If this error occurs repeatedly, the source file may not exist or the network connection may be abnormal.",
|
||||||
|
"accountPunishments": "Punishments",
|
||||||
|
"accountPunishmentsDescription": "View your account's reputation status.",
|
||||||
|
"punishmentType0": "Strike",
|
||||||
|
"punishmentType1": "Limited",
|
||||||
|
"punishmentType2": "Banned",
|
||||||
|
"punishmentOverall": "Overall Status",
|
||||||
|
"punishmentStatusNormal": "All abilities normal",
|
||||||
|
"punishmentStatusWarned": "All abilities normal, but at least one strike is in effect",
|
||||||
|
"punishmentStatusLimited": "Some abilities limited, at least one limited punishment is in effect",
|
||||||
|
"punishmentStatusLimitedFully": "All abilities limited, at least one completely limited punishment is in effect",
|
||||||
|
"punishmentStatusBanned": "All services are terminated, banned",
|
||||||
|
"punishmentCreatedAt": "Applied since {}",
|
||||||
|
"punishmentExpiredAt": "Expired at {}",
|
||||||
|
"punishmentExpiredNever": "Never expired",
|
||||||
|
"punishmentModerator": "Moderator who made this punishment",
|
||||||
|
"punishmentMadeBySystem": "Made by auto-mod system"
|
||||||
}
|
}
|
||||||
|
@ -914,5 +914,21 @@
|
|||||||
"accountProgramLeft": "已离开计划。",
|
"accountProgramLeft": "已离开计划。",
|
||||||
"accountProgramAlreadyJoined": "已加入",
|
"accountProgramAlreadyJoined": "已加入",
|
||||||
"leave": "离开",
|
"leave": "离开",
|
||||||
"attachmentFailedToLoadMedia": "无法加载媒体文件,请稍后重试。若此错误重复出现,可能源文件不存在或者网络连接异常。"
|
"attachmentFailedToLoadMedia": "无法加载媒体文件,请稍后重试。若此错误重复出现,可能源文件不存在或者网络连接异常。",
|
||||||
|
"accountPunishments": "处分",
|
||||||
|
"accountPunishmentsDescription": "查看你帐号的信誉状态。",
|
||||||
|
"punishmentType0": "警告",
|
||||||
|
"punishmentType1": "停权",
|
||||||
|
"punishmentType2": "封禁",
|
||||||
|
"punishmentOverall": "总体状态",
|
||||||
|
"punishmentStatusNormal": "所有功能正常",
|
||||||
|
"punishmentStatusWarned": "所有功能正常,但有警告生效",
|
||||||
|
"punishmentStatusLimited": "部份功能暂时受限,有至少一个停权生效",
|
||||||
|
"punishmentStatusLimitedFully": "所有功能暂时受限,有至少一个完全停权生效",
|
||||||
|
"punishmentStatusBanned": "所有服务终止,已被封禁",
|
||||||
|
"punishmentCreatedAt": "宣布于 {}",
|
||||||
|
"punishmentExpiredAt": "到期于 {}",
|
||||||
|
"punishmentExpiredNever": "永久生效",
|
||||||
|
"punishmentModerator": "责任管理员",
|
||||||
|
"punishmentMadeBySystem": "由系统自动裁决"
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,20 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:surface/types/realm.dart';
|
import 'package:surface/types/realm.dart';
|
||||||
|
|
||||||
|
class AppNavListItem {
|
||||||
|
final String title;
|
||||||
|
final String subtitle;
|
||||||
|
final String screen;
|
||||||
|
final IconData icon;
|
||||||
|
|
||||||
|
const AppNavListItem({
|
||||||
|
required this.title,
|
||||||
|
required this.subtitle,
|
||||||
|
required this.screen,
|
||||||
|
required this.icon,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class AppNavDestination {
|
class AppNavDestination {
|
||||||
final String label;
|
final String label;
|
||||||
final String screen;
|
final String screen;
|
||||||
|
@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:surface/screens/abuse_report.dart';
|
import 'package:surface/screens/abuse_report.dart';
|
||||||
import 'package:surface/screens/account.dart';
|
import 'package:surface/screens/account.dart';
|
||||||
import 'package:surface/screens/account/account_settings.dart';
|
import 'package:surface/screens/account/punishments.dart';
|
||||||
|
import 'package:surface/screens/account/settings.dart';
|
||||||
import 'package:surface/screens/account/action_events.dart';
|
import 'package:surface/screens/account/action_events.dart';
|
||||||
import 'package:surface/screens/account/badges.dart';
|
import 'package:surface/screens/account/badges.dart';
|
||||||
import 'package:surface/screens/account/contact_methods.dart';
|
import 'package:surface/screens/account/contact_methods.dart';
|
||||||
@ -131,6 +132,11 @@ final _appRoutes = [
|
|||||||
name: 'account',
|
name: 'account',
|
||||||
builder: (context, state) => const AccountScreen(),
|
builder: (context, state) => const AccountScreen(),
|
||||||
routes: [
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: '/punishments',
|
||||||
|
name: 'accountPunishments',
|
||||||
|
builder: (context, state) => const PunishmentsScreen(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/programs',
|
path: '/programs',
|
||||||
name: 'accountProgram',
|
name: 'accountProgram',
|
||||||
|
@ -8,6 +8,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/database.dart';
|
import 'package:surface/providers/database.dart';
|
||||||
|
import 'package:surface/providers/navigation.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/userinfo.dart';
|
import 'package:surface/providers/userinfo.dart';
|
||||||
import 'package:surface/providers/websocket.dart';
|
import 'package:surface/providers/websocket.dart';
|
||||||
@ -22,6 +23,87 @@ import 'package:surface/widgets/universal_image.dart';
|
|||||||
class AccountScreen extends StatelessWidget {
|
class AccountScreen extends StatelessWidget {
|
||||||
const AccountScreen({super.key});
|
const AccountScreen({super.key});
|
||||||
|
|
||||||
|
static const List<AppNavListItem> kNavList = [
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountPublishers",
|
||||||
|
subtitle: "accountPublishersSubtitle",
|
||||||
|
screen: "accountPublishers",
|
||||||
|
icon: Symbols.face,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountProgram",
|
||||||
|
subtitle: "accountProgramDescription",
|
||||||
|
screen: "accountProgram",
|
||||||
|
icon: Symbols.communities,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "friends",
|
||||||
|
subtitle: "friendsDescription",
|
||||||
|
screen: "friend",
|
||||||
|
icon: Symbols.person,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "album",
|
||||||
|
subtitle: "albumDescription",
|
||||||
|
screen: "album",
|
||||||
|
icon: Symbols.photo_library,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "stickers",
|
||||||
|
subtitle: "stickersDescription",
|
||||||
|
screen: "stickers",
|
||||||
|
icon: Symbols.emoji_emotions,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountWallet",
|
||||||
|
subtitle: "accountWalletSubtitle",
|
||||||
|
screen: "accountWallet",
|
||||||
|
icon: Symbols.wallet,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountBadges",
|
||||||
|
subtitle: "accountBadgesDescription",
|
||||||
|
screen: "accountBadges",
|
||||||
|
icon: Symbols.award_star,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountKeyPairs",
|
||||||
|
subtitle: "accountKeyPairsDescription",
|
||||||
|
screen: "accountKeyPairs",
|
||||||
|
icon: Symbols.key,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountPunishments",
|
||||||
|
subtitle: "accountPunishmentsDescription",
|
||||||
|
screen: "accountPunishments",
|
||||||
|
icon: Symbols.credit_score,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountActionEvent",
|
||||||
|
subtitle: "accountActionEventDescription",
|
||||||
|
screen: "accountActionEvents",
|
||||||
|
icon: Symbols.history,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountAuthTickets",
|
||||||
|
subtitle: "accountAuthTicketsDescription",
|
||||||
|
screen: "accountAuthTickets",
|
||||||
|
icon: Symbols.confirmation_number,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "accountSettings",
|
||||||
|
subtitle: "accountSettingsSubtitle",
|
||||||
|
screen: "accountSettings",
|
||||||
|
icon: Symbols.manage_accounts,
|
||||||
|
),
|
||||||
|
AppNavListItem(
|
||||||
|
title: "abuseReport",
|
||||||
|
subtitle: "abuseReportActionDescription",
|
||||||
|
screen: "abuseReport",
|
||||||
|
icon: Symbols.flag,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ua = context.watch<UserProvider>();
|
final ua = context.watch<UserProvider>();
|
||||||
@ -146,145 +228,42 @@ class _AuthorizedAccountScreen extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}).padding(all: 20),
|
}).padding(all: 20),
|
||||||
).padding(horizontal: 8, top: 16, bottom: 4),
|
).padding(horizontal: 8, top: 16, bottom: 4),
|
||||||
ListTile(
|
for (final item in AccountScreen.kNavList)
|
||||||
title: Text('accountPublishers').tr(),
|
Tooltip(
|
||||||
subtitle: Text('accountPublishersSubtitle').tr(),
|
message: item.subtitle.tr(),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
child: ListTile(
|
||||||
leading: const Icon(Symbols.face),
|
minTileHeight: 48,
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
title: Text(item.title).tr(),
|
||||||
onTap: () {
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
GoRouter.of(context).pushNamed('accountPublishers');
|
leading: Icon(item.icon),
|
||||||
},
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
),
|
onTap: () {
|
||||||
ListTile(
|
GoRouter.of(context).pushNamed(item.screen);
|
||||||
title: Text('accountProgram').tr(),
|
},
|
||||||
subtitle: Text('accountProgramDescription').tr(),
|
),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
),
|
||||||
leading: const Icon(Symbols.communities),
|
Tooltip(
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
message: 'accountLogoutSubtitle'.tr(),
|
||||||
onTap: () {
|
child: ListTile(
|
||||||
GoRouter.of(context).pushNamed('accountProgram');
|
title: Text('accountLogout').tr(),
|
||||||
},
|
minTileHeight: 48,
|
||||||
),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
ListTile(
|
leading: const Icon(Symbols.logout),
|
||||||
title: Text('friends').tr(),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
subtitle: Text('friendsDescription').tr(),
|
onTap: () async {
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
final confirm = await context.showConfirmDialog(
|
||||||
leading: const Icon(Symbols.person),
|
'accountLogoutConfirmTitle'.tr(),
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
'accountLogoutConfirm'.tr(),
|
||||||
onTap: () {
|
);
|
||||||
GoRouter.of(context).pushNamed('friend');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('album').tr(),
|
|
||||||
subtitle: Text('albumDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.photo_library),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('album');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('stickers').tr(),
|
|
||||||
subtitle: Text('stickersDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.emoji_emotions),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('stickers');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountWallet').tr(),
|
|
||||||
subtitle: Text('accountWalletSubtitle').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.wallet),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountWallet');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountBadges').tr(),
|
|
||||||
subtitle: Text('accountBadgesDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.award_star),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountBadges');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountKeyPairs').tr(),
|
|
||||||
subtitle: Text('accountKeyPairsDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.key),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountKeyPairs');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountActionEvent').tr(),
|
|
||||||
subtitle: Text('accountActionEventDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.history),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountActionEvents');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountAuthTickets').tr(),
|
|
||||||
subtitle: Text('accountAuthTicketsDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.confirmation_number),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountAuthTickets');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountSettings').tr(),
|
|
||||||
subtitle: Text('accountSettingsSubtitle').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.manage_accounts),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('accountSettings');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('abuseReport').tr(),
|
|
||||||
subtitle: Text('abuseReportActionDescription').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.flag),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () {
|
|
||||||
GoRouter.of(context).pushNamed('abuseReport');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
title: Text('accountLogout').tr(),
|
|
||||||
subtitle: Text('accountLogoutSubtitle').tr(),
|
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
leading: const Icon(Symbols.logout),
|
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
|
||||||
onTap: () async {
|
|
||||||
final confirm = await context.showConfirmDialog(
|
|
||||||
'accountLogoutConfirmTitle'.tr(),
|
|
||||||
'accountLogoutConfirm'.tr(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!confirm) return;
|
if (!confirm) return;
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
ua.logoutUser();
|
ua.logoutUser();
|
||||||
final ws = context.read<WebSocketProvider>();
|
final ws = context.read<WebSocketProvider>();
|
||||||
ws.disconnect();
|
ws.disconnect();
|
||||||
context.read<DatabaseProvider>().removeDatabase();
|
context.read<DatabaseProvider>().removeDatabase();
|
||||||
},
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
180
lib/screens/account/punishments.dart
Normal file
180
lib/screens/account/punishments.dart
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/types/account.dart';
|
||||||
|
import 'package:surface/widgets/account/account_image.dart';
|
||||||
|
import 'package:surface/widgets/dialog.dart';
|
||||||
|
import 'package:surface/widgets/loading_indicator.dart';
|
||||||
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
|
||||||
|
const kPunishmentIcons = [
|
||||||
|
Symbols.warning,
|
||||||
|
Symbols.emergency_home,
|
||||||
|
Symbols.dangerous,
|
||||||
|
];
|
||||||
|
|
||||||
|
class PunishmentsScreen extends StatefulWidget {
|
||||||
|
const PunishmentsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PunishmentsScreen> createState() => _PunishmentsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PunishmentsScreenState extends State<PunishmentsScreen> {
|
||||||
|
bool _isBusy = false;
|
||||||
|
List<SnPunishment>? _punishments;
|
||||||
|
|
||||||
|
Future<void> _fetchPunishments() async {
|
||||||
|
setState(() => _isBusy = true);
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final resp = await sn.client.get('/cgi/id/punishments');
|
||||||
|
if (!mounted) return;
|
||||||
|
_punishments = List.from(
|
||||||
|
resp.data.map((ele) => SnPunishment.fromJson(ele)),
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
} finally {
|
||||||
|
setState(() => _isBusy = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_fetchPunishments();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('accountPunishments').tr(),
|
||||||
|
leading: PageBackButton(),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
LoadingIndicator(isActive: _isBusy),
|
||||||
|
Card(
|
||||||
|
margin: EdgeInsets.only(bottom: 8, left: 8, right: 8),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Symbols.visibility, size: 20),
|
||||||
|
const Gap(6),
|
||||||
|
Expanded(
|
||||||
|
child: Text('punishmentOverall').tr().fontSize(16).bold(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Builder(
|
||||||
|
builder: (context) {
|
||||||
|
if (_punishments == null) return Text('loading').tr();
|
||||||
|
if (_punishments!.any((ele) => ele.type == 2)) {
|
||||||
|
return Text('punishmentStatusBanned').tr();
|
||||||
|
}
|
||||||
|
if (_punishments!.any(
|
||||||
|
(ele) => ele.type == 1 && ele.permNodes.isEmpty,
|
||||||
|
)) {
|
||||||
|
return Text('punishmentStatusLimitedFully').tr();
|
||||||
|
} else if (_punishments!.any((ele) => ele.type == 1)) {
|
||||||
|
return Text('punishmentStatusLimited').tr();
|
||||||
|
}
|
||||||
|
if (_punishments!.any((ele) => ele.type == 0)) {
|
||||||
|
return Text('punishmentStatusWarned').tr();
|
||||||
|
}
|
||||||
|
return Text('punishmentStatusNormal').tr();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 24, vertical: 16),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: _fetchPunishments,
|
||||||
|
child: ListView.separated(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: _punishments?.length ?? 0,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final ele = _punishments![index];
|
||||||
|
return Card(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(kPunishmentIcons[ele.type], size: 20),
|
||||||
|
const Gap(6),
|
||||||
|
Expanded(
|
||||||
|
child: Text('punishmentType${ele.type}')
|
||||||
|
.tr()
|
||||||
|
.fontSize(16)
|
||||||
|
.bold(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(ele.reason),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
'punishmentCreatedAt'
|
||||||
|
.tr(args: [DateFormat().format(ele.createdAt)]),
|
||||||
|
).opacity(0.8),
|
||||||
|
Text(
|
||||||
|
ele.expiredAt == null
|
||||||
|
? 'punishmentExpiredNever'.tr()
|
||||||
|
: 'punishmentExpiredAt'.tr(
|
||||||
|
args: [DateFormat().format(ele.expiredAt!)]),
|
||||||
|
).opacity(0.8),
|
||||||
|
const Gap(8),
|
||||||
|
if (ele.moderator != null)
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('punishmentModerator').tr().opacity(0.75),
|
||||||
|
InkWell(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
AccountImage(
|
||||||
|
content: ele.moderator!.avatar,
|
||||||
|
radius: 8,
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(ele.moderator?.nick ?? 'unknown'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
GoRouter.of(context).pushNamed(
|
||||||
|
'accountProfilePage',
|
||||||
|
pathParameters: {
|
||||||
|
'name': ele.moderator!.name,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text('punishmentMadeBySystem').tr().opacity(0.75),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 24, vertical: 16),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (_, __) => const Gap(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,6 @@ import 'package:surface/providers/userinfo.dart';
|
|||||||
import 'package:surface/types/account.dart';
|
import 'package:surface/types/account.dart';
|
||||||
import 'package:surface/widgets/account/account_image.dart';
|
import 'package:surface/widgets/account/account_image.dart';
|
||||||
import 'package:surface/widgets/account/account_select.dart';
|
import 'package:surface/widgets/account/account_select.dart';
|
||||||
import 'package:surface/widgets/app_bar_leading.dart';
|
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/loading_indicator.dart';
|
import 'package:surface/widgets/loading_indicator.dart';
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
@ -46,7 +45,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final resp = await sn.client.get('/cgi/id/users/me/relations?status=1');
|
final resp = await sn.client.get('/cgi/id/users/me/relations?status=1');
|
||||||
_relations = List<SnRelationship>.from(resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
_relations = List<SnRelationship>.from(
|
||||||
|
resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
@ -64,7 +64,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final resp = await sn.client.get('/cgi/id/users/me/relations?status=0,3');
|
final resp = await sn.client.get('/cgi/id/users/me/relations?status=0,3');
|
||||||
_requests = List<SnRelationship>.from(resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
_requests = List<SnRelationship>.from(
|
||||||
|
resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
@ -82,7 +83,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final resp = await sn.client.get('/cgi/id/users/me/relations?status=2');
|
final resp = await sn.client.get('/cgi/id/users/me/relations?status=2');
|
||||||
_blocks = List<SnRelationship>.from(resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
_blocks = List<SnRelationship>.from(
|
||||||
|
resp.data?.map((e) => SnRelationship.fromJson(e)) ?? []);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
@ -98,7 +100,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final rel = context.read<SnRelationshipProvider>();
|
final rel = context.read<SnRelationshipProvider>();
|
||||||
await rel.updateRelationship(relation.relatedId, dstStatus, relation.permNodes);
|
await rel.updateRelationship(
|
||||||
|
relation.relatedId, dstStatus, relation.permNodes);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
_fetchRelations();
|
_fetchRelations();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -112,7 +115,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
Future<void> _deleteRelation(SnRelationship relation) async {
|
Future<void> _deleteRelation(SnRelationship relation) async {
|
||||||
final confirm = await context.showConfirmDialog(
|
final confirm = await context.showConfirmDialog(
|
||||||
'friendDelete'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
'friendDelete'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
||||||
'friendDeleteDescription'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
'friendDeleteDescription'
|
||||||
|
.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
||||||
);
|
);
|
||||||
if (!confirm) return;
|
if (!confirm) return;
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
@ -133,7 +137,10 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _showRequests() {
|
void _showRequests() {
|
||||||
showModalBottomSheet(context: context, builder: (context) => _FriendshipListWidget(relations: _requests)).then((
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => _FriendshipListWidget(relations: _requests))
|
||||||
|
.then((
|
||||||
value,
|
value,
|
||||||
) {
|
) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
@ -144,7 +151,9 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _showBlocks() {
|
void _showBlocks() {
|
||||||
showModalBottomSheet(context: context, builder: (context) => _FriendshipListWidget(relations: _blocks)).then((
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => _FriendshipListWidget(relations: _blocks)).then((
|
||||||
value,
|
value,
|
||||||
) {
|
) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
@ -159,7 +168,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
await sn.client.post('/cgi/id/users/me/relations', data: {'related': user.name});
|
await sn.client
|
||||||
|
.post('/cgi/id/users/me/relations', data: {'related': user.name});
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showSnackbar('friendRequestSent'.tr());
|
context.showSnackbar('friendRequestSent'.tr());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -184,13 +194,19 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
|
|
||||||
if (!ua.isAuthorized) {
|
if (!ua.isAuthorized) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(leading: PageBackButton(), title: Text('screenFriend').tr()),
|
appBar: AppBar(
|
||||||
|
leading: PageBackButton(),
|
||||||
|
title: Text('screenFriend').tr(),
|
||||||
|
),
|
||||||
body: Center(child: UnauthorizedHint()),
|
body: Center(child: UnauthorizedHint()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(leading: AutoAppBarLeading(), title: Text('screenFriend').tr()),
|
appBar: AppBar(
|
||||||
|
leading: PageBackButton(),
|
||||||
|
title: Text('screenFriend').tr(),
|
||||||
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
child: const Icon(Symbols.add),
|
child: const Icon(Symbols.add),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
@ -209,7 +225,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
if (_requests.isNotEmpty)
|
if (_requests.isNotEmpty)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('friendRequests').tr(),
|
title: Text('friendRequests').tr(),
|
||||||
subtitle: Text('friendRequestsDescription').plural(_requests.length),
|
subtitle:
|
||||||
|
Text('friendRequestsDescription').plural(_requests.length),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
leading: const Icon(Symbols.group_add),
|
leading: const Icon(Symbols.group_add),
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
@ -218,19 +235,22 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
if (_blocks.isNotEmpty)
|
if (_blocks.isNotEmpty)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('friendBlocklist').tr(),
|
title: Text('friendBlocklist').tr(),
|
||||||
subtitle: Text('friendBlocklistDescription').plural(_blocks.length),
|
subtitle:
|
||||||
|
Text('friendBlocklistDescription').plural(_blocks.length),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
leading: const Icon(Symbols.block),
|
leading: const Icon(Symbols.block),
|
||||||
trailing: const Icon(Symbols.chevron_right),
|
trailing: const Icon(Symbols.chevron_right),
|
||||||
onTap: _showBlocks,
|
onTap: _showBlocks,
|
||||||
),
|
),
|
||||||
if (_requests.isNotEmpty || _blocks.isNotEmpty) const Divider(height: 1),
|
if (_requests.isNotEmpty || _blocks.isNotEmpty)
|
||||||
|
const Divider(height: 1),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MediaQuery.removePadding(
|
child: MediaQuery.removePadding(
|
||||||
context: context,
|
context: context,
|
||||||
removeTop: true,
|
removeTop: true,
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () => Future.wait([_fetchRelations(), _fetchRequests()]),
|
onRefresh: () =>
|
||||||
|
Future.wait([_fetchRelations(), _fetchRequests()]),
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: _relations.length,
|
itemCount: _relations.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
@ -254,12 +274,16 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: _isUpdating ? null : () => _changeRelation(relation, 2),
|
onTap: _isUpdating
|
||||||
|
? null
|
||||||
|
: () => _changeRelation(relation, 2),
|
||||||
child: Text('friendBlock').tr(),
|
child: Text('friendBlock').tr(),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: _isUpdating ? null : () => _deleteRelation(relation),
|
onTap: _isUpdating
|
||||||
|
? null
|
||||||
|
: () => _deleteRelation(relation),
|
||||||
child: Text('friendDeleteAction').tr(),
|
child: Text('friendDeleteAction').tr(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -328,7 +352,8 @@ class _FriendshipListWidgetState extends State<_FriendshipListWidget> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final rel = context.read<SnRelationshipProvider>();
|
final rel = context.read<SnRelationshipProvider>();
|
||||||
await rel.updateRelationship(relation.relatedId, dstStatus, relation.permNodes);
|
await rel.updateRelationship(
|
||||||
|
relation.relatedId, dstStatus, relation.permNodes);
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -342,7 +367,8 @@ class _FriendshipListWidgetState extends State<_FriendshipListWidget> {
|
|||||||
Future<void> _deleteRelation(SnRelationship relation) async {
|
Future<void> _deleteRelation(SnRelationship relation) async {
|
||||||
final confirm = await context.showConfirmDialog(
|
final confirm = await context.showConfirmDialog(
|
||||||
'friendDelete'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
'friendDelete'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
||||||
'friendDeleteDescription'.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
'friendDeleteDescription'
|
||||||
|
.tr(args: [relation.related?.nick ?? 'unknown'.tr()]),
|
||||||
);
|
);
|
||||||
if (!confirm) return;
|
if (!confirm) return;
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
@ -382,7 +408,9 @@ class _FriendshipListWidgetState extends State<_FriendshipListWidget> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Text(kFriendStatus[relation.status] ?? 'unknown').tr().opacity(0.75),
|
Text(kFriendStatus[relation.status] ?? 'unknown')
|
||||||
|
.tr()
|
||||||
|
.opacity(0.75),
|
||||||
if (relation.status == 0)
|
if (relation.status == 0)
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
@ -403,7 +431,8 @@ class _FriendshipListWidgetState extends State<_FriendshipListWidget> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: _isBusy ? null : () => _changeRelation(relation, 1),
|
onTap:
|
||||||
|
_isBusy ? null : () => _changeRelation(relation, 1),
|
||||||
child: Text('friendUnblock').tr(),
|
child: Text('friendUnblock').tr(),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
|
@ -223,3 +223,24 @@ abstract class SnProgramMember with _$SnProgramMember {
|
|||||||
factory SnProgramMember.fromJson(Map<String, Object?> json) =>
|
factory SnProgramMember.fromJson(Map<String, Object?> json) =>
|
||||||
_$SnProgramMemberFromJson(json);
|
_$SnProgramMemberFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class SnPunishment with _$SnPunishment {
|
||||||
|
const factory SnPunishment({
|
||||||
|
required int id,
|
||||||
|
required DateTime createdAt,
|
||||||
|
required DateTime updatedAt,
|
||||||
|
required DateTime? deletedAt,
|
||||||
|
required String reason,
|
||||||
|
required int type,
|
||||||
|
@Default({}) Map<String, dynamic> permNodes,
|
||||||
|
required DateTime? expiredAt,
|
||||||
|
required SnAccount? account,
|
||||||
|
required int? accountId,
|
||||||
|
required SnAccount? moderator,
|
||||||
|
required int? moderatorId,
|
||||||
|
}) = _SnPunishment;
|
||||||
|
|
||||||
|
factory SnPunishment.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$SnPunishmentFromJson(json);
|
||||||
|
}
|
||||||
|
@ -4229,4 +4229,461 @@ class __$SnProgramMemberCopyWithImpl<$Res>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnPunishment {
|
||||||
|
int get id;
|
||||||
|
DateTime get createdAt;
|
||||||
|
DateTime get updatedAt;
|
||||||
|
DateTime? get deletedAt;
|
||||||
|
String get reason;
|
||||||
|
int get type;
|
||||||
|
Map<String, dynamic> get permNodes;
|
||||||
|
DateTime? get expiredAt;
|
||||||
|
SnAccount? get account;
|
||||||
|
int? get accountId;
|
||||||
|
SnAccount? get moderator;
|
||||||
|
int? get moderatorId;
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPunishmentCopyWith<SnPunishment> get copyWith =>
|
||||||
|
_$SnPunishmentCopyWithImpl<SnPunishment>(
|
||||||
|
this as SnPunishment, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnPunishment to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is SnPunishment &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.createdAt, createdAt) ||
|
||||||
|
other.createdAt == createdAt) &&
|
||||||
|
(identical(other.updatedAt, updatedAt) ||
|
||||||
|
other.updatedAt == updatedAt) &&
|
||||||
|
(identical(other.deletedAt, deletedAt) ||
|
||||||
|
other.deletedAt == deletedAt) &&
|
||||||
|
(identical(other.reason, reason) || other.reason == reason) &&
|
||||||
|
(identical(other.type, type) || other.type == type) &&
|
||||||
|
const DeepCollectionEquality().equals(other.permNodes, permNodes) &&
|
||||||
|
(identical(other.expiredAt, expiredAt) ||
|
||||||
|
other.expiredAt == expiredAt) &&
|
||||||
|
(identical(other.account, account) || other.account == account) &&
|
||||||
|
(identical(other.accountId, accountId) ||
|
||||||
|
other.accountId == accountId) &&
|
||||||
|
(identical(other.moderator, moderator) ||
|
||||||
|
other.moderator == moderator) &&
|
||||||
|
(identical(other.moderatorId, moderatorId) ||
|
||||||
|
other.moderatorId == moderatorId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
id,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
deletedAt,
|
||||||
|
reason,
|
||||||
|
type,
|
||||||
|
const DeepCollectionEquality().hash(permNodes),
|
||||||
|
expiredAt,
|
||||||
|
account,
|
||||||
|
accountId,
|
||||||
|
moderator,
|
||||||
|
moderatorId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPunishment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, reason: $reason, type: $type, permNodes: $permNodes, expiredAt: $expiredAt, account: $account, accountId: $accountId, moderator: $moderator, moderatorId: $moderatorId)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnPunishmentCopyWith<$Res> {
|
||||||
|
factory $SnPunishmentCopyWith(
|
||||||
|
SnPunishment value, $Res Function(SnPunishment) _then) =
|
||||||
|
_$SnPunishmentCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime createdAt,
|
||||||
|
DateTime updatedAt,
|
||||||
|
DateTime? deletedAt,
|
||||||
|
String reason,
|
||||||
|
int type,
|
||||||
|
Map<String, dynamic> permNodes,
|
||||||
|
DateTime? expiredAt,
|
||||||
|
SnAccount? account,
|
||||||
|
int? accountId,
|
||||||
|
SnAccount? moderator,
|
||||||
|
int? moderatorId});
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
$SnAccountCopyWith<$Res>? get moderator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnPunishmentCopyWithImpl<$Res> implements $SnPunishmentCopyWith<$Res> {
|
||||||
|
_$SnPunishmentCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnPunishment _self;
|
||||||
|
final $Res Function(SnPunishment) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? createdAt = null,
|
||||||
|
Object? updatedAt = null,
|
||||||
|
Object? deletedAt = freezed,
|
||||||
|
Object? reason = null,
|
||||||
|
Object? type = null,
|
||||||
|
Object? permNodes = null,
|
||||||
|
Object? expiredAt = freezed,
|
||||||
|
Object? account = freezed,
|
||||||
|
Object? accountId = freezed,
|
||||||
|
Object? moderator = freezed,
|
||||||
|
Object? moderatorId = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _self.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
createdAt: null == createdAt
|
||||||
|
? _self.createdAt
|
||||||
|
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
updatedAt: null == updatedAt
|
||||||
|
? _self.updatedAt
|
||||||
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
deletedAt: freezed == deletedAt
|
||||||
|
? _self.deletedAt
|
||||||
|
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
reason: null == reason
|
||||||
|
? _self.reason
|
||||||
|
: reason // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
type: null == type
|
||||||
|
? _self.type
|
||||||
|
: type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
permNodes: null == permNodes
|
||||||
|
? _self.permNodes
|
||||||
|
: permNodes // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
|
expiredAt: freezed == expiredAt
|
||||||
|
? _self.expiredAt
|
||||||
|
: expiredAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
|
accountId: freezed == accountId
|
||||||
|
? _self.accountId
|
||||||
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
moderator: freezed == moderator
|
||||||
|
? _self.moderator
|
||||||
|
: moderator // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
|
moderatorId: freezed == moderatorId
|
||||||
|
? _self.moderatorId
|
||||||
|
: moderatorId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get moderator {
|
||||||
|
if (_self.moderator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.moderator!, (value) {
|
||||||
|
return _then(_self.copyWith(moderator: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _SnPunishment implements SnPunishment {
|
||||||
|
const _SnPunishment(
|
||||||
|
{required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.deletedAt,
|
||||||
|
required this.reason,
|
||||||
|
required this.type,
|
||||||
|
final Map<String, dynamic> permNodes = const {},
|
||||||
|
required this.expiredAt,
|
||||||
|
required this.account,
|
||||||
|
required this.accountId,
|
||||||
|
required this.moderator,
|
||||||
|
required this.moderatorId})
|
||||||
|
: _permNodes = permNodes;
|
||||||
|
factory _SnPunishment.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnPunishmentFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
final DateTime createdAt;
|
||||||
|
@override
|
||||||
|
final DateTime updatedAt;
|
||||||
|
@override
|
||||||
|
final DateTime? deletedAt;
|
||||||
|
@override
|
||||||
|
final String reason;
|
||||||
|
@override
|
||||||
|
final int type;
|
||||||
|
final Map<String, dynamic> _permNodes;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
Map<String, dynamic> get permNodes {
|
||||||
|
if (_permNodes is EqualUnmodifiableMapView) return _permNodes;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_permNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final DateTime? expiredAt;
|
||||||
|
@override
|
||||||
|
final SnAccount? account;
|
||||||
|
@override
|
||||||
|
final int? accountId;
|
||||||
|
@override
|
||||||
|
final SnAccount? moderator;
|
||||||
|
@override
|
||||||
|
final int? moderatorId;
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnPunishmentCopyWith<_SnPunishment> get copyWith =>
|
||||||
|
__$SnPunishmentCopyWithImpl<_SnPunishment>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnPunishmentToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _SnPunishment &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.createdAt, createdAt) ||
|
||||||
|
other.createdAt == createdAt) &&
|
||||||
|
(identical(other.updatedAt, updatedAt) ||
|
||||||
|
other.updatedAt == updatedAt) &&
|
||||||
|
(identical(other.deletedAt, deletedAt) ||
|
||||||
|
other.deletedAt == deletedAt) &&
|
||||||
|
(identical(other.reason, reason) || other.reason == reason) &&
|
||||||
|
(identical(other.type, type) || other.type == type) &&
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other._permNodes, _permNodes) &&
|
||||||
|
(identical(other.expiredAt, expiredAt) ||
|
||||||
|
other.expiredAt == expiredAt) &&
|
||||||
|
(identical(other.account, account) || other.account == account) &&
|
||||||
|
(identical(other.accountId, accountId) ||
|
||||||
|
other.accountId == accountId) &&
|
||||||
|
(identical(other.moderator, moderator) ||
|
||||||
|
other.moderator == moderator) &&
|
||||||
|
(identical(other.moderatorId, moderatorId) ||
|
||||||
|
other.moderatorId == moderatorId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
id,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
deletedAt,
|
||||||
|
reason,
|
||||||
|
type,
|
||||||
|
const DeepCollectionEquality().hash(_permNodes),
|
||||||
|
expiredAt,
|
||||||
|
account,
|
||||||
|
accountId,
|
||||||
|
moderator,
|
||||||
|
moderatorId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPunishment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, reason: $reason, type: $type, permNodes: $permNodes, expiredAt: $expiredAt, account: $account, accountId: $accountId, moderator: $moderator, moderatorId: $moderatorId)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnPunishmentCopyWith<$Res>
|
||||||
|
implements $SnPunishmentCopyWith<$Res> {
|
||||||
|
factory _$SnPunishmentCopyWith(
|
||||||
|
_SnPunishment value, $Res Function(_SnPunishment) _then) =
|
||||||
|
__$SnPunishmentCopyWithImpl;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime createdAt,
|
||||||
|
DateTime updatedAt,
|
||||||
|
DateTime? deletedAt,
|
||||||
|
String reason,
|
||||||
|
int type,
|
||||||
|
Map<String, dynamic> permNodes,
|
||||||
|
DateTime? expiredAt,
|
||||||
|
SnAccount? account,
|
||||||
|
int? accountId,
|
||||||
|
SnAccount? moderator,
|
||||||
|
int? moderatorId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
@override
|
||||||
|
$SnAccountCopyWith<$Res>? get moderator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnPunishmentCopyWithImpl<$Res>
|
||||||
|
implements _$SnPunishmentCopyWith<$Res> {
|
||||||
|
__$SnPunishmentCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnPunishment _self;
|
||||||
|
final $Res Function(_SnPunishment) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? createdAt = null,
|
||||||
|
Object? updatedAt = null,
|
||||||
|
Object? deletedAt = freezed,
|
||||||
|
Object? reason = null,
|
||||||
|
Object? type = null,
|
||||||
|
Object? permNodes = null,
|
||||||
|
Object? expiredAt = freezed,
|
||||||
|
Object? account = freezed,
|
||||||
|
Object? accountId = freezed,
|
||||||
|
Object? moderator = freezed,
|
||||||
|
Object? moderatorId = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_SnPunishment(
|
||||||
|
id: null == id
|
||||||
|
? _self.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
createdAt: null == createdAt
|
||||||
|
? _self.createdAt
|
||||||
|
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
updatedAt: null == updatedAt
|
||||||
|
? _self.updatedAt
|
||||||
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
deletedAt: freezed == deletedAt
|
||||||
|
? _self.deletedAt
|
||||||
|
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
reason: null == reason
|
||||||
|
? _self.reason
|
||||||
|
: reason // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
type: null == type
|
||||||
|
? _self.type
|
||||||
|
: type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
permNodes: null == permNodes
|
||||||
|
? _self._permNodes
|
||||||
|
: permNodes // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
|
expiredAt: freezed == expiredAt
|
||||||
|
? _self.expiredAt
|
||||||
|
: expiredAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
account: freezed == account
|
||||||
|
? _self.account
|
||||||
|
: account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
|
accountId: freezed == accountId
|
||||||
|
? _self.accountId
|
||||||
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
moderator: freezed == moderator
|
||||||
|
? _self.moderator
|
||||||
|
: moderator // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,
|
||||||
|
moderatorId: freezed == moderatorId
|
||||||
|
? _self.moderatorId
|
||||||
|
: moderatorId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPunishment
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get moderator {
|
||||||
|
if (_self.moderator == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.moderator!, (value) {
|
||||||
|
return _then(_self.copyWith(moderator: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
@ -380,3 +380,43 @@ Map<String, dynamic> _$SnProgramMemberToJson(_SnProgramMember instance) =>
|
|||||||
'program': instance.program.toJson(),
|
'program': instance.program.toJson(),
|
||||||
'program_id': instance.programId,
|
'program_id': instance.programId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_SnPunishment _$SnPunishmentFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SnPunishment(
|
||||||
|
id: (json['id'] as num).toInt(),
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt: json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
reason: json['reason'] as String,
|
||||||
|
type: (json['type'] as num).toInt(),
|
||||||
|
permNodes: json['perm_nodes'] as Map<String, dynamic>? ?? const {},
|
||||||
|
expiredAt: json['expired_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['expired_at'] as String),
|
||||||
|
account: json['account'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
|
accountId: (json['account_id'] as num?)?.toInt(),
|
||||||
|
moderator: json['moderator'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['moderator'] as Map<String, dynamic>),
|
||||||
|
moderatorId: (json['moderator_id'] as num?)?.toInt(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnPunishmentToJson(_SnPunishment instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'reason': instance.reason,
|
||||||
|
'type': instance.type,
|
||||||
|
'perm_nodes': instance.permNodes,
|
||||||
|
'expired_at': instance.expiredAt?.toIso8601String(),
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'moderator': instance.moderator?.toJson(),
|
||||||
|
'moderator_id': instance.moderatorId,
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user