✨ Realm manage (CRUD)
This commit is contained in:
@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:easy_localization_loader/easy_localization_loader.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:relative_time/relative_time.dart';
|
||||
import 'package:responsive_framework/responsive_framework.dart';
|
||||
@ -18,6 +19,8 @@ void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await EasyLocalization.ensureInitialized();
|
||||
|
||||
await Hive.initFlutter();
|
||||
|
||||
if (!kReleaseMode) {
|
||||
debugInvertOversizedImages = true;
|
||||
}
|
||||
|
@ -43,26 +43,32 @@ class NavigationProvider extends ChangeNotifier {
|
||||
screen: 'explore',
|
||||
label: 'screenExplore',
|
||||
),
|
||||
AppNavDestination(
|
||||
icon: Icon(Symbols.chat, weight: 400, opticalSize: 20),
|
||||
screen: 'chat',
|
||||
label: 'screenChat',
|
||||
),
|
||||
AppNavDestination(
|
||||
icon: Icon(Symbols.account_circle, weight: 400, opticalSize: 20),
|
||||
screen: 'account',
|
||||
label: 'screenAccount',
|
||||
),
|
||||
AppNavDestination(
|
||||
icon: Icon(Symbols.group, weight: 400, opticalSize: 20),
|
||||
screen: 'realm',
|
||||
label: 'screenRealm',
|
||||
),
|
||||
AppNavDestination(
|
||||
icon: Icon(Symbols.album, weight: 400, opticalSize: 20),
|
||||
screen: 'album',
|
||||
label: 'screenAlbum',
|
||||
),
|
||||
AppNavDestination(
|
||||
icon: Icon(Symbols.chat, weight: 400, opticalSize: 20),
|
||||
screen: 'chat',
|
||||
label: 'screenChat',
|
||||
),
|
||||
];
|
||||
static const List<String> kDefaultPinnedDestination = [
|
||||
'home',
|
||||
'explore',
|
||||
'account'
|
||||
'chat',
|
||||
'account',
|
||||
];
|
||||
|
||||
List<AppNavDestination> destinations = [];
|
||||
|
@ -9,10 +9,13 @@ import 'package:surface/screens/album.dart';
|
||||
import 'package:surface/screens/auth/login.dart';
|
||||
import 'package:surface/screens/auth/register.dart';
|
||||
import 'package:surface/screens/chat.dart';
|
||||
import 'package:surface/screens/chat/manage.dart';
|
||||
import 'package:surface/screens/explore.dart';
|
||||
import 'package:surface/screens/home.dart';
|
||||
import 'package:surface/screens/post/post_detail.dart';
|
||||
import 'package:surface/screens/post/post_editor.dart';
|
||||
import 'package:surface/screens/realm.dart';
|
||||
import 'package:surface/screens/realm/manage.dart';
|
||||
import 'package:surface/screens/settings.dart';
|
||||
import 'package:surface/types/post.dart';
|
||||
import 'package:surface/widgets/navigation/app_background.dart';
|
||||
@ -98,6 +101,55 @@ final _appRoutes = [
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
child: const ChatScreen(),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/chat/manage',
|
||||
name: 'chatManage',
|
||||
pageBuilder: (context, state) => CustomTransitionPage(
|
||||
child: ChatManageScreen(),
|
||||
transitionsBuilder:
|
||||
(context, animation, secondaryAnimation, child) {
|
||||
return FadeThroughTransition(
|
||||
animation: animation,
|
||||
secondaryAnimation: secondaryAnimation,
|
||||
child: AppBackground(
|
||||
isLessOptimization: true,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: '/realm',
|
||||
name: 'realm',
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
child: const RealmScreen(),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/realm/manage',
|
||||
name: 'realmManage',
|
||||
pageBuilder: (context, state) => CustomTransitionPage(
|
||||
child: RealmManageScreen(
|
||||
editingRealmAlias: state.uri.queryParameters['editing'],
|
||||
),
|
||||
transitionsBuilder:
|
||||
(context, animation, secondaryAnimation, child) {
|
||||
return FadeThroughTransition(
|
||||
animation: animation,
|
||||
secondaryAnimation: secondaryAnimation,
|
||||
child: AppBackground(
|
||||
isLessOptimization: true,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: '/album',
|
||||
|
@ -148,20 +148,14 @@ class _AccountPublisherEditScreenState
|
||||
mimetype: 'image/png',
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
await sn.client.put(
|
||||
'/cgi/id/users/me/$place',
|
||||
data: {'attachment': attachment.rid},
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
final ua = context.read<UserProvider>();
|
||||
await ua.refreshUser();
|
||||
|
||||
if (!mounted) return;
|
||||
context.showSnackbar('accountProfileEditApplied'.tr());
|
||||
_syncWidget();
|
||||
switch (place) {
|
||||
case 'avatar':
|
||||
_avatar = attachment.rid;
|
||||
break;
|
||||
case 'banner':
|
||||
_banner = attachment.rid;
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
@ -286,7 +280,7 @@ class _AccountPublisherEditScreenState
|
||||
],
|
||||
)
|
||||
],
|
||||
).padding(horizontal: 16, vertical: 12),
|
||||
).padding(horizontal: 24, vertical: 12),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,40 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
|
||||
class ChatScreen extends StatelessWidget {
|
||||
class ChatScreen extends StatefulWidget {
|
||||
const ChatScreen({super.key});
|
||||
|
||||
@override
|
||||
State<ChatScreen> createState() => _ChatScreenState();
|
||||
}
|
||||
|
||||
class _ChatScreenState extends State<ChatScreen> {
|
||||
Future<void> _fetchChannels({scope = 'global', direct = false}) async {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final resp = await sn.client.get(
|
||||
'/cgi/im/channels/$scope/me/available',
|
||||
queryParameters: {
|
||||
'direct': direct,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('screenChat').tr(),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Symbols.chat_add_on),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pushNamed('chatManage');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
139
lib/screens/chat/manage.dart
Normal file
139
lib/screens/chat/manage.dart
Normal file
@ -0,0 +1,139 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.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/widgets/dialog.dart';
|
||||
import 'package:surface/widgets/loading_indicator.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChatManageScreen extends StatefulWidget {
|
||||
final String? editingChannelAlias;
|
||||
const ChatManageScreen({super.key, this.editingChannelAlias});
|
||||
|
||||
@override
|
||||
State<ChatManageScreen> createState() => _ChatManageScreenState();
|
||||
}
|
||||
|
||||
class _ChatManageScreenState extends State<ChatManageScreen> {
|
||||
bool _isBusy = false;
|
||||
|
||||
final _aliasController = TextEditingController();
|
||||
final _nameController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
||||
|
||||
Future<void> _performAction() async {
|
||||
final uuid = const Uuid();
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
// TODO Add realm support
|
||||
// final scope = widget.realm != null ? widget.realm!.alias : 'global';
|
||||
final scope = 'global';
|
||||
final payload = {
|
||||
'alias': _aliasController.text.isNotEmpty
|
||||
? _aliasController.text.toLowerCase()
|
||||
: uuid.v4().replaceAll('-', '').substring(0, 12),
|
||||
'name': _nameController.text,
|
||||
'description': _descriptionController.text,
|
||||
};
|
||||
|
||||
try {
|
||||
final resp = await sn.client.request(
|
||||
widget.editingChannelAlias != null
|
||||
? '/cgi/im/channels/$scope/${widget.editingChannelAlias}'
|
||||
: '/cgi/im/channels/$scope',
|
||||
data: payload,
|
||||
options: Options(
|
||||
method: widget.editingChannelAlias != null ? 'PUT' : 'POST',
|
||||
),
|
||||
);
|
||||
log(jsonEncode(resp.data));
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) Navigator.pop(context, resp.data);
|
||||
} catch (err) {
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) context.showErrorDialog(err);
|
||||
}
|
||||
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_aliasController.dispose();
|
||||
_nameController.dispose();
|
||||
_descriptionController.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: widget.editingChannelAlias != null
|
||||
? Text('screenChatManage').tr()
|
||||
: Text('screenChatNew').tr(),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
LoadingIndicator(isActive: _isBusy),
|
||||
const Gap(24),
|
||||
TextField(
|
||||
controller: _aliasController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldChatAlias'.tr(),
|
||||
helperText: 'fieldChatAliasHint'.tr(),
|
||||
helperMaxLines: 2,
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _nameController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldChatName'.tr(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _descriptionController,
|
||||
maxLines: null,
|
||||
minLines: 3,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldChatDescription'.tr(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: _isBusy ? null : _performAction,
|
||||
icon: const Icon(Symbols.save),
|
||||
label: Text('apply').tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).padding(horizontal: 24),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
220
lib/screens/realm.dart
Normal file
220
lib/screens/realm.dart
Normal file
@ -0,0 +1,220 @@
|
||||
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/realm.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/universal_image.dart';
|
||||
|
||||
class RealmScreen extends StatefulWidget {
|
||||
const RealmScreen({super.key});
|
||||
|
||||
@override
|
||||
State<RealmScreen> createState() => _RealmScreenState();
|
||||
}
|
||||
|
||||
class _RealmScreenState extends State<RealmScreen> {
|
||||
bool _isBusy = false;
|
||||
bool _isCompactView = false;
|
||||
|
||||
List<SnRealm>? _realms;
|
||||
|
||||
Future<void> _fetchRealms() async {
|
||||
setState(() => _isBusy = true);
|
||||
try {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final resp = await sn.client.get('/cgi/id/realms/me/available');
|
||||
_realms = List<SnRealm>.from(
|
||||
resp.data?.map((e) => SnRealm.fromJson(e)) ?? [],
|
||||
);
|
||||
} catch (err) {
|
||||
if (mounted) context.showErrorDialog(err);
|
||||
} finally {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _deleteRealm(SnRealm realm) async {
|
||||
final confirm = await context.showConfirmDialog(
|
||||
'realmDelete'.tr(args: ['#${realm.alias}']),
|
||||
'realmDeleteDescription'.tr(),
|
||||
);
|
||||
if (!confirm) return;
|
||||
|
||||
if (!mounted) return;
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
try {
|
||||
await sn.client.delete('/cgi/id/realms/${realm.alias}');
|
||||
if (!mounted) return;
|
||||
context.showSnackbar('realmDeleted'.tr(args: ['#${realm.alias}']));
|
||||
_fetchRealms();
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
} finally {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_fetchRealms();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('screenRealm').tr(),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: !_isCompactView
|
||||
? const Icon(Icons.view_list)
|
||||
: const Icon(Icons.view_module),
|
||||
onPressed: () {
|
||||
setState(() => _isCompactView = !_isCompactView);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Symbols.group_add),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pushNamed('realmManage');
|
||||
},
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
LoadingIndicator(isActive: _isBusy),
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: _fetchRealms,
|
||||
child: ListView.builder(
|
||||
itemCount: _realms?.length ?? 0,
|
||||
itemBuilder: (context, idx) {
|
||||
final realm = _realms![idx];
|
||||
if (_isCompactView) {
|
||||
return ListTile(
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 16),
|
||||
leading: AccountImage(
|
||||
content: realm.avatar,
|
||||
fallbackWidget: const Icon(Symbols.group, size: 20),
|
||||
),
|
||||
title: Text(realm.name),
|
||||
subtitle: Text(
|
||||
realm.description,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
trailing: PopupMenuButton(
|
||||
itemBuilder: (BuildContext context) => [
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Symbols.edit),
|
||||
const Gap(16),
|
||||
Text('edit').tr(),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
GoRouter.of(context).pushNamed(
|
||||
'realmManage',
|
||||
queryParameters: {'editing': realm.alias},
|
||||
).then((value) {
|
||||
if (value != null) {
|
||||
_fetchRealms();
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Symbols.delete),
|
||||
const Gap(16),
|
||||
Text('delete').tr(),
|
||||
],
|
||||
),
|
||||
onTap: () {
|
||||
_deleteRealm(realm);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(12),
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: 16 / 7,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surfaceContainer,
|
||||
child: (realm.banner?.isEmpty ?? true)
|
||||
? const SizedBox.shrink()
|
||||
: AutoResizeUniversalImage(
|
||||
sn.getAttachmentUrl(realm.banner!),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: -30,
|
||||
left: 18,
|
||||
child: AccountImage(
|
||||
content: realm.avatar,
|
||||
radius: 24,
|
||||
fallbackWidget:
|
||||
const Icon(Symbols.group, size: 24),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Gap(20 + 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(realm.name).textStyle(
|
||||
Theme.of(context).textTheme.titleMedium!),
|
||||
Text(realm.description).textStyle(
|
||||
Theme.of(context).textTheme.bodySmall!),
|
||||
],
|
||||
).padding(horizontal: 24, bottom: 14),
|
||||
],
|
||||
),
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
312
lib/screens/realm/manage.dart
Normal file
312
lib/screens/realm/manage.dart
Normal file
@ -0,0 +1,312 @@
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:croppy/croppy.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:path/path.dart' show basename;
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/providers/sn_attachment.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/types/realm.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/universal_image.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class RealmManageScreen extends StatefulWidget {
|
||||
final String? editingRealmAlias;
|
||||
const RealmManageScreen({super.key, this.editingRealmAlias});
|
||||
|
||||
@override
|
||||
State<RealmManageScreen> createState() => _RealmManageScreenState();
|
||||
}
|
||||
|
||||
class _RealmManageScreenState extends State<RealmManageScreen> {
|
||||
bool _isBusy = false;
|
||||
|
||||
SnRealm? _editingRealm;
|
||||
|
||||
Future<void> _fetchRealm() async {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
try {
|
||||
final resp =
|
||||
await sn.client.get('/cgi/id/realms/${widget.editingRealmAlias}');
|
||||
final out = SnRealm.fromJson(resp.data);
|
||||
_editingRealm = out;
|
||||
_avatar = out.avatar;
|
||||
_banner = out.banner;
|
||||
_aliasController.text = out.alias;
|
||||
_nameController.text = out.name;
|
||||
_descriptionController.text = out.description;
|
||||
} catch (err) {
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) context.showErrorDialog(err);
|
||||
} finally {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
}
|
||||
|
||||
String? _avatar;
|
||||
String? _banner;
|
||||
|
||||
final _aliasController = TextEditingController();
|
||||
final _nameController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
||||
|
||||
final _imagePicker = ImagePicker();
|
||||
|
||||
Future<void> _updateImage(String place) async {
|
||||
final image = await _imagePicker.pickImage(source: ImageSource.gallery);
|
||||
if (image == null) return;
|
||||
if (!mounted) return;
|
||||
|
||||
final ImageProvider imageProvider =
|
||||
kIsWeb ? NetworkImage(image.path) : FileImage(File(image.path));
|
||||
final aspectRatios = place == 'banner'
|
||||
? [CropAspectRatio(width: 16, height: 7)]
|
||||
: [CropAspectRatio(width: 1, height: 1)];
|
||||
final result = (!kIsWeb && (Platform.isIOS || Platform.isMacOS))
|
||||
? await showCupertinoImageCropper(
|
||||
// ignore: use_build_context_synchronously
|
||||
context,
|
||||
allowedAspectRatios: aspectRatios,
|
||||
imageProvider: imageProvider,
|
||||
)
|
||||
: await showMaterialImageCropper(
|
||||
// ignore: use_build_context_synchronously
|
||||
context,
|
||||
allowedAspectRatios: aspectRatios,
|
||||
imageProvider: imageProvider,
|
||||
);
|
||||
|
||||
if (result == null) return;
|
||||
|
||||
if (!mounted) return;
|
||||
final attach = context.read<SnAttachmentProvider>();
|
||||
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
final rawBytes =
|
||||
(await result.uiImage.toByteData(format: ImageByteFormat.png))!
|
||||
.buffer
|
||||
.asUint8List();
|
||||
|
||||
try {
|
||||
final attachment = await attach.directUploadOne(
|
||||
rawBytes,
|
||||
basename(image.path),
|
||||
'avatar',
|
||||
null,
|
||||
mimetype: 'image/png',
|
||||
);
|
||||
|
||||
switch (place) {
|
||||
case 'avatar':
|
||||
_avatar = attachment.rid;
|
||||
break;
|
||||
case 'banner':
|
||||
_banner = attachment.rid;
|
||||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
} finally {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _performAction() async {
|
||||
final uuid = const Uuid();
|
||||
final payload = {
|
||||
'alias': _aliasController.text.isNotEmpty
|
||||
? _aliasController.text.toLowerCase()
|
||||
: uuid.v4().replaceAll('-', '').substring(0, 12),
|
||||
'name': _nameController.text,
|
||||
'description': _descriptionController.text,
|
||||
'avatar': _avatar,
|
||||
'banner': _banner,
|
||||
};
|
||||
|
||||
try {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final resp = await sn.client.request(
|
||||
widget.editingRealmAlias != null
|
||||
? '/cgi/id/realms/${widget.editingRealmAlias}'
|
||||
: '/cgi/id/realms',
|
||||
data: payload,
|
||||
options: Options(
|
||||
method: widget.editingRealmAlias != null ? 'PUT' : 'POST',
|
||||
),
|
||||
);
|
||||
final out = SnRealm.fromJson(resp.data);
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) Navigator.pop(context, out);
|
||||
} catch (err) {
|
||||
// ignore: use_build_context_synchronously
|
||||
if (context.mounted) context.showErrorDialog(err);
|
||||
} finally {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.editingRealmAlias != null) _fetchRealm();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_aliasController.dispose();
|
||||
_nameController.dispose();
|
||||
_descriptionController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: widget.editingRealmAlias != null
|
||||
? Text('screenRealmManage').tr()
|
||||
: Text('screenRealmNew').tr(),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
LoadingIndicator(isActive: _isBusy),
|
||||
if (_editingRealm != null)
|
||||
MaterialBanner(
|
||||
leading: const Icon(Icons.edit),
|
||||
leadingPadding: const EdgeInsets.only(left: 10, right: 20),
|
||||
dividerColor: Colors.transparent,
|
||||
content: Text(
|
||||
'realmEditingNotice'.tr(args: ['#${_editingRealm!.alias}']),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('cancel').tr(),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(24),
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Material(
|
||||
elevation: 0,
|
||||
child: InkWell(
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 16 / 9,
|
||||
child: Container(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surfaceContainerHigh,
|
||||
child: _banner != null
|
||||
? AutoResizeUniversalImage(
|
||||
sn.getAttachmentUrl(_banner!),
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
_updateImage('banner');
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: -28,
|
||||
left: 16,
|
||||
child: Material(
|
||||
elevation: 2,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(40)),
|
||||
child: InkWell(
|
||||
child: AccountImage(
|
||||
content: _avatar,
|
||||
radius: 40,
|
||||
fallbackWidget: const Icon(Symbols.group, size: 40),
|
||||
),
|
||||
onTap: () {
|
||||
_updateImage('avatar');
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
).padding(horizontal: 24),
|
||||
const Gap(8 + 28),
|
||||
Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: _aliasController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldRealmAlias'.tr(),
|
||||
helperText: 'fieldRealmAliasHint'.tr(),
|
||||
helperMaxLines: 2,
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _nameController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldRealmName'.tr(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _descriptionController,
|
||||
maxLines: null,
|
||||
minLines: 3,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldRealmDescription'.tr(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: _isBusy ? null : _performAction,
|
||||
icon: const Icon(Symbols.save),
|
||||
label: Text('apply').tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).padding(horizontal: 24 + 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
46
lib/types/realm.dart
Normal file
46
lib/types/realm.dart
Normal file
@ -0,0 +1,46 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:surface/types/account.dart';
|
||||
|
||||
part 'realm.freezed.dart';
|
||||
part 'realm.g.dart';
|
||||
|
||||
@freezed
|
||||
class SnRealmMember with _$SnRealmMember {
|
||||
const factory SnRealmMember({
|
||||
required int id,
|
||||
required DateTime createdAt,
|
||||
required DateTime updatedAt,
|
||||
required DateTime? deletedAt,
|
||||
required int realmId,
|
||||
required int accountId,
|
||||
required SnRealm realm,
|
||||
required SnAccount account,
|
||||
required int powerLevel,
|
||||
}) = _SnRealmMember;
|
||||
|
||||
factory SnRealmMember.fromJson(Map<String, dynamic> json) =>
|
||||
_$SnRealmMemberFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SnRealm with _$SnRealm {
|
||||
const factory SnRealm({
|
||||
required int id,
|
||||
required DateTime createdAt,
|
||||
required DateTime updatedAt,
|
||||
required DateTime? deletedAt,
|
||||
required String alias,
|
||||
required String name,
|
||||
required String description,
|
||||
required List<SnRealmMember>? members,
|
||||
required String? avatar,
|
||||
required String? banner,
|
||||
required Map<String, dynamic>? accessPolicy,
|
||||
required bool isPublic,
|
||||
required bool isCommunity,
|
||||
required int accountId,
|
||||
}) = _SnRealm;
|
||||
|
||||
factory SnRealm.fromJson(Map<String, dynamic> json) =>
|
||||
_$SnRealmFromJson(json);
|
||||
}
|
812
lib/types/realm.freezed.dart
Normal file
812
lib/types/realm.freezed.dart
Normal file
@ -0,0 +1,812 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'realm.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
SnRealmMember _$SnRealmMemberFromJson(Map<String, dynamic> json) {
|
||||
return _SnRealmMember.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SnRealmMember {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
DateTime get updatedAt => throw _privateConstructorUsedError;
|
||||
DateTime? get deletedAt => throw _privateConstructorUsedError;
|
||||
int get realmId => throw _privateConstructorUsedError;
|
||||
int get accountId => throw _privateConstructorUsedError;
|
||||
SnRealm get realm => throw _privateConstructorUsedError;
|
||||
SnAccount get account => throw _privateConstructorUsedError;
|
||||
int get powerLevel => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this SnRealmMember to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$SnRealmMemberCopyWith<SnRealmMember> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SnRealmMemberCopyWith<$Res> {
|
||||
factory $SnRealmMemberCopyWith(
|
||||
SnRealmMember value, $Res Function(SnRealmMember) then) =
|
||||
_$SnRealmMemberCopyWithImpl<$Res, SnRealmMember>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
int realmId,
|
||||
int accountId,
|
||||
SnRealm realm,
|
||||
SnAccount account,
|
||||
int powerLevel});
|
||||
|
||||
$SnRealmCopyWith<$Res> get realm;
|
||||
$SnAccountCopyWith<$Res> get account;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SnRealmMemberCopyWithImpl<$Res, $Val extends SnRealmMember>
|
||||
implements $SnRealmMemberCopyWith<$Res> {
|
||||
_$SnRealmMemberCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// 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? realmId = null,
|
||||
Object? accountId = null,
|
||||
Object? realm = null,
|
||||
Object? account = null,
|
||||
Object? powerLevel = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _value.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
realmId: null == realmId
|
||||
? _value.realmId
|
||||
: realmId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
accountId: null == accountId
|
||||
? _value.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
realm: null == realm
|
||||
? _value.realm
|
||||
: realm // ignore: cast_nullable_to_non_nullable
|
||||
as SnRealm,
|
||||
account: null == account
|
||||
? _value.account
|
||||
: account // ignore: cast_nullable_to_non_nullable
|
||||
as SnAccount,
|
||||
powerLevel: null == powerLevel
|
||||
? _value.powerLevel
|
||||
: powerLevel // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SnRealmCopyWith<$Res> get realm {
|
||||
return $SnRealmCopyWith<$Res>(_value.realm, (value) {
|
||||
return _then(_value.copyWith(realm: value) as $Val);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SnAccountCopyWith<$Res> get account {
|
||||
return $SnAccountCopyWith<$Res>(_value.account, (value) {
|
||||
return _then(_value.copyWith(account: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$SnRealmMemberImplCopyWith<$Res>
|
||||
implements $SnRealmMemberCopyWith<$Res> {
|
||||
factory _$$SnRealmMemberImplCopyWith(
|
||||
_$SnRealmMemberImpl value, $Res Function(_$SnRealmMemberImpl) then) =
|
||||
__$$SnRealmMemberImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
int realmId,
|
||||
int accountId,
|
||||
SnRealm realm,
|
||||
SnAccount account,
|
||||
int powerLevel});
|
||||
|
||||
@override
|
||||
$SnRealmCopyWith<$Res> get realm;
|
||||
@override
|
||||
$SnAccountCopyWith<$Res> get account;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$SnRealmMemberImplCopyWithImpl<$Res>
|
||||
extends _$SnRealmMemberCopyWithImpl<$Res, _$SnRealmMemberImpl>
|
||||
implements _$$SnRealmMemberImplCopyWith<$Res> {
|
||||
__$$SnRealmMemberImplCopyWithImpl(
|
||||
_$SnRealmMemberImpl _value, $Res Function(_$SnRealmMemberImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// 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? realmId = null,
|
||||
Object? accountId = null,
|
||||
Object? realm = null,
|
||||
Object? account = null,
|
||||
Object? powerLevel = null,
|
||||
}) {
|
||||
return _then(_$SnRealmMemberImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _value.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
realmId: null == realmId
|
||||
? _value.realmId
|
||||
: realmId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
accountId: null == accountId
|
||||
? _value.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
realm: null == realm
|
||||
? _value.realm
|
||||
: realm // ignore: cast_nullable_to_non_nullable
|
||||
as SnRealm,
|
||||
account: null == account
|
||||
? _value.account
|
||||
: account // ignore: cast_nullable_to_non_nullable
|
||||
as SnAccount,
|
||||
powerLevel: null == powerLevel
|
||||
? _value.powerLevel
|
||||
: powerLevel // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$SnRealmMemberImpl implements _SnRealmMember {
|
||||
const _$SnRealmMemberImpl(
|
||||
{required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.deletedAt,
|
||||
required this.realmId,
|
||||
required this.accountId,
|
||||
required this.realm,
|
||||
required this.account,
|
||||
required this.powerLevel});
|
||||
|
||||
factory _$SnRealmMemberImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$SnRealmMemberImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
final DateTime updatedAt;
|
||||
@override
|
||||
final DateTime? deletedAt;
|
||||
@override
|
||||
final int realmId;
|
||||
@override
|
||||
final int accountId;
|
||||
@override
|
||||
final SnRealm realm;
|
||||
@override
|
||||
final SnAccount account;
|
||||
@override
|
||||
final int powerLevel;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnRealmMember(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, realmId: $realmId, accountId: $accountId, realm: $realm, account: $account, powerLevel: $powerLevel)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$SnRealmMemberImpl &&
|
||||
(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.realmId, realmId) || other.realmId == realmId) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId) &&
|
||||
(identical(other.realm, realm) || other.realm == realm) &&
|
||||
(identical(other.account, account) || other.account == account) &&
|
||||
(identical(other.powerLevel, powerLevel) ||
|
||||
other.powerLevel == powerLevel));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, createdAt, updatedAt,
|
||||
deletedAt, realmId, accountId, realm, account, powerLevel);
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$SnRealmMemberImplCopyWith<_$SnRealmMemberImpl> get copyWith =>
|
||||
__$$SnRealmMemberImplCopyWithImpl<_$SnRealmMemberImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$SnRealmMemberImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _SnRealmMember implements SnRealmMember {
|
||||
const factory _SnRealmMember(
|
||||
{required final int id,
|
||||
required final DateTime createdAt,
|
||||
required final DateTime updatedAt,
|
||||
required final DateTime? deletedAt,
|
||||
required final int realmId,
|
||||
required final int accountId,
|
||||
required final SnRealm realm,
|
||||
required final SnAccount account,
|
||||
required final int powerLevel}) = _$SnRealmMemberImpl;
|
||||
|
||||
factory _SnRealmMember.fromJson(Map<String, dynamic> json) =
|
||||
_$SnRealmMemberImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
DateTime get createdAt;
|
||||
@override
|
||||
DateTime get updatedAt;
|
||||
@override
|
||||
DateTime? get deletedAt;
|
||||
@override
|
||||
int get realmId;
|
||||
@override
|
||||
int get accountId;
|
||||
@override
|
||||
SnRealm get realm;
|
||||
@override
|
||||
SnAccount get account;
|
||||
@override
|
||||
int get powerLevel;
|
||||
|
||||
/// Create a copy of SnRealmMember
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$SnRealmMemberImplCopyWith<_$SnRealmMemberImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
SnRealm _$SnRealmFromJson(Map<String, dynamic> json) {
|
||||
return _SnRealm.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SnRealm {
|
||||
int get id => throw _privateConstructorUsedError;
|
||||
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||
DateTime get updatedAt => throw _privateConstructorUsedError;
|
||||
DateTime? get deletedAt => throw _privateConstructorUsedError;
|
||||
String get alias => throw _privateConstructorUsedError;
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get description => throw _privateConstructorUsedError;
|
||||
List<SnRealmMember>? get members => throw _privateConstructorUsedError;
|
||||
String? get avatar => throw _privateConstructorUsedError;
|
||||
String? get banner => throw _privateConstructorUsedError;
|
||||
Map<String, dynamic>? get accessPolicy => throw _privateConstructorUsedError;
|
||||
bool get isPublic => throw _privateConstructorUsedError;
|
||||
bool get isCommunity => throw _privateConstructorUsedError;
|
||||
int get accountId => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this SnRealm to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of SnRealm
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$SnRealmCopyWith<SnRealm> get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SnRealmCopyWith<$Res> {
|
||||
factory $SnRealmCopyWith(SnRealm value, $Res Function(SnRealm) then) =
|
||||
_$SnRealmCopyWithImpl<$Res, SnRealm>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
String alias,
|
||||
String name,
|
||||
String description,
|
||||
List<SnRealmMember>? members,
|
||||
String? avatar,
|
||||
String? banner,
|
||||
Map<String, dynamic>? accessPolicy,
|
||||
bool isPublic,
|
||||
bool isCommunity,
|
||||
int accountId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SnRealmCopyWithImpl<$Res, $Val extends SnRealm>
|
||||
implements $SnRealmCopyWith<$Res> {
|
||||
_$SnRealmCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of SnRealm
|
||||
/// 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? alias = null,
|
||||
Object? name = null,
|
||||
Object? description = null,
|
||||
Object? members = freezed,
|
||||
Object? avatar = freezed,
|
||||
Object? banner = freezed,
|
||||
Object? accessPolicy = freezed,
|
||||
Object? isPublic = null,
|
||||
Object? isCommunity = null,
|
||||
Object? accountId = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _value.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
alias: null == alias
|
||||
? _value.alias
|
||||
: alias // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
members: freezed == members
|
||||
? _value.members
|
||||
: members // ignore: cast_nullable_to_non_nullable
|
||||
as List<SnRealmMember>?,
|
||||
avatar: freezed == avatar
|
||||
? _value.avatar
|
||||
: avatar // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
banner: freezed == banner
|
||||
? _value.banner
|
||||
: banner // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
accessPolicy: freezed == accessPolicy
|
||||
? _value.accessPolicy
|
||||
: accessPolicy // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,
|
||||
isPublic: null == isPublic
|
||||
? _value.isPublic
|
||||
: isPublic // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isCommunity: null == isCommunity
|
||||
? _value.isCommunity
|
||||
: isCommunity // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
accountId: null == accountId
|
||||
? _value.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$SnRealmImplCopyWith<$Res> implements $SnRealmCopyWith<$Res> {
|
||||
factory _$$SnRealmImplCopyWith(
|
||||
_$SnRealmImpl value, $Res Function(_$SnRealmImpl) then) =
|
||||
__$$SnRealmImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
String alias,
|
||||
String name,
|
||||
String description,
|
||||
List<SnRealmMember>? members,
|
||||
String? avatar,
|
||||
String? banner,
|
||||
Map<String, dynamic>? accessPolicy,
|
||||
bool isPublic,
|
||||
bool isCommunity,
|
||||
int accountId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$SnRealmImplCopyWithImpl<$Res>
|
||||
extends _$SnRealmCopyWithImpl<$Res, _$SnRealmImpl>
|
||||
implements _$$SnRealmImplCopyWith<$Res> {
|
||||
__$$SnRealmImplCopyWithImpl(
|
||||
_$SnRealmImpl _value, $Res Function(_$SnRealmImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of SnRealm
|
||||
/// 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? alias = null,
|
||||
Object? name = null,
|
||||
Object? description = null,
|
||||
Object? members = freezed,
|
||||
Object? avatar = freezed,
|
||||
Object? banner = freezed,
|
||||
Object? accessPolicy = freezed,
|
||||
Object? isPublic = null,
|
||||
Object? isCommunity = null,
|
||||
Object? accountId = null,
|
||||
}) {
|
||||
return _then(_$SnRealmImpl(
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
createdAt: null == createdAt
|
||||
? _value.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _value.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _value.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
alias: null == alias
|
||||
? _value.alias
|
||||
: alias // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _value.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
members: freezed == members
|
||||
? _value._members
|
||||
: members // ignore: cast_nullable_to_non_nullable
|
||||
as List<SnRealmMember>?,
|
||||
avatar: freezed == avatar
|
||||
? _value.avatar
|
||||
: avatar // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
banner: freezed == banner
|
||||
? _value.banner
|
||||
: banner // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
accessPolicy: freezed == accessPolicy
|
||||
? _value._accessPolicy
|
||||
: accessPolicy // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,
|
||||
isPublic: null == isPublic
|
||||
? _value.isPublic
|
||||
: isPublic // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isCommunity: null == isCommunity
|
||||
? _value.isCommunity
|
||||
: isCommunity // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
accountId: null == accountId
|
||||
? _value.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$SnRealmImpl implements _SnRealm {
|
||||
const _$SnRealmImpl(
|
||||
{required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.deletedAt,
|
||||
required this.alias,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required final List<SnRealmMember>? members,
|
||||
required this.avatar,
|
||||
required this.banner,
|
||||
required final Map<String, dynamic>? accessPolicy,
|
||||
required this.isPublic,
|
||||
required this.isCommunity,
|
||||
required this.accountId})
|
||||
: _members = members,
|
||||
_accessPolicy = accessPolicy;
|
||||
|
||||
factory _$SnRealmImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$SnRealmImplFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
final DateTime updatedAt;
|
||||
@override
|
||||
final DateTime? deletedAt;
|
||||
@override
|
||||
final String alias;
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String description;
|
||||
final List<SnRealmMember>? _members;
|
||||
@override
|
||||
List<SnRealmMember>? get members {
|
||||
final value = _members;
|
||||
if (value == null) return null;
|
||||
if (_members is EqualUnmodifiableListView) return _members;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
final String? avatar;
|
||||
@override
|
||||
final String? banner;
|
||||
final Map<String, dynamic>? _accessPolicy;
|
||||
@override
|
||||
Map<String, dynamic>? get accessPolicy {
|
||||
final value = _accessPolicy;
|
||||
if (value == null) return null;
|
||||
if (_accessPolicy is EqualUnmodifiableMapView) return _accessPolicy;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
final bool isPublic;
|
||||
@override
|
||||
final bool isCommunity;
|
||||
@override
|
||||
final int accountId;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnRealm(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, alias: $alias, name: $name, description: $description, members: $members, avatar: $avatar, banner: $banner, accessPolicy: $accessPolicy, isPublic: $isPublic, isCommunity: $isCommunity, accountId: $accountId)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$SnRealmImpl &&
|
||||
(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.alias, alias) || other.alias == alias) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
const DeepCollectionEquality().equals(other._members, _members) &&
|
||||
(identical(other.avatar, avatar) || other.avatar == avatar) &&
|
||||
(identical(other.banner, banner) || other.banner == banner) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._accessPolicy, _accessPolicy) &&
|
||||
(identical(other.isPublic, isPublic) ||
|
||||
other.isPublic == isPublic) &&
|
||||
(identical(other.isCommunity, isCommunity) ||
|
||||
other.isCommunity == isCommunity) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
deletedAt,
|
||||
alias,
|
||||
name,
|
||||
description,
|
||||
const DeepCollectionEquality().hash(_members),
|
||||
avatar,
|
||||
banner,
|
||||
const DeepCollectionEquality().hash(_accessPolicy),
|
||||
isPublic,
|
||||
isCommunity,
|
||||
accountId);
|
||||
|
||||
/// Create a copy of SnRealm
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$SnRealmImplCopyWith<_$SnRealmImpl> get copyWith =>
|
||||
__$$SnRealmImplCopyWithImpl<_$SnRealmImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$SnRealmImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _SnRealm implements SnRealm {
|
||||
const factory _SnRealm(
|
||||
{required final int id,
|
||||
required final DateTime createdAt,
|
||||
required final DateTime updatedAt,
|
||||
required final DateTime? deletedAt,
|
||||
required final String alias,
|
||||
required final String name,
|
||||
required final String description,
|
||||
required final List<SnRealmMember>? members,
|
||||
required final String? avatar,
|
||||
required final String? banner,
|
||||
required final Map<String, dynamic>? accessPolicy,
|
||||
required final bool isPublic,
|
||||
required final bool isCommunity,
|
||||
required final int accountId}) = _$SnRealmImpl;
|
||||
|
||||
factory _SnRealm.fromJson(Map<String, dynamic> json) = _$SnRealmImpl.fromJson;
|
||||
|
||||
@override
|
||||
int get id;
|
||||
@override
|
||||
DateTime get createdAt;
|
||||
@override
|
||||
DateTime get updatedAt;
|
||||
@override
|
||||
DateTime? get deletedAt;
|
||||
@override
|
||||
String get alias;
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
List<SnRealmMember>? get members;
|
||||
@override
|
||||
String? get avatar;
|
||||
@override
|
||||
String? get banner;
|
||||
@override
|
||||
Map<String, dynamic>? get accessPolicy;
|
||||
@override
|
||||
bool get isPublic;
|
||||
@override
|
||||
bool get isCommunity;
|
||||
@override
|
||||
int get accountId;
|
||||
|
||||
/// Create a copy of SnRealm
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$SnRealmImplCopyWith<_$SnRealmImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
75
lib/types/realm.g.dart
Normal file
75
lib/types/realm.g.dart
Normal file
@ -0,0 +1,75 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'realm.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$SnRealmMemberImpl _$$SnRealmMemberImplFromJson(Map<String, dynamic> json) =>
|
||||
_$SnRealmMemberImpl(
|
||||
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),
|
||||
realmId: (json['realm_id'] as num).toInt(),
|
||||
accountId: (json['account_id'] as num).toInt(),
|
||||
realm: SnRealm.fromJson(json['realm'] as Map<String, dynamic>),
|
||||
account: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||
powerLevel: (json['power_level'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$SnRealmMemberImplToJson(_$SnRealmMemberImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||
'realm_id': instance.realmId,
|
||||
'account_id': instance.accountId,
|
||||
'realm': instance.realm.toJson(),
|
||||
'account': instance.account.toJson(),
|
||||
'power_level': instance.powerLevel,
|
||||
};
|
||||
|
||||
_$SnRealmImpl _$$SnRealmImplFromJson(Map<String, dynamic> json) =>
|
||||
_$SnRealmImpl(
|
||||
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),
|
||||
alias: json['alias'] as String,
|
||||
name: json['name'] as String,
|
||||
description: json['description'] as String,
|
||||
members: (json['members'] as List<dynamic>?)
|
||||
?.map((e) => SnRealmMember.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
avatar: json['avatar'] as String?,
|
||||
banner: json['banner'] as String?,
|
||||
accessPolicy: json['access_policy'] as Map<String, dynamic>?,
|
||||
isPublic: json['is_public'] as bool,
|
||||
isCommunity: json['is_community'] as bool,
|
||||
accountId: (json['account_id'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$SnRealmImplToJson(_$SnRealmImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||
'alias': instance.alias,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'members': instance.members?.map((e) => e.toJson()).toList(),
|
||||
'avatar': instance.avatar,
|
||||
'banner': instance.banner,
|
||||
'access_policy': instance.accessPolicy,
|
||||
'is_public': instance.isPublic,
|
||||
'is_community': instance.isCommunity,
|
||||
'account_id': instance.accountId,
|
||||
};
|
Reference in New Issue
Block a user