From 2e37582b45554a42b86e41e28146bd29d1bc283b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 4 May 2025 23:07:36 +0800 Subject: [PATCH] :sparkles: Realm detail page --- assets/i18n/en-US.json | 5 +- lib/models/realm.dart | 19 ++ lib/models/realm.freezed.dart | 205 +++++++++++++++ lib/models/realm.g.dart | 38 +++ lib/route.dart | 1 + lib/route.gr.dart | 220 ++++++++++------- lib/screens/chat/room_detail.dart | 53 ++-- lib/screens/realm/detail.dart | 397 ++++++++++++++++++++++++++++++ lib/screens/realm/detail.g.dart | 152 ++++++++++++ lib/screens/realm/realms.dart | 49 +--- 10 files changed, 975 insertions(+), 164 deletions(-) create mode 100644 lib/screens/realm/detail.dart create mode 100644 lib/screens/realm/detail.g.dart diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index 368732b..3d02698 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -63,7 +63,7 @@ "createRealm": "Create a Realm", "createRealmHint": "Meet friends with same interests, build communities, and more.", "editRealm": "Edit Realm", - "deleteRealm": "Delete Realm {}", + "deleteRealm": "Delete Realm", "deleteRealmHint": "Are you sure to delete this realm? This will also deleted all the channels, publishers, and posts under this realm.", "explore": "Explore", "account": "Account", @@ -74,6 +74,7 @@ "createChatRoom": "Create a Room", "editChatRoom": "Edit Room", "deleteChatRoom": "Delete Room", + "deleteChatRoomHint": "Are you sure to delete this room? This action cannot be undone.", "chat": "Chat", "chatMessageHint": "Message in {}", "chatDirectMessageHint": "Message to {}", @@ -81,7 +82,7 @@ "descriptionNone": "No description yet.", "invites": "Invites", "invitesEmpty": "No invites yet, such a lonely person...", - "chatMembers": { + "members": { "one": "{} member", "other": "{} members" }, diff --git a/lib/models/realm.dart b/lib/models/realm.dart index 34a6b7e..53e58bc 100644 --- a/lib/models/realm.dart +++ b/lib/models/realm.dart @@ -1,5 +1,6 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:island/models/file.dart'; +import 'package:island/models/user.dart'; part 'realm.freezed.dart'; part 'realm.g.dart'; @@ -28,3 +29,21 @@ abstract class SnRealm with _$SnRealm { factory SnRealm.fromJson(Map json) => _$SnRealmFromJson(json); } + +@freezed +abstract class SnRealmMember with _$SnRealmMember { + const factory SnRealmMember({ + required int realmId, + required SnRealm? realm, + required int accountId, + required SnAccount? account, + required int role, + required DateTime? joinedAt, + required DateTime createdAt, + required DateTime updatedAt, + required DateTime? deletedAt, + }) = _SnRealmMember; + + factory SnRealmMember.fromJson(Map json) => + _$SnRealmMemberFromJson(json); +} diff --git a/lib/models/realm.freezed.dart b/lib/models/realm.freezed.dart index ed12b2a..a38ba3d 100644 --- a/lib/models/realm.freezed.dart +++ b/lib/models/realm.freezed.dart @@ -238,4 +238,209 @@ $SnCloudFileCopyWith<$Res>? get background { } } + +/// @nodoc +mixin _$SnRealmMember { + + int get realmId; SnRealm? get realm; int get accountId; SnAccount? get account; int get role; DateTime? get joinedAt; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; +/// Create a copy of SnRealmMember +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnRealmMemberCopyWith get copyWith => _$SnRealmMemberCopyWithImpl(this as SnRealmMember, _$identity); + + /// Serializes this SnRealmMember to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $SnRealmMemberCopyWith<$Res> { + factory $SnRealmMemberCopyWith(SnRealmMember value, $Res Function(SnRealmMember) _then) = _$SnRealmMemberCopyWithImpl; +@useResult +$Res call({ + int realmId, SnRealm? realm, int accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + +$SnRealmCopyWith<$Res>? get realm;$SnAccountCopyWith<$Res>? get account; + +} +/// @nodoc +class _$SnRealmMemberCopyWithImpl<$Res> + implements $SnRealmMemberCopyWith<$Res> { + _$SnRealmMemberCopyWithImpl(this._self, this._then); + + final SnRealmMember _self; + final $Res Function(SnRealmMember) _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? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_self.copyWith( +realmId: null == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable +as int,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable +as SnRealm?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable +as int,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable +as SnAccount?,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} +/// 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 { + if (_self.realm == null) { + return null; + } + + return $SnRealmCopyWith<$Res>(_self.realm!, (value) { + return _then(_self.copyWith(realm: value)); + }); +}/// 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 { + if (_self.account == null) { + return null; + } + + return $SnAccountCopyWith<$Res>(_self.account!, (value) { + return _then(_self.copyWith(account: value)); + }); +} +} + + +/// @nodoc +@JsonSerializable() + +class _SnRealmMember implements SnRealmMember { + const _SnRealmMember({required this.realmId, required this.realm, required this.accountId, required this.account, required this.role, required this.joinedAt, required this.createdAt, required this.updatedAt, required this.deletedAt}); + factory _SnRealmMember.fromJson(Map json) => _$SnRealmMemberFromJson(json); + +@override final int realmId; +@override final SnRealm? realm; +@override final int accountId; +@override final SnAccount? account; +@override final int role; +@override final DateTime? joinedAt; +@override final DateTime createdAt; +@override final DateTime updatedAt; +@override final DateTime? deletedAt; + +/// Create a copy of SnRealmMember +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnRealmMemberCopyWith<_SnRealmMember> get copyWith => __$SnRealmMemberCopyWithImpl<_SnRealmMember>(this, _$identity); + +@override +Map toJson() { + return _$SnRealmMemberToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnRealmMemberCopyWith<$Res> implements $SnRealmMemberCopyWith<$Res> { + factory _$SnRealmMemberCopyWith(_SnRealmMember value, $Res Function(_SnRealmMember) _then) = __$SnRealmMemberCopyWithImpl; +@override @useResult +$Res call({ + int realmId, SnRealm? realm, int accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + +@override $SnRealmCopyWith<$Res>? get realm;@override $SnAccountCopyWith<$Res>? get account; + +} +/// @nodoc +class __$SnRealmMemberCopyWithImpl<$Res> + implements _$SnRealmMemberCopyWith<$Res> { + __$SnRealmMemberCopyWithImpl(this._self, this._then); + + final _SnRealmMember _self; + final $Res Function(_SnRealmMember) _then; + +/// Create a copy of SnRealmMember +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_SnRealmMember( +realmId: null == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable +as int,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable +as SnRealm?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable +as int,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable +as SnAccount?,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable +as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} + +/// 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 { + if (_self.realm == null) { + return null; + } + + return $SnRealmCopyWith<$Res>(_self.realm!, (value) { + return _then(_self.copyWith(realm: value)); + }); +}/// 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 { + if (_self.account == null) { + return null; + } + + return $SnAccountCopyWith<$Res>(_self.account!, (value) { + return _then(_self.copyWith(account: value)); + }); +} +} + // dart format on diff --git a/lib/models/realm.g.dart b/lib/models/realm.g.dart index 9b3834f..2085358 100644 --- a/lib/models/realm.g.dart +++ b/lib/models/realm.g.dart @@ -55,3 +55,41 @@ Map _$SnRealmToJson(_SnRealm instance) => { 'updated_at': instance.updatedAt.toIso8601String(), 'deleted_at': instance.deletedAt?.toIso8601String(), }; + +_SnRealmMember _$SnRealmMemberFromJson(Map json) => + _SnRealmMember( + realmId: (json['realm_id'] as num).toInt(), + realm: + json['realm'] == null + ? null + : SnRealm.fromJson(json['realm'] as Map), + accountId: (json['account_id'] as num).toInt(), + account: + json['account'] == null + ? null + : SnAccount.fromJson(json['account'] as Map), + role: (json['role'] as num).toInt(), + joinedAt: + json['joined_at'] == null + ? null + : DateTime.parse(json['joined_at'] as String), + 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), + ); + +Map _$SnRealmMemberToJson(_SnRealmMember instance) => + { + 'realm_id': instance.realmId, + 'realm': instance.realm?.toJson(), + 'account_id': instance.accountId, + 'account': instance.account?.toJson(), + 'role': instance.role, + 'joined_at': instance.joinedAt?.toIso8601String(), + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt?.toIso8601String(), + }; diff --git a/lib/route.dart b/lib/route.dart index 12ae600..dc56694 100644 --- a/lib/route.dart +++ b/lib/route.dart @@ -33,6 +33,7 @@ class AppRouter extends RootStackRouter { AutoRoute(page: PostDetailRoute.page, path: '/posts/:id'), AutoRoute(page: PostEditRoute.page, path: '/posts/:id/edit'), AutoRoute(page: NewRealmRoute.page, path: '/realms/new'), + AutoRoute(page: RealmDetailRoute.page, path: '/realms/:slug'), AutoRoute(page: EditRealmRoute.page, path: '/realms/:slug/edit'), AutoRoute(page: NewChatRoute.page, path: '/chat/new'), AutoRoute(page: EditChatRoute.page, path: '/chat/:id/edit'), diff --git a/lib/route.gr.dart b/lib/route.gr.dart index ec049b8..40ccf8c 100644 --- a/lib/route.gr.dart +++ b/lib/route.gr.dart @@ -9,33 +9,34 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i15; -import 'package:flutter/material.dart' as _i16; -import 'package:island/models/post.dart' as _i17; +import 'package:auto_route/auto_route.dart' as _i16; +import 'package:flutter/material.dart' as _i17; +import 'package:island/models/post.dart' as _i18; import 'package:island/screens/account.dart' as _i1; import 'package:island/screens/account/me.dart' as _i10; import 'package:island/screens/account/me/publishers.dart' as _i6; -import 'package:island/screens/account/me/update.dart' as _i14; +import 'package:island/screens/account/me/update.dart' as _i15; import 'package:island/screens/auth/create_account.dart' as _i5; import 'package:island/screens/auth/login.dart' as _i9; -import 'package:island/screens/auth/tabs.dart' as _i13; +import 'package:island/screens/auth/tabs.dart' as _i14; import 'package:island/screens/chat/chat.dart' as _i3; import 'package:island/screens/chat/room.dart' as _i4; import 'package:island/screens/chat/room_detail.dart' as _i2; import 'package:island/screens/explore.dart' as _i8; import 'package:island/screens/posts/compose.dart' as _i11; import 'package:island/screens/posts/detail.dart' as _i12; +import 'package:island/screens/realm/detail.dart' as _i13; import 'package:island/screens/realm/realms.dart' as _i7; /// generated route for /// [_i1.AccountScreen] -class AccountRoute extends _i15.PageRouteInfo { - const AccountRoute({List<_i15.PageRouteInfo>? children}) +class AccountRoute extends _i16.PageRouteInfo { + const AccountRoute({List<_i16.PageRouteInfo>? children}) : super(AccountRoute.name, initialChildren: children); static const String name = 'AccountRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i1.AccountScreen(); @@ -45,11 +46,11 @@ class AccountRoute extends _i15.PageRouteInfo { /// generated route for /// [_i2.ChatDetailScreen] -class ChatDetailRoute extends _i15.PageRouteInfo { +class ChatDetailRoute extends _i16.PageRouteInfo { ChatDetailRoute({ - _i16.Key? key, + _i17.Key? key, required int id, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( ChatDetailRoute.name, args: ChatDetailRouteArgs(key: key, id: id), @@ -59,7 +60,7 @@ class ChatDetailRoute extends _i15.PageRouteInfo { static const String name = 'ChatDetailRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -74,7 +75,7 @@ class ChatDetailRoute extends _i15.PageRouteInfo { class ChatDetailRouteArgs { const ChatDetailRouteArgs({this.key, required this.id}); - final _i16.Key? key; + final _i17.Key? key; final int id; @@ -86,13 +87,13 @@ class ChatDetailRouteArgs { /// generated route for /// [_i3.ChatListScreen] -class ChatListRoute extends _i15.PageRouteInfo { - const ChatListRoute({List<_i15.PageRouteInfo>? children}) +class ChatListRoute extends _i16.PageRouteInfo { + const ChatListRoute({List<_i16.PageRouteInfo>? children}) : super(ChatListRoute.name, initialChildren: children); static const String name = 'ChatListRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i3.ChatListScreen(); @@ -102,11 +103,11 @@ class ChatListRoute extends _i15.PageRouteInfo { /// generated route for /// [_i4.ChatRoomScreen] -class ChatRoomRoute extends _i15.PageRouteInfo { +class ChatRoomRoute extends _i16.PageRouteInfo { ChatRoomRoute({ - _i16.Key? key, + _i17.Key? key, required int id, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( ChatRoomRoute.name, args: ChatRoomRouteArgs(key: key, id: id), @@ -116,7 +117,7 @@ class ChatRoomRoute extends _i15.PageRouteInfo { static const String name = 'ChatRoomRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -131,7 +132,7 @@ class ChatRoomRoute extends _i15.PageRouteInfo { class ChatRoomRouteArgs { const ChatRoomRouteArgs({this.key, required this.id}); - final _i16.Key? key; + final _i17.Key? key; final int id; @@ -143,13 +144,13 @@ class ChatRoomRouteArgs { /// generated route for /// [_i5.CreateAccountScreen] -class CreateAccountRoute extends _i15.PageRouteInfo { - const CreateAccountRoute({List<_i15.PageRouteInfo>? children}) +class CreateAccountRoute extends _i16.PageRouteInfo { + const CreateAccountRoute({List<_i16.PageRouteInfo>? children}) : super(CreateAccountRoute.name, initialChildren: children); static const String name = 'CreateAccountRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i5.CreateAccountScreen(); @@ -159,8 +160,8 @@ class CreateAccountRoute extends _i15.PageRouteInfo { /// generated route for /// [_i3.EditChatScreen] -class EditChatRoute extends _i15.PageRouteInfo { - EditChatRoute({_i16.Key? key, int? id, List<_i15.PageRouteInfo>? children}) +class EditChatRoute extends _i16.PageRouteInfo { + EditChatRoute({_i17.Key? key, int? id, List<_i16.PageRouteInfo>? children}) : super( EditChatRoute.name, args: EditChatRouteArgs(key: key, id: id), @@ -170,7 +171,7 @@ class EditChatRoute extends _i15.PageRouteInfo { static const String name = 'EditChatRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -185,7 +186,7 @@ class EditChatRoute extends _i15.PageRouteInfo { class EditChatRouteArgs { const EditChatRouteArgs({this.key, this.id}); - final _i16.Key? key; + final _i17.Key? key; final int? id; @@ -197,11 +198,11 @@ class EditChatRouteArgs { /// generated route for /// [_i6.EditPublisherScreen] -class EditPublisherRoute extends _i15.PageRouteInfo { +class EditPublisherRoute extends _i16.PageRouteInfo { EditPublisherRoute({ - _i16.Key? key, + _i17.Key? key, String? name, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( EditPublisherRoute.name, args: EditPublisherRouteArgs(key: key, name: name), @@ -211,7 +212,7 @@ class EditPublisherRoute extends _i15.PageRouteInfo { static const String name = 'EditPublisherRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -226,7 +227,7 @@ class EditPublisherRoute extends _i15.PageRouteInfo { class EditPublisherRouteArgs { const EditPublisherRouteArgs({this.key, this.name}); - final _i16.Key? key; + final _i17.Key? key; final String? name; @@ -238,11 +239,11 @@ class EditPublisherRouteArgs { /// generated route for /// [_i7.EditRealmScreen] -class EditRealmRoute extends _i15.PageRouteInfo { +class EditRealmRoute extends _i16.PageRouteInfo { EditRealmRoute({ - _i16.Key? key, + _i17.Key? key, String? slug, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( EditRealmRoute.name, args: EditRealmRouteArgs(key: key, slug: slug), @@ -252,7 +253,7 @@ class EditRealmRoute extends _i15.PageRouteInfo { static const String name = 'EditRealmRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -267,7 +268,7 @@ class EditRealmRoute extends _i15.PageRouteInfo { class EditRealmRouteArgs { const EditRealmRouteArgs({this.key, this.slug}); - final _i16.Key? key; + final _i17.Key? key; final String? slug; @@ -279,13 +280,13 @@ class EditRealmRouteArgs { /// generated route for /// [_i8.ExploreScreen] -class ExploreRoute extends _i15.PageRouteInfo { - const ExploreRoute({List<_i15.PageRouteInfo>? children}) +class ExploreRoute extends _i16.PageRouteInfo { + const ExploreRoute({List<_i16.PageRouteInfo>? children}) : super(ExploreRoute.name, initialChildren: children); static const String name = 'ExploreRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i8.ExploreScreen(); @@ -295,13 +296,13 @@ class ExploreRoute extends _i15.PageRouteInfo { /// generated route for /// [_i9.LoginScreen] -class LoginRoute extends _i15.PageRouteInfo { - const LoginRoute({List<_i15.PageRouteInfo>? children}) +class LoginRoute extends _i16.PageRouteInfo { + const LoginRoute({List<_i16.PageRouteInfo>? children}) : super(LoginRoute.name, initialChildren: children); static const String name = 'LoginRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i9.LoginScreen(); @@ -311,13 +312,13 @@ class LoginRoute extends _i15.PageRouteInfo { /// generated route for /// [_i6.ManagedPublisherScreen] -class ManagedPublisherRoute extends _i15.PageRouteInfo { - const ManagedPublisherRoute({List<_i15.PageRouteInfo>? children}) +class ManagedPublisherRoute extends _i16.PageRouteInfo { + const ManagedPublisherRoute({List<_i16.PageRouteInfo>? children}) : super(ManagedPublisherRoute.name, initialChildren: children); static const String name = 'ManagedPublisherRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i6.ManagedPublisherScreen(); @@ -327,13 +328,13 @@ class ManagedPublisherRoute extends _i15.PageRouteInfo { /// generated route for /// [_i10.MyselfProfileScreen] -class MyselfProfileRoute extends _i15.PageRouteInfo { - const MyselfProfileRoute({List<_i15.PageRouteInfo>? children}) +class MyselfProfileRoute extends _i16.PageRouteInfo { + const MyselfProfileRoute({List<_i16.PageRouteInfo>? children}) : super(MyselfProfileRoute.name, initialChildren: children); static const String name = 'MyselfProfileRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i10.MyselfProfileScreen(); @@ -343,13 +344,13 @@ class MyselfProfileRoute extends _i15.PageRouteInfo { /// generated route for /// [_i3.NewChatScreen] -class NewChatRoute extends _i15.PageRouteInfo { - const NewChatRoute({List<_i15.PageRouteInfo>? children}) +class NewChatRoute extends _i16.PageRouteInfo { + const NewChatRoute({List<_i16.PageRouteInfo>? children}) : super(NewChatRoute.name, initialChildren: children); static const String name = 'NewChatRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i3.NewChatScreen(); @@ -359,13 +360,13 @@ class NewChatRoute extends _i15.PageRouteInfo { /// generated route for /// [_i6.NewPublisherScreen] -class NewPublisherRoute extends _i15.PageRouteInfo { - const NewPublisherRoute({List<_i15.PageRouteInfo>? children}) +class NewPublisherRoute extends _i16.PageRouteInfo { + const NewPublisherRoute({List<_i16.PageRouteInfo>? children}) : super(NewPublisherRoute.name, initialChildren: children); static const String name = 'NewPublisherRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i6.NewPublisherScreen(); @@ -375,13 +376,13 @@ class NewPublisherRoute extends _i15.PageRouteInfo { /// generated route for /// [_i7.NewRealmScreen] -class NewRealmRoute extends _i15.PageRouteInfo { - const NewRealmRoute({List<_i15.PageRouteInfo>? children}) +class NewRealmRoute extends _i16.PageRouteInfo { + const NewRealmRoute({List<_i16.PageRouteInfo>? children}) : super(NewRealmRoute.name, initialChildren: children); static const String name = 'NewRealmRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i7.NewRealmScreen(); @@ -391,11 +392,11 @@ class NewRealmRoute extends _i15.PageRouteInfo { /// generated route for /// [_i11.PostComposeScreen] -class PostComposeRoute extends _i15.PageRouteInfo { +class PostComposeRoute extends _i16.PageRouteInfo { PostComposeRoute({ - _i16.Key? key, - _i17.SnPost? originalPost, - List<_i15.PageRouteInfo>? children, + _i17.Key? key, + _i18.SnPost? originalPost, + List<_i16.PageRouteInfo>? children, }) : super( PostComposeRoute.name, args: PostComposeRouteArgs(key: key, originalPost: originalPost), @@ -404,7 +405,7 @@ class PostComposeRoute extends _i15.PageRouteInfo { static const String name = 'PostComposeRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final args = data.argsAs( @@ -421,9 +422,9 @@ class PostComposeRoute extends _i15.PageRouteInfo { class PostComposeRouteArgs { const PostComposeRouteArgs({this.key, this.originalPost}); - final _i16.Key? key; + final _i17.Key? key; - final _i17.SnPost? originalPost; + final _i18.SnPost? originalPost; @override String toString() { @@ -433,11 +434,11 @@ class PostComposeRouteArgs { /// generated route for /// [_i12.PostDetailScreen] -class PostDetailRoute extends _i15.PageRouteInfo { +class PostDetailRoute extends _i16.PageRouteInfo { PostDetailRoute({ - _i16.Key? key, + _i17.Key? key, required int id, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( PostDetailRoute.name, args: PostDetailRouteArgs(key: key, id: id), @@ -447,7 +448,7 @@ class PostDetailRoute extends _i15.PageRouteInfo { static const String name = 'PostDetailRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -462,7 +463,7 @@ class PostDetailRoute extends _i15.PageRouteInfo { class PostDetailRouteArgs { const PostDetailRouteArgs({this.key, required this.id}); - final _i16.Key? key; + final _i17.Key? key; final int id; @@ -474,11 +475,11 @@ class PostDetailRouteArgs { /// generated route for /// [_i11.PostEditScreen] -class PostEditRoute extends _i15.PageRouteInfo { +class PostEditRoute extends _i16.PageRouteInfo { PostEditRoute({ - _i16.Key? key, + _i17.Key? key, required int id, - List<_i15.PageRouteInfo>? children, + List<_i16.PageRouteInfo>? children, }) : super( PostEditRoute.name, args: PostEditRouteArgs(key: key, id: id), @@ -488,7 +489,7 @@ class PostEditRoute extends _i15.PageRouteInfo { static const String name = 'PostEditRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -503,7 +504,7 @@ class PostEditRoute extends _i15.PageRouteInfo { class PostEditRouteArgs { const PostEditRouteArgs({this.key, required this.id}); - final _i16.Key? key; + final _i17.Key? key; final int id; @@ -513,15 +514,56 @@ class PostEditRouteArgs { } } +/// generated route for +/// [_i13.RealmDetailScreen] +class RealmDetailRoute extends _i16.PageRouteInfo { + RealmDetailRoute({ + _i17.Key? key, + required String slug, + List<_i16.PageRouteInfo>? children, + }) : super( + RealmDetailRoute.name, + args: RealmDetailRouteArgs(key: key, slug: slug), + rawPathParams: {'slug': slug}, + initialChildren: children, + ); + + static const String name = 'RealmDetailRoute'; + + static _i16.PageInfo page = _i16.PageInfo( + name, + builder: (data) { + final pathParams = data.inheritedPathParams; + final args = data.argsAs( + orElse: () => RealmDetailRouteArgs(slug: pathParams.getString('slug')), + ); + return _i13.RealmDetailScreen(key: args.key, slug: args.slug); + }, + ); +} + +class RealmDetailRouteArgs { + const RealmDetailRouteArgs({this.key, required this.slug}); + + final _i17.Key? key; + + final String slug; + + @override + String toString() { + return 'RealmDetailRouteArgs{key: $key, slug: $slug}'; + } +} + /// generated route for /// [_i7.RealmListScreen] -class RealmListRoute extends _i15.PageRouteInfo { - const RealmListRoute({List<_i15.PageRouteInfo>? children}) +class RealmListRoute extends _i16.PageRouteInfo { + const RealmListRoute({List<_i16.PageRouteInfo>? children}) : super(RealmListRoute.name, initialChildren: children); static const String name = 'RealmListRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { return const _i7.RealmListScreen(); @@ -530,33 +572,33 @@ class RealmListRoute extends _i15.PageRouteInfo { } /// generated route for -/// [_i13.TabsScreen] -class TabsRoute extends _i15.PageRouteInfo { - const TabsRoute({List<_i15.PageRouteInfo>? children}) +/// [_i14.TabsScreen] +class TabsRoute extends _i16.PageRouteInfo { + const TabsRoute({List<_i16.PageRouteInfo>? children}) : super(TabsRoute.name, initialChildren: children); static const String name = 'TabsRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { - return const _i13.TabsScreen(); + return const _i14.TabsScreen(); }, ); } /// generated route for -/// [_i14.UpdateProfileScreen] -class UpdateProfileRoute extends _i15.PageRouteInfo { - const UpdateProfileRoute({List<_i15.PageRouteInfo>? children}) +/// [_i15.UpdateProfileScreen] +class UpdateProfileRoute extends _i16.PageRouteInfo { + const UpdateProfileRoute({List<_i16.PageRouteInfo>? children}) : super(UpdateProfileRoute.name, initialChildren: children); static const String name = 'UpdateProfileRoute'; - static _i15.PageInfo page = _i15.PageInfo( + static _i16.PageInfo page = _i16.PageInfo( name, builder: (data) { - return const _i14.UpdateProfileScreen(); + return const _i15.UpdateProfileScreen(); }, ); } diff --git a/lib/screens/chat/room_detail.dart b/lib/screens/chat/room_detail.dart index ca13643..8159c9e 100644 --- a/lib/screens/chat/room_detail.dart +++ b/lib/screens/chat/room_detail.dart @@ -85,7 +85,11 @@ class ChatDetailScreen extends HookConsumerWidget { currentRoom.type == 1 ? currentRoom.members!.first.account.nick : currentRoom.name, - ).textColor(Theme.of(context).appBarTheme.foregroundColor), + style: TextStyle( + color: Theme.of(context).appBarTheme.foregroundColor, + shadows: [iconShadow], + ), + ), ), actions: [ IconButton( @@ -110,7 +114,7 @@ class ChatDetailScreen extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - currentRoom?.description ?? 'descriptionNone'.tr(), + currentRoom.description, style: const TextStyle(fontSize: 16), ), ], @@ -124,14 +128,14 @@ class ChatDetailScreen extends HookConsumerWidget { } } -class _ChatRoomActionMenu extends StatelessWidget { +class _ChatRoomActionMenu extends HookConsumerWidget { final int id; final Shadow iconShadow; const _ChatRoomActionMenu({required this.id, required this.iconShadow}); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return PopupMenuButton( icon: Icon(Icons.more_vert, shadows: [iconShadow]), itemBuilder: @@ -163,30 +167,21 @@ class _ChatRoomActionMenu extends StatelessWidget { ], ), onTap: () { - Navigator.pop(context); - showDialog( - context: context, - builder: - (context) => AlertDialog( - title: const Text('Delete Room'), - content: const Text( - 'Are you sure you want to delete this room? This action cannot be undone.', - ), - actions: [ - TextButton( - child: const Text('Cancel'), - onPressed: () => Navigator.pop(context), - ), - TextButton( - child: const Text( - 'Delete', - style: TextStyle(color: Colors.red), - ), - onPressed: () async {}, - ), - ], - ), - ); + showConfirmAlert( + 'deleteChatRoomHint'.tr(), + 'deleteChatRoom'.tr(), + ).then((confirm) { + if (confirm) { + final client = ref.watch(apiClientProvider); + client.delete('/chat/$id'); + ref.invalidate(chatroomsJoinedProvider); + if (context.mounted) { + context.router.popUntil( + (route) => route is ChatRoomRoute, + ); + } + } + }); }, ), ], @@ -304,7 +299,7 @@ class _ChatMemberListSheet extends HookConsumerWidget { child: Row( children: [ Text( - 'chatMembers'.plural(memberState.total), + 'members'.plural(memberState.total), style: Theme.of(context).textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.w600, letterSpacing: -0.5, diff --git a/lib/screens/realm/detail.dart b/lib/screens/realm/detail.dart new file mode 100644 index 0000000..56dcc00 --- /dev/null +++ b/lib/screens/realm/detail.dart @@ -0,0 +1,397 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:dio/dio.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:gap/gap.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:island/models/realm.dart'; +import 'package:island/pods/network.dart'; +import 'package:island/route.gr.dart'; +import 'package:island/screens/realm/realms.dart'; +import 'package:island/widgets/account/account_picker.dart'; +import 'package:island/widgets/alert.dart'; +import 'package:island/widgets/app_scaffold.dart'; +import 'package:island/widgets/content/cloud_files.dart'; +import 'package:material_symbols_icons/symbols.dart'; +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:styled_widget/styled_widget.dart'; + +part 'detail.g.dart'; + +@riverpod +Future realmIdentity(Ref ref, String realmSlug) async { + final apiClient = ref.watch(apiClientProvider); + final response = await apiClient.get('/realms/$realmSlug/members/me'); + return SnRealmMember.fromJson(response.data); +} + +@RoutePage() +class RealmDetailScreen extends HookConsumerWidget { + final String slug; + const RealmDetailScreen({super.key, @PathParam("slug") required this.slug}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final realmState = ref.watch(realmProvider(slug)); + final realmIdentity = ref.watch(realmIdentityProvider(slug)); + + final isModerator = realmIdentity.when( + loading: () => false, + error: (error, _) => false, + data: (identity) => (identity?.role ?? 0) >= 50, + ); + + const iconShadow = Shadow( + color: Colors.black54, + blurRadius: 5.0, + offset: Offset(1.0, 1.0), + ); + + return AppScaffold( + body: realmState.when( + loading: () => const Center(child: CircularProgressIndicator()), + error: (error, _) => Center(child: Text('Error: $error')), + data: + (realm) => CustomScrollView( + slivers: [ + SliverAppBar( + expandedHeight: 180, + pinned: true, + leading: PageBackButton(shadows: [iconShadow]), + flexibleSpace: FlexibleSpaceBar( + background: + realm!.backgroundId != null + ? CloudImageWidget(fileId: realm.backgroundId!) + : Container( + color: + Theme.of(context).appBarTheme.backgroundColor, + ), + title: Text( + realm.name, + style: TextStyle( + color: Theme.of(context).appBarTheme.foregroundColor, + shadows: [iconShadow], + ), + ), + ), + actions: [ + IconButton( + icon: const Icon(Icons.people, shadows: [iconShadow]), + onPressed: () { + showCupertinoModalBottomSheet( + context: context, + builder: + (context) => + _RealmMemberListSheet(realmSlug: slug), + ); + }, + ), + if (isModerator) + _RealmActionMenu(realmSlug: slug, iconShadow: iconShadow), + const Gap(8), + ], + ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + realm.description, + style: const TextStyle(fontSize: 16), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } +} + +class _RealmActionMenu extends HookConsumerWidget { + final String realmSlug; + final Shadow iconShadow; + + const _RealmActionMenu({required this.realmSlug, required this.iconShadow}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return PopupMenuButton( + icon: Icon(Icons.more_vert, shadows: [iconShadow]), + itemBuilder: + (context) => [ + PopupMenuItem( + onTap: () { + context.router.replace(EditRealmRoute(slug: realmSlug)); + }, + child: Row( + children: [ + Icon( + Icons.edit, + color: Theme.of(context).colorScheme.onSecondaryContainer, + ), + const Gap(12), + const Text('editRealm').tr(), + ], + ), + ), + PopupMenuItem( + child: Row( + children: [ + const Icon(Icons.delete, color: Colors.red), + const Gap(12), + const Text( + 'deleteRealm', + style: TextStyle(color: Colors.red), + ).tr(), + ], + ), + onTap: () { + showConfirmAlert( + 'deleteRealmHint'.tr(), + 'deleteRealm'.tr(), + ).then((confirm) { + if (confirm) { + final client = ref.watch(apiClientProvider); + client.delete('/realms/$realmSlug'); + ref.invalidate(realmsJoinedProvider); + if (context.mounted) context.router.maybePop(true); + } + }); + }, + ), + ], + ); + } +} + +final realmMemberStateProvider = + StateNotifierProvider.family( + (ref, realmSlug) { + final apiClient = ref.watch(apiClientProvider); + return RealmMemberNotifier(apiClient, realmSlug); + }, + ); + +class RealmMemberNotifier extends StateNotifier { + final String realmSlug; + final Dio _apiClient; + + RealmMemberNotifier(this._apiClient, this.realmSlug) + : super(const RealmMemberState(members: [], isLoading: false, total: 0)); + + Future loadMore({int offset = 0, int take = 20}) async { + if (state.isLoading) return; + if (state.total > 0 && state.members.length >= state.total) return; + + state = state.copyWith(isLoading: true, error: null); + + try { + final response = await _apiClient.get( + '/realms/$realmSlug/members', + queryParameters: {'offset': offset, 'take': take}, + ); + + final total = int.parse(response.headers.value('X-Total') ?? '0'); + final List data = response.data; + final members = data.map((e) => SnRealmMember.fromJson(e)).toList(); + + state = state.copyWith( + members: [...state.members, ...members], + total: total, + isLoading: false, + ); + } catch (e) { + state = state.copyWith(error: e.toString(), isLoading: false); + } + } + + void reset() { + state = const RealmMemberState(members: [], isLoading: false, total: 0); + } +} + +class _RealmMemberListSheet extends HookConsumerWidget { + final String realmSlug; + const _RealmMemberListSheet({required this.realmSlug}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final memberState = ref.watch(realmMemberStateProvider(realmSlug)); + final memberNotifier = ref.read( + realmMemberStateProvider(realmSlug).notifier, + ); + + useEffect(() { + Future(() { + memberNotifier.loadMore(); + }); + return null; + }, []); + + Future invitePerson() async { + final result = await showCupertinoModalBottomSheet( + context: context, + builder: (context) => const AccountPickerSheet(), + ); + if (result == null) return; + try { + final apiClient = ref.watch(apiClientProvider); + await apiClient.post( + '/realms/invites/$realmSlug', + data: {'related_user_id': result.id, 'role': 0}, + ); + memberNotifier.reset(); + await memberNotifier.loadMore(); + } catch (err) { + showErrorAlert(err); + } + } + + return Container( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.8, + ), + child: Material( + color: Colors.transparent, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only( + top: 16, + left: 20, + right: 16, + bottom: 12, + ), + child: Row( + children: [ + Text( + 'members'.plural(memberState.total), + style: Theme.of(context).textTheme.headlineSmall?.copyWith( + fontWeight: FontWeight.w600, + letterSpacing: -0.5, + ), + ), + const Spacer(), + IconButton( + icon: const Icon(Symbols.person_add), + onPressed: invitePerson, + style: IconButton.styleFrom( + minimumSize: const Size(36, 36), + ), + ), + IconButton( + icon: const Icon(Symbols.refresh), + onPressed: () { + memberNotifier.reset(); + memberNotifier.loadMore(); + }, + ), + IconButton( + icon: const Icon(Symbols.close), + onPressed: () => Navigator.pop(context), + style: IconButton.styleFrom( + minimumSize: const Size(36, 36), + ), + ), + ], + ), + ), + const Divider(height: 1), + Expanded( + child: + memberState.error != null + ? Center(child: Text(memberState.error!)) + : ListView.builder( + itemCount: memberState.members.length + 1, + itemBuilder: (context, index) { + if (index == memberState.members.length) { + if (memberState.isLoading) { + return const Center( + child: Padding( + padding: EdgeInsets.all(16.0), + child: CircularProgressIndicator(), + ), + ); + } + if (memberState.members.length < + memberState.total) { + memberNotifier.loadMore( + offset: memberState.members.length, + ); + } + return const SizedBox.shrink(); + } + + final member = memberState.members[index]; + return ListTile( + leading: ProfilePictureWidget( + fileId: member.account!.profile.pictureId, + ), + title: Row( + spacing: 6, + children: [ + Flexible(child: Text(member.account!.nick)), + if (member.joinedAt == null) + const Icon(Symbols.pending_actions, size: 20), + ], + ), + subtitle: Row( + children: [ + Text( + member.role >= 100 + ? 'permissionOwner' + : member.role >= 50 + ? 'permissionModerator' + : 'permissionMember', + ).tr(), + Text('ยท').bold().padding(horizontal: 6), + Expanded( + child: Text("@${member.account!.name}"), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +class RealmMemberState { + final List members; + final bool isLoading; + final int total; + final String? error; + + const RealmMemberState({ + required this.members, + required this.isLoading, + required this.total, + this.error, + }); + + RealmMemberState copyWith({ + List? members, + bool? isLoading, + int? total, + String? error, + }) { + return RealmMemberState( + members: members ?? this.members, + isLoading: isLoading ?? this.isLoading, + total: total ?? this.total, + error: error ?? this.error, + ); + } +} diff --git a/lib/screens/realm/detail.g.dart b/lib/screens/realm/detail.g.dart new file mode 100644 index 0000000..ef73fba --- /dev/null +++ b/lib/screens/realm/detail.g.dart @@ -0,0 +1,152 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'detail.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$realmIdentityHash() => r'eac6e829b5b46bcfadbf201ab6f918d78c894b9f'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +/// See also [realmIdentity]. +@ProviderFor(realmIdentity) +const realmIdentityProvider = RealmIdentityFamily(); + +/// See also [realmIdentity]. +class RealmIdentityFamily extends Family> { + /// See also [realmIdentity]. + const RealmIdentityFamily(); + + /// See also [realmIdentity]. + RealmIdentityProvider call(String realmSlug) { + return RealmIdentityProvider(realmSlug); + } + + @override + RealmIdentityProvider getProviderOverride( + covariant RealmIdentityProvider provider, + ) { + return call(provider.realmSlug); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'realmIdentityProvider'; +} + +/// See also [realmIdentity]. +class RealmIdentityProvider extends AutoDisposeFutureProvider { + /// See also [realmIdentity]. + RealmIdentityProvider(String realmSlug) + : this._internal( + (ref) => realmIdentity(ref as RealmIdentityRef, realmSlug), + from: realmIdentityProvider, + name: r'realmIdentityProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') + ? null + : _$realmIdentityHash, + dependencies: RealmIdentityFamily._dependencies, + allTransitiveDependencies: + RealmIdentityFamily._allTransitiveDependencies, + realmSlug: realmSlug, + ); + + RealmIdentityProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.realmSlug, + }) : super.internal(); + + final String realmSlug; + + @override + Override overrideWith( + FutureOr Function(RealmIdentityRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: RealmIdentityProvider._internal( + (ref) => create(ref as RealmIdentityRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + realmSlug: realmSlug, + ), + ); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _RealmIdentityProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is RealmIdentityProvider && other.realmSlug == realmSlug; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, realmSlug.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin RealmIdentityRef on AutoDisposeFutureProviderRef { + /// The parameter `realmSlug` of this provider. + String get realmSlug; +} + +class _RealmIdentityProviderElement + extends AutoDisposeFutureProviderElement + with RealmIdentityRef { + _RealmIdentityProviderElement(super.provider); + + @override + String get realmSlug => (origin as RealmIdentityProvider).realmSlug; +} + +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/screens/realm/realms.dart b/lib/screens/realm/realms.dart index 818cf9b..8f71a25 100644 --- a/lib/screens/realm/realms.dart +++ b/lib/screens/realm/realms.dart @@ -64,50 +64,11 @@ class RealmListScreen extends HookConsumerWidget { ), title: Text(value[item].name), subtitle: Text(value[item].description), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - padding: EdgeInsets.zero, - visualDensity: VisualDensity.compact, - icon: Icon(Symbols.delete), - onPressed: () { - showConfirmAlert( - 'deleteRealmHint'.tr(), - 'deleteRealm'.tr(args: [value[item].name]), - ).then((confirm) { - if (confirm) { - final client = ref.watch( - apiClientProvider, - ); - client.delete( - '/realms/${value[item].slug}', - ); - ref.invalidate(publishersManagedProvider); - } - }); - }, - ), - IconButton( - padding: EdgeInsets.zero, - visualDensity: VisualDensity.compact, - icon: Icon(Symbols.edit), - onPressed: () { - context.router - .push( - EditRealmRoute(slug: value[item].slug), - ) - .then((value) { - if (value != null) { - ref.refresh( - realmsJoinedProvider.future, - ); - } - }); - }, - ), - ], - ), + onTap: () { + context.router.push( + RealmDetailRoute(slug: value[item].slug), + ); + }, contentPadding: EdgeInsets.only(left: 16, right: 14), ); },