♻️ Use sqlite to replace hive #5
@ -13,7 +13,6 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
|
||||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -41,8 +40,6 @@ import 'package:surface/providers/userinfo.dart';
|
|||||||
import 'package:surface/providers/websocket.dart';
|
import 'package:surface/providers/websocket.dart';
|
||||||
import 'package:surface/providers/widget.dart';
|
import 'package:surface/providers/widget.dart';
|
||||||
import 'package:surface/router.dart';
|
import 'package:surface/router.dart';
|
||||||
import 'package:surface/types/chat.dart';
|
|
||||||
import 'package:surface/types/realm.dart';
|
|
||||||
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
|
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:tray_manager/tray_manager.dart';
|
import 'package:tray_manager/tray_manager.dart';
|
||||||
@ -83,12 +80,6 @@ void main() async {
|
|||||||
|
|
||||||
await EasyLocalization.ensureInitialized();
|
await EasyLocalization.ensureInitialized();
|
||||||
|
|
||||||
await Hive.initFlutter();
|
|
||||||
Hive.registerAdapter(SnChannelImplAdapter());
|
|
||||||
Hive.registerAdapter(SnRealmImplAdapter());
|
|
||||||
Hive.registerAdapter(SnChannelMemberImplAdapter());
|
|
||||||
Hive.registerAdapter(SnChatMessageImplAdapter());
|
|
||||||
|
|
||||||
if (!kIsWeb && !Platform.isLinux) {
|
if (!kIsWeb && !Platform.isLinux) {
|
||||||
await Firebase.initializeApp(
|
await Firebase.initializeApp(
|
||||||
options: DefaultFirebaseOptions.currentPlatform,
|
options: DefaultFirebaseOptions.currentPlatform,
|
||||||
@ -115,7 +106,8 @@ void main() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!kIsWeb && Platform.isAndroid) {
|
if (!kIsWeb && Platform.isAndroid) {
|
||||||
final ImagePickerPlatform imagePickerImplementation = ImagePickerPlatform.instance;
|
final ImagePickerPlatform imagePickerImplementation =
|
||||||
|
ImagePickerPlatform.instance;
|
||||||
if (imagePickerImplementation is ImagePickerAndroid) {
|
if (imagePickerImplementation is ImagePickerAndroid) {
|
||||||
imagePickerImplementation.useAndroidPhotoPicker = true;
|
imagePickerImplementation.useAndroidPhotoPicker = true;
|
||||||
}
|
}
|
||||||
@ -234,7 +226,8 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
if (prefs.containsKey('first_boot_time')) {
|
if (prefs.containsKey('first_boot_time')) {
|
||||||
final rawTime = prefs.getString('first_boot_time');
|
final rawTime = prefs.getString('first_boot_time');
|
||||||
final time = DateTime.tryParse(rawTime ?? '');
|
final time = DateTime.tryParse(rawTime ?? '');
|
||||||
if (time != null && time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
if (time != null &&
|
||||||
|
time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
||||||
final inAppReview = InAppReview.instance;
|
final inAppReview = InAppReview.instance;
|
||||||
if (prefs.getBool('rating_requested') == true) return;
|
if (prefs.getBool('rating_requested') == true) return;
|
||||||
if (await inAppReview.isAvailable()) {
|
if (await inAppReview.isAvailable()) {
|
||||||
@ -262,13 +255,18 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
).get(
|
).get(
|
||||||
'https://git.solsynth.dev/api/v1/repos/HyperNet/Surface/tags?page=1&limit=1',
|
'https://git.solsynth.dev/api/v1/repos/HyperNet/Surface/tags?page=1&limit=1',
|
||||||
);
|
);
|
||||||
final remoteVersionString = (resp.data as List).firstOrNull?['name'] ?? '0.0.0+0';
|
final remoteVersionString =
|
||||||
|
(resp.data as List).firstOrNull?['name'] ?? '0.0.0+0';
|
||||||
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
||||||
final localVersion = Version.parse(localVersionString.split('+').first);
|
final localVersion = Version.parse(localVersionString.split('+').first);
|
||||||
final remoteBuildNumber = int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
final remoteBuildNumber =
|
||||||
final localBuildNumber = int.tryParse(localVersionString.split('+').last) ?? 0;
|
int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
||||||
|
final localBuildNumber =
|
||||||
|
int.tryParse(localVersionString.split('+').last) ?? 0;
|
||||||
log("[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
log("[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
||||||
if ((remoteVersion > localVersion || remoteBuildNumber > localBuildNumber) && mounted) {
|
if ((remoteVersion > localVersion ||
|
||||||
|
remoteBuildNumber > localBuildNumber) &&
|
||||||
|
mounted) {
|
||||||
final config = context.read<ConfigProvider>();
|
final config = context.read<ConfigProvider>();
|
||||||
config.setUpdate(remoteVersionString);
|
config.setUpdate(remoteVersionString);
|
||||||
log("[Update] Update available: $remoteVersionString");
|
log("[Update] Update available: $remoteVersionString");
|
||||||
@ -335,7 +333,9 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
Future<void> _trayInitialization() async {
|
Future<void> _trayInitialization() async {
|
||||||
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
|
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
|
||||||
|
|
||||||
final icon = Platform.isWindows ? 'assets/icon/tray-icon.ico' : 'assets/icon/tray-icon.png';
|
final icon = Platform.isWindows
|
||||||
|
? 'assets/icon/tray-icon.ico'
|
||||||
|
: 'assets/icon/tray-icon.png';
|
||||||
final appVersion = await PackageInfo.fromPlatform();
|
final appVersion = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
trayManager.addListener(this);
|
trayManager.addListener(this);
|
||||||
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:surface/database/database.dart';
|
import 'package:surface/database/database.dart';
|
||||||
import 'package:surface/providers/database.dart';
|
import 'package:surface/providers/database.dart';
|
||||||
@ -22,11 +21,6 @@ class ChatChannelProvider extends ChangeNotifier {
|
|||||||
_sn = context.read<SnNetworkProvider>();
|
_sn = context.read<SnNetworkProvider>();
|
||||||
_ud = context.read<UserDirectoryProvider>();
|
_ud = context.read<UserDirectoryProvider>();
|
||||||
_dt = context.read<DatabaseProvider>();
|
_dt = context.read<DatabaseProvider>();
|
||||||
_initializeLocalData();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _initializeLocalData() async {
|
|
||||||
await Hive.openBox<SnChannel>(kChatChannelBoxName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveChannelToLocal(Iterable<SnChannel> channels) async {
|
Future<void> _saveChannelToLocal(Iterable<SnChannel> channels) async {
|
||||||
|
@ -4,10 +4,10 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hive_flutter/hive_flutter.dart';
|
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
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/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';
|
||||||
@ -45,7 +45,8 @@ class AccountScreen extends StatelessWidget {
|
|||||||
? Stack(
|
? Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
AutoResizeUniversalImage(sn.getAttachmentUrl(ua.user!.banner), fit: BoxFit.cover),
|
AutoResizeUniversalImage(sn.getAttachmentUrl(ua.user!.banner),
|
||||||
|
fit: BoxFit.cover),
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
@ -79,7 +80,9 @@ class AccountScreen extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: ua.isAuthorized ? _AuthorizedAccountScreen() : _UnauthorizedAccountScreen(),
|
child: ua.isAuthorized
|
||||||
|
? _AuthorizedAccountScreen()
|
||||||
|
: _UnauthorizedAccountScreen(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -115,12 +118,15 @@ class _AuthorizedAccountScreen extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||||
textBaseline: TextBaseline.alphabetic,
|
textBaseline: TextBaseline.alphabetic,
|
||||||
children: [
|
children: [
|
||||||
Text(ua.user!.nick).textStyle(Theme.of(context).textTheme.titleLarge!),
|
Text(ua.user!.nick)
|
||||||
|
.textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text('@${ua.user!.name}').textStyle(Theme.of(context).textTheme.bodySmall!),
|
Text('@${ua.user!.name}')
|
||||||
|
.textStyle(Theme.of(context).textTheme.bodySmall!),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Text(ua.user!.description).textStyle(Theme.of(context).textTheme.bodyMedium!),
|
Text(ua.user!.description)
|
||||||
|
.textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -193,8 +199,7 @@ class _AuthorizedAccountScreen extends StatelessWidget {
|
|||||||
ua.logoutUser();
|
ua.logoutUser();
|
||||||
final ws = context.read<WebSocketProvider>();
|
final ws = context.read<WebSocketProvider>();
|
||||||
ws.disconnect();
|
ws.disconnect();
|
||||||
await Hive.deleteFromDisk();
|
context.read<DatabaseProvider>().removeDatabase();
|
||||||
await Hive.initFlutter();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -220,7 +225,9 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
|
|||||||
child: Icon(Symbols.waving_hand, size: 28),
|
child: Icon(Symbols.waving_hand, size: 28),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Text('accountIntroTitle').tr().textStyle(Theme.of(context).textTheme.titleLarge!),
|
Text('accountIntroTitle')
|
||||||
|
.tr()
|
||||||
|
.textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||||
Text('accountIntroSubtitle').tr(),
|
Text('accountIntroSubtitle').tr(),
|
||||||
],
|
],
|
||||||
).padding(all: 20),
|
).padding(all: 20),
|
||||||
|
@ -9,7 +9,7 @@ class SnAccount with _$SnAccount {
|
|||||||
const SnAccount._();
|
const SnAccount._();
|
||||||
|
|
||||||
const factory SnAccount({
|
const factory SnAccount({
|
||||||
@HiveField(0) required int id,
|
required int id,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
|
@ -58,7 +58,7 @@ abstract class $SnAccountCopyWith<$Res> {
|
|||||||
_$SnAccountCopyWithImpl<$Res, SnAccount>;
|
_$SnAccountCopyWithImpl<$Res, SnAccount>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
DateTime createdAt,
|
DateTime createdAt,
|
||||||
DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@ -226,7 +226,7 @@ abstract class _$$SnAccountImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
DateTime createdAt,
|
DateTime createdAt,
|
||||||
DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@ -374,7 +374,7 @@ class __$$SnAccountImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$SnAccountImpl extends _SnAccount {
|
class _$SnAccountImpl extends _SnAccount {
|
||||||
const _$SnAccountImpl(
|
const _$SnAccountImpl(
|
||||||
{@HiveField(0) required this.id,
|
{required this.id,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.deletedAt,
|
required this.deletedAt,
|
||||||
@ -556,7 +556,7 @@ class _$SnAccountImpl extends _SnAccount {
|
|||||||
|
|
||||||
abstract class _SnAccount extends SnAccount {
|
abstract class _SnAccount extends SnAccount {
|
||||||
const factory _SnAccount(
|
const factory _SnAccount(
|
||||||
{@HiveField(0) required final int id,
|
{required final int id,
|
||||||
required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
required final DateTime updatedAt,
|
required final DateTime updatedAt,
|
||||||
required final DateTime? deletedAt,
|
required final DateTime? deletedAt,
|
||||||
|
@ -14,21 +14,21 @@ class SnChannel with _$SnChannel {
|
|||||||
|
|
||||||
@HiveType(typeId: 2)
|
@HiveType(typeId: 2)
|
||||||
const factory SnChannel({
|
const factory SnChannel({
|
||||||
@HiveField(0) required int id,
|
required int id,
|
||||||
@HiveField(1) required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
@HiveField(2) required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
@HiveField(3) required dynamic deletedAt,
|
required dynamic deletedAt,
|
||||||
@HiveField(4) required String alias,
|
required String alias,
|
||||||
@HiveField(5) required String name,
|
required String name,
|
||||||
@HiveField(6) required String description,
|
required String description,
|
||||||
@HiveField(7) required List<SnChannelMember>? members,
|
required List<SnChannelMember>? members,
|
||||||
List<SnChatMessage>? messages,
|
List<SnChatMessage>? messages,
|
||||||
@HiveField(8) required int type,
|
required int type,
|
||||||
@HiveField(9) required int accountId,
|
required int accountId,
|
||||||
@HiveField(10) required SnRealm? realm,
|
required SnRealm? realm,
|
||||||
@HiveField(11) required int? realmId,
|
required int? realmId,
|
||||||
@HiveField(12) required bool isPublic,
|
required bool isPublic,
|
||||||
@HiveField(13) required bool isCommunity,
|
required bool isCommunity,
|
||||||
}) = _SnChannel;
|
}) = _SnChannel;
|
||||||
|
|
||||||
factory SnChannel.fromJson(Map<String, dynamic> json) =>
|
factory SnChannel.fromJson(Map<String, dynamic> json) =>
|
||||||
@ -44,17 +44,17 @@ class SnChannelMember with _$SnChannelMember {
|
|||||||
|
|
||||||
@HiveType(typeId: 3)
|
@HiveType(typeId: 3)
|
||||||
const factory SnChannelMember({
|
const factory SnChannelMember({
|
||||||
@HiveField(0) required int id,
|
required int id,
|
||||||
@HiveField(1) required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
@HiveField(2) required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
@HiveField(3) required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@HiveField(4) required int channelId,
|
required int channelId,
|
||||||
@HiveField(5) required int accountId,
|
required int accountId,
|
||||||
@HiveField(6) required String? nick,
|
required String? nick,
|
||||||
@HiveField(7) required SnChannel? channel,
|
required SnChannel? channel,
|
||||||
@HiveField(8) required SnAccount? account,
|
required SnAccount? account,
|
||||||
@Default(0) int notify,
|
@Default(0) int notify,
|
||||||
@HiveField(9) required int powerLevel,
|
required int powerLevel,
|
||||||
dynamic calls,
|
dynamic calls,
|
||||||
dynamic events,
|
dynamic events,
|
||||||
}) = _SnChannelMember;
|
}) = _SnChannelMember;
|
||||||
@ -69,19 +69,19 @@ class SnChatMessage with _$SnChatMessage {
|
|||||||
|
|
||||||
@HiveType(typeId: 4)
|
@HiveType(typeId: 4)
|
||||||
const factory SnChatMessage({
|
const factory SnChatMessage({
|
||||||
@HiveField(0) required int id,
|
required int id,
|
||||||
@HiveField(1) required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
@HiveField(2) required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
@HiveField(3) required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@HiveField(4) required String uuid,
|
required String uuid,
|
||||||
@HiveField(5) @Default({}) Map<String, dynamic> body,
|
@Default({}) Map<String, dynamic> body,
|
||||||
@HiveField(6) required String type,
|
required String type,
|
||||||
@HiveField(7) required SnChannel channel,
|
required SnChannel channel,
|
||||||
@HiveField(8) required SnChannelMember sender,
|
required SnChannelMember sender,
|
||||||
@HiveField(9) required int channelId,
|
required int channelId,
|
||||||
@HiveField(10) required int senderId,
|
required int senderId,
|
||||||
@HiveField(11) required int? quoteEventId,
|
required int? quoteEventId,
|
||||||
@HiveField(12) required int? relatedEventId,
|
required int? relatedEventId,
|
||||||
SnChatMessagePreload? preload,
|
SnChatMessagePreload? preload,
|
||||||
}) = _SnChatMessage;
|
}) = _SnChatMessage;
|
||||||
|
|
||||||
|
@ -66,21 +66,21 @@ abstract class $SnChannelCopyWith<$Res> {
|
|||||||
_$SnChannelCopyWithImpl<$Res, SnChannel>;
|
_$SnChannelCopyWithImpl<$Res, SnChannel>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) dynamic deletedAt,
|
dynamic deletedAt,
|
||||||
@HiveField(4) String alias,
|
String alias,
|
||||||
@HiveField(5) String name,
|
String name,
|
||||||
@HiveField(6) String description,
|
String description,
|
||||||
@HiveField(7) List<SnChannelMember>? members,
|
List<SnChannelMember>? members,
|
||||||
List<SnChatMessage>? messages,
|
List<SnChatMessage>? messages,
|
||||||
@HiveField(8) int type,
|
int type,
|
||||||
@HiveField(9) int accountId,
|
int accountId,
|
||||||
@HiveField(10) SnRealm? realm,
|
SnRealm? realm,
|
||||||
@HiveField(11) int? realmId,
|
int? realmId,
|
||||||
@HiveField(12) bool isPublic,
|
bool isPublic,
|
||||||
@HiveField(13) bool isCommunity});
|
bool isCommunity});
|
||||||
|
|
||||||
$SnRealmCopyWith<$Res>? get realm;
|
$SnRealmCopyWith<$Res>? get realm;
|
||||||
}
|
}
|
||||||
@ -204,21 +204,21 @@ abstract class _$$SnChannelImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) dynamic deletedAt,
|
dynamic deletedAt,
|
||||||
@HiveField(4) String alias,
|
String alias,
|
||||||
@HiveField(5) String name,
|
String name,
|
||||||
@HiveField(6) String description,
|
String description,
|
||||||
@HiveField(7) List<SnChannelMember>? members,
|
List<SnChannelMember>? members,
|
||||||
List<SnChatMessage>? messages,
|
List<SnChatMessage>? messages,
|
||||||
@HiveField(8) int type,
|
int type,
|
||||||
@HiveField(9) int accountId,
|
int accountId,
|
||||||
@HiveField(10) SnRealm? realm,
|
SnRealm? realm,
|
||||||
@HiveField(11) int? realmId,
|
int? realmId,
|
||||||
@HiveField(12) bool isPublic,
|
bool isPublic,
|
||||||
@HiveField(13) bool isCommunity});
|
bool isCommunity});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$SnRealmCopyWith<$Res>? get realm;
|
$SnRealmCopyWith<$Res>? get realm;
|
||||||
@ -323,21 +323,21 @@ class __$$SnChannelImplCopyWithImpl<$Res>
|
|||||||
@HiveType(typeId: 2)
|
@HiveType(typeId: 2)
|
||||||
class _$SnChannelImpl extends _SnChannel {
|
class _$SnChannelImpl extends _SnChannel {
|
||||||
const _$SnChannelImpl(
|
const _$SnChannelImpl(
|
||||||
{@HiveField(0) required this.id,
|
{required this.id,
|
||||||
@HiveField(1) required this.createdAt,
|
required this.createdAt,
|
||||||
@HiveField(2) required this.updatedAt,
|
required this.updatedAt,
|
||||||
@HiveField(3) required this.deletedAt,
|
required this.deletedAt,
|
||||||
@HiveField(4) required this.alias,
|
required this.alias,
|
||||||
@HiveField(5) required this.name,
|
required this.name,
|
||||||
@HiveField(6) required this.description,
|
required this.description,
|
||||||
@HiveField(7) required final List<SnChannelMember>? members,
|
required final List<SnChannelMember>? members,
|
||||||
final List<SnChatMessage>? messages,
|
final List<SnChatMessage>? messages,
|
||||||
@HiveField(8) required this.type,
|
required this.type,
|
||||||
@HiveField(9) required this.accountId,
|
required this.accountId,
|
||||||
@HiveField(10) required this.realm,
|
required this.realm,
|
||||||
@HiveField(11) required this.realmId,
|
required this.realmId,
|
||||||
@HiveField(12) required this.isPublic,
|
required this.isPublic,
|
||||||
@HiveField(13) required this.isCommunity})
|
required this.isCommunity})
|
||||||
: _members = members,
|
: _members = members,
|
||||||
_messages = messages,
|
_messages = messages,
|
||||||
super._();
|
super._();
|
||||||
@ -477,21 +477,21 @@ class _$SnChannelImpl extends _SnChannel {
|
|||||||
|
|
||||||
abstract class _SnChannel extends SnChannel {
|
abstract class _SnChannel extends SnChannel {
|
||||||
const factory _SnChannel(
|
const factory _SnChannel(
|
||||||
{@HiveField(0) required final int id,
|
{required final int id,
|
||||||
@HiveField(1) required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
@HiveField(2) required final DateTime updatedAt,
|
required final DateTime updatedAt,
|
||||||
@HiveField(3) required final dynamic deletedAt,
|
required final dynamic deletedAt,
|
||||||
@HiveField(4) required final String alias,
|
required final String alias,
|
||||||
@HiveField(5) required final String name,
|
required final String name,
|
||||||
@HiveField(6) required final String description,
|
required final String description,
|
||||||
@HiveField(7) required final List<SnChannelMember>? members,
|
required final List<SnChannelMember>? members,
|
||||||
final List<SnChatMessage>? messages,
|
final List<SnChatMessage>? messages,
|
||||||
@HiveField(8) required final int type,
|
required final int type,
|
||||||
@HiveField(9) required final int accountId,
|
required final int accountId,
|
||||||
@HiveField(10) required final SnRealm? realm,
|
required final SnRealm? realm,
|
||||||
@HiveField(11) required final int? realmId,
|
required final int? realmId,
|
||||||
@HiveField(12) required final bool isPublic,
|
required final bool isPublic,
|
||||||
@HiveField(13) required final bool isCommunity}) = _$SnChannelImpl;
|
required final bool isCommunity}) = _$SnChannelImpl;
|
||||||
const _SnChannel._() : super._();
|
const _SnChannel._() : super._();
|
||||||
|
|
||||||
factory _SnChannel.fromJson(Map<String, dynamic> json) =
|
factory _SnChannel.fromJson(Map<String, dynamic> json) =
|
||||||
@ -597,17 +597,17 @@ abstract class $SnChannelMemberCopyWith<$Res> {
|
|||||||
_$SnChannelMemberCopyWithImpl<$Res, SnChannelMember>;
|
_$SnChannelMemberCopyWithImpl<$Res, SnChannelMember>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) int channelId,
|
int channelId,
|
||||||
@HiveField(5) int accountId,
|
int accountId,
|
||||||
@HiveField(6) String? nick,
|
String? nick,
|
||||||
@HiveField(7) SnChannel? channel,
|
SnChannel? channel,
|
||||||
@HiveField(8) SnAccount? account,
|
SnAccount? account,
|
||||||
int notify,
|
int notify,
|
||||||
@HiveField(9) int powerLevel,
|
int powerLevel,
|
||||||
dynamic calls,
|
dynamic calls,
|
||||||
dynamic events});
|
dynamic events});
|
||||||
|
|
||||||
@ -738,17 +738,17 @@ abstract class _$$SnChannelMemberImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) int channelId,
|
int channelId,
|
||||||
@HiveField(5) int accountId,
|
int accountId,
|
||||||
@HiveField(6) String? nick,
|
String? nick,
|
||||||
@HiveField(7) SnChannel? channel,
|
SnChannel? channel,
|
||||||
@HiveField(8) SnAccount? account,
|
SnAccount? account,
|
||||||
int notify,
|
int notify,
|
||||||
@HiveField(9) int powerLevel,
|
int powerLevel,
|
||||||
dynamic calls,
|
dynamic calls,
|
||||||
dynamic events});
|
dynamic events});
|
||||||
|
|
||||||
@ -847,17 +847,17 @@ class __$$SnChannelMemberImplCopyWithImpl<$Res>
|
|||||||
@HiveType(typeId: 3)
|
@HiveType(typeId: 3)
|
||||||
class _$SnChannelMemberImpl extends _SnChannelMember {
|
class _$SnChannelMemberImpl extends _SnChannelMember {
|
||||||
const _$SnChannelMemberImpl(
|
const _$SnChannelMemberImpl(
|
||||||
{@HiveField(0) required this.id,
|
{required this.id,
|
||||||
@HiveField(1) required this.createdAt,
|
required this.createdAt,
|
||||||
@HiveField(2) required this.updatedAt,
|
required this.updatedAt,
|
||||||
@HiveField(3) required this.deletedAt,
|
required this.deletedAt,
|
||||||
@HiveField(4) required this.channelId,
|
required this.channelId,
|
||||||
@HiveField(5) required this.accountId,
|
required this.accountId,
|
||||||
@HiveField(6) required this.nick,
|
required this.nick,
|
||||||
@HiveField(7) required this.channel,
|
required this.channel,
|
||||||
@HiveField(8) required this.account,
|
required this.account,
|
||||||
this.notify = 0,
|
this.notify = 0,
|
||||||
@HiveField(9) required this.powerLevel,
|
required this.powerLevel,
|
||||||
this.calls,
|
this.calls,
|
||||||
this.events})
|
this.events})
|
||||||
: super._();
|
: super._();
|
||||||
@ -971,17 +971,17 @@ class _$SnChannelMemberImpl extends _SnChannelMember {
|
|||||||
|
|
||||||
abstract class _SnChannelMember extends SnChannelMember {
|
abstract class _SnChannelMember extends SnChannelMember {
|
||||||
const factory _SnChannelMember(
|
const factory _SnChannelMember(
|
||||||
{@HiveField(0) required final int id,
|
{required final int id,
|
||||||
@HiveField(1) required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
@HiveField(2) required final DateTime updatedAt,
|
required final DateTime updatedAt,
|
||||||
@HiveField(3) required final DateTime? deletedAt,
|
required final DateTime? deletedAt,
|
||||||
@HiveField(4) required final int channelId,
|
required final int channelId,
|
||||||
@HiveField(5) required final int accountId,
|
required final int accountId,
|
||||||
@HiveField(6) required final String? nick,
|
required final String? nick,
|
||||||
@HiveField(7) required final SnChannel? channel,
|
required final SnChannel? channel,
|
||||||
@HiveField(8) required final SnAccount? account,
|
required final SnAccount? account,
|
||||||
final int notify,
|
final int notify,
|
||||||
@HiveField(9) required final int powerLevel,
|
required final int powerLevel,
|
||||||
final dynamic calls,
|
final dynamic calls,
|
||||||
final dynamic events}) = _$SnChannelMemberImpl;
|
final dynamic events}) = _$SnChannelMemberImpl;
|
||||||
const _SnChannelMember._() : super._();
|
const _SnChannelMember._() : super._();
|
||||||
@ -1085,19 +1085,19 @@ abstract class $SnChatMessageCopyWith<$Res> {
|
|||||||
_$SnChatMessageCopyWithImpl<$Res, SnChatMessage>;
|
_$SnChatMessageCopyWithImpl<$Res, SnChatMessage>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) String uuid,
|
String uuid,
|
||||||
@HiveField(5) Map<String, dynamic> body,
|
Map<String, dynamic> body,
|
||||||
@HiveField(6) String type,
|
String type,
|
||||||
@HiveField(7) SnChannel channel,
|
SnChannel channel,
|
||||||
@HiveField(8) SnChannelMember sender,
|
SnChannelMember sender,
|
||||||
@HiveField(9) int channelId,
|
int channelId,
|
||||||
@HiveField(10) int senderId,
|
int senderId,
|
||||||
@HiveField(11) int? quoteEventId,
|
int? quoteEventId,
|
||||||
@HiveField(12) int? relatedEventId,
|
int? relatedEventId,
|
||||||
SnChatMessagePreload? preload});
|
SnChatMessagePreload? preload});
|
||||||
|
|
||||||
$SnChannelCopyWith<$Res> get channel;
|
$SnChannelCopyWith<$Res> get channel;
|
||||||
@ -1239,19 +1239,19 @@ abstract class _$$SnChatMessageImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) String uuid,
|
String uuid,
|
||||||
@HiveField(5) Map<String, dynamic> body,
|
Map<String, dynamic> body,
|
||||||
@HiveField(6) String type,
|
String type,
|
||||||
@HiveField(7) SnChannel channel,
|
SnChannel channel,
|
||||||
@HiveField(8) SnChannelMember sender,
|
SnChannelMember sender,
|
||||||
@HiveField(9) int channelId,
|
int channelId,
|
||||||
@HiveField(10) int senderId,
|
int senderId,
|
||||||
@HiveField(11) int? quoteEventId,
|
int? quoteEventId,
|
||||||
@HiveField(12) int? relatedEventId,
|
int? relatedEventId,
|
||||||
SnChatMessagePreload? preload});
|
SnChatMessagePreload? preload});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1356,19 +1356,19 @@ class __$$SnChatMessageImplCopyWithImpl<$Res>
|
|||||||
@HiveType(typeId: 4)
|
@HiveType(typeId: 4)
|
||||||
class _$SnChatMessageImpl extends _SnChatMessage {
|
class _$SnChatMessageImpl extends _SnChatMessage {
|
||||||
const _$SnChatMessageImpl(
|
const _$SnChatMessageImpl(
|
||||||
{@HiveField(0) required this.id,
|
{required this.id,
|
||||||
@HiveField(1) required this.createdAt,
|
required this.createdAt,
|
||||||
@HiveField(2) required this.updatedAt,
|
required this.updatedAt,
|
||||||
@HiveField(3) required this.deletedAt,
|
required this.deletedAt,
|
||||||
@HiveField(4) required this.uuid,
|
required this.uuid,
|
||||||
@HiveField(5) final Map<String, dynamic> body = const {},
|
final Map<String, dynamic> body = const {},
|
||||||
@HiveField(6) required this.type,
|
required this.type,
|
||||||
@HiveField(7) required this.channel,
|
required this.channel,
|
||||||
@HiveField(8) required this.sender,
|
required this.sender,
|
||||||
@HiveField(9) required this.channelId,
|
required this.channelId,
|
||||||
@HiveField(10) required this.senderId,
|
required this.senderId,
|
||||||
@HiveField(11) required this.quoteEventId,
|
required this.quoteEventId,
|
||||||
@HiveField(12) required this.relatedEventId,
|
required this.relatedEventId,
|
||||||
this.preload})
|
this.preload})
|
||||||
: _body = body,
|
: _body = body,
|
||||||
super._();
|
super._();
|
||||||
@ -1495,19 +1495,19 @@ class _$SnChatMessageImpl extends _SnChatMessage {
|
|||||||
|
|
||||||
abstract class _SnChatMessage extends SnChatMessage {
|
abstract class _SnChatMessage extends SnChatMessage {
|
||||||
const factory _SnChatMessage(
|
const factory _SnChatMessage(
|
||||||
{@HiveField(0) required final int id,
|
{required final int id,
|
||||||
@HiveField(1) required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
@HiveField(2) required final DateTime updatedAt,
|
required final DateTime updatedAt,
|
||||||
@HiveField(3) required final DateTime? deletedAt,
|
required final DateTime? deletedAt,
|
||||||
@HiveField(4) required final String uuid,
|
required final String uuid,
|
||||||
@HiveField(5) final Map<String, dynamic> body,
|
final Map<String, dynamic> body,
|
||||||
@HiveField(6) required final String type,
|
required final String type,
|
||||||
@HiveField(7) required final SnChannel channel,
|
required final SnChannel channel,
|
||||||
@HiveField(8) required final SnChannelMember sender,
|
required final SnChannelMember sender,
|
||||||
@HiveField(9) required final int channelId,
|
required final int channelId,
|
||||||
@HiveField(10) required final int senderId,
|
required final int senderId,
|
||||||
@HiveField(11) required final int? quoteEventId,
|
required final int? quoteEventId,
|
||||||
@HiveField(12) required final int? relatedEventId,
|
required final int? relatedEventId,
|
||||||
final SnChatMessagePreload? preload}) = _$SnChatMessageImpl;
|
final SnChatMessagePreload? preload}) = _$SnChatMessageImpl;
|
||||||
const _SnChatMessage._() : super._();
|
const _SnChatMessage._() : super._();
|
||||||
|
|
||||||
|
@ -29,20 +29,20 @@ class SnRealm with _$SnRealm {
|
|||||||
|
|
||||||
@HiveType(typeId: 1)
|
@HiveType(typeId: 1)
|
||||||
const factory SnRealm({
|
const factory SnRealm({
|
||||||
@HiveField(0) required int id,
|
required int id,
|
||||||
@HiveField(1) required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
@HiveField(2) required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
@HiveField(3) required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@HiveField(4) required String alias,
|
required String alias,
|
||||||
@HiveField(5) required String name,
|
required String name,
|
||||||
@HiveField(6) required String description,
|
required String description,
|
||||||
List<SnRealmMember>? members,
|
List<SnRealmMember>? members,
|
||||||
@HiveField(7) required String? avatar,
|
required String? avatar,
|
||||||
@HiveField(8) required String? banner,
|
required String? banner,
|
||||||
@HiveField(9) required Map<String, dynamic>? accessPolicy,
|
required Map<String, dynamic>? accessPolicy,
|
||||||
@HiveField(10) required int accountId,
|
required int accountId,
|
||||||
@HiveField(11) required bool isPublic,
|
required bool isPublic,
|
||||||
@HiveField(12) required bool isCommunity,
|
required bool isCommunity,
|
||||||
@Default(0) int popularity,
|
@Default(0) int popularity,
|
||||||
}) = _SnRealm;
|
}) = _SnRealm;
|
||||||
|
|
||||||
|
@ -411,20 +411,20 @@ abstract class $SnRealmCopyWith<$Res> {
|
|||||||
_$SnRealmCopyWithImpl<$Res, SnRealm>;
|
_$SnRealmCopyWithImpl<$Res, SnRealm>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) String alias,
|
String alias,
|
||||||
@HiveField(5) String name,
|
String name,
|
||||||
@HiveField(6) String description,
|
String description,
|
||||||
List<SnRealmMember>? members,
|
List<SnRealmMember>? members,
|
||||||
@HiveField(7) String? avatar,
|
String? avatar,
|
||||||
@HiveField(8) String? banner,
|
String? banner,
|
||||||
@HiveField(9) Map<String, dynamic>? accessPolicy,
|
Map<String, dynamic>? accessPolicy,
|
||||||
@HiveField(10) int accountId,
|
int accountId,
|
||||||
@HiveField(11) bool isPublic,
|
bool isPublic,
|
||||||
@HiveField(12) bool isCommunity,
|
bool isCommunity,
|
||||||
int popularity});
|
int popularity});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,20 +532,20 @@ abstract class _$$SnRealmImplCopyWith<$Res> implements $SnRealmCopyWith<$Res> {
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@HiveField(0) int id,
|
{int id,
|
||||||
@HiveField(1) DateTime createdAt,
|
DateTime createdAt,
|
||||||
@HiveField(2) DateTime updatedAt,
|
DateTime updatedAt,
|
||||||
@HiveField(3) DateTime? deletedAt,
|
DateTime? deletedAt,
|
||||||
@HiveField(4) String alias,
|
String alias,
|
||||||
@HiveField(5) String name,
|
String name,
|
||||||
@HiveField(6) String description,
|
String description,
|
||||||
List<SnRealmMember>? members,
|
List<SnRealmMember>? members,
|
||||||
@HiveField(7) String? avatar,
|
String? avatar,
|
||||||
@HiveField(8) String? banner,
|
String? banner,
|
||||||
@HiveField(9) Map<String, dynamic>? accessPolicy,
|
Map<String, dynamic>? accessPolicy,
|
||||||
@HiveField(10) int accountId,
|
int accountId,
|
||||||
@HiveField(11) bool isPublic,
|
bool isPublic,
|
||||||
@HiveField(12) bool isCommunity,
|
bool isCommunity,
|
||||||
int popularity});
|
int popularity});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,20 +648,20 @@ class __$$SnRealmImplCopyWithImpl<$Res>
|
|||||||
@HiveType(typeId: 1)
|
@HiveType(typeId: 1)
|
||||||
class _$SnRealmImpl extends _SnRealm {
|
class _$SnRealmImpl extends _SnRealm {
|
||||||
const _$SnRealmImpl(
|
const _$SnRealmImpl(
|
||||||
{@HiveField(0) required this.id,
|
{required this.id,
|
||||||
@HiveField(1) required this.createdAt,
|
required this.createdAt,
|
||||||
@HiveField(2) required this.updatedAt,
|
required this.updatedAt,
|
||||||
@HiveField(3) required this.deletedAt,
|
required this.deletedAt,
|
||||||
@HiveField(4) required this.alias,
|
required this.alias,
|
||||||
@HiveField(5) required this.name,
|
required this.name,
|
||||||
@HiveField(6) required this.description,
|
required this.description,
|
||||||
final List<SnRealmMember>? members,
|
final List<SnRealmMember>? members,
|
||||||
@HiveField(7) required this.avatar,
|
required this.avatar,
|
||||||
@HiveField(8) required this.banner,
|
required this.banner,
|
||||||
@HiveField(9) required final Map<String, dynamic>? accessPolicy,
|
required final Map<String, dynamic>? accessPolicy,
|
||||||
@HiveField(10) required this.accountId,
|
required this.accountId,
|
||||||
@HiveField(11) required this.isPublic,
|
required this.isPublic,
|
||||||
@HiveField(12) required this.isCommunity,
|
required this.isCommunity,
|
||||||
this.popularity = 0})
|
this.popularity = 0})
|
||||||
: _members = members,
|
: _members = members,
|
||||||
_accessPolicy = accessPolicy,
|
_accessPolicy = accessPolicy,
|
||||||
@ -805,20 +805,20 @@ class _$SnRealmImpl extends _SnRealm {
|
|||||||
|
|
||||||
abstract class _SnRealm extends SnRealm {
|
abstract class _SnRealm extends SnRealm {
|
||||||
const factory _SnRealm(
|
const factory _SnRealm(
|
||||||
{@HiveField(0) required final int id,
|
{required final int id,
|
||||||
@HiveField(1) required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
@HiveField(2) required final DateTime updatedAt,
|
required final DateTime updatedAt,
|
||||||
@HiveField(3) required final DateTime? deletedAt,
|
required final DateTime? deletedAt,
|
||||||
@HiveField(4) required final String alias,
|
required final String alias,
|
||||||
@HiveField(5) required final String name,
|
required final String name,
|
||||||
@HiveField(6) required final String description,
|
required final String description,
|
||||||
final List<SnRealmMember>? members,
|
final List<SnRealmMember>? members,
|
||||||
@HiveField(7) required final String? avatar,
|
required final String? avatar,
|
||||||
@HiveField(8) required final String? banner,
|
required final String? banner,
|
||||||
@HiveField(9) required final Map<String, dynamic>? accessPolicy,
|
required final Map<String, dynamic>? accessPolicy,
|
||||||
@HiveField(10) required final int accountId,
|
required final int accountId,
|
||||||
@HiveField(11) required final bool isPublic,
|
required final bool isPublic,
|
||||||
@HiveField(12) required final bool isCommunity,
|
required final bool isCommunity,
|
||||||
final int popularity}) = _$SnRealmImpl;
|
final int popularity}) = _$SnRealmImpl;
|
||||||
const _SnRealm._() : super._();
|
const _SnRealm._() : super._();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user