diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index 1243374..8c84dac 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -18,7 +18,7 @@ "loginResetPasswordHint": "Provide your username to receive a password reset link.", "password": "Password", "next": "Next", - "createAccount": "Create an Account", + "createAccount": "Create an Account", "nickname": "Nickname", "email": "Email", "bio": "Bio", @@ -244,5 +244,9 @@ "removeRealmMemberHint": "Are you sure to remove this member from the realm?", "memberRole": "Member Role", "memberRoleHint": "Greater number has higher permission.", - "memberRoleEdit": "Edit role for @{}" + "memberRoleEdit": "Edit role for @{}", + "openLinkConfirm": "Leaving the Solar Network", + "openLinkConfirmDescription": "You're going to leave the Solar Network and open the link ({}) in your browser. It is not related to Solar Network. Beware of phishing and scams.", + "brokenLink": "Unable open link {}... It might be broken or missing uri parts...", + "copyToClipboard": "Copy to clipboard" } diff --git a/lib/models/sticker.dart b/lib/models/sticker.dart index 3246c04..f585d7a 100644 --- a/lib/models/sticker.dart +++ b/lib/models/sticker.dart @@ -30,7 +30,7 @@ abstract class SnStickerPack with _$SnStickerPack { required String name, required String description, required String prefix, - required int publisherId, + required String publisherId, required SnPublisher? publisher, required DateTime createdAt, required DateTime updatedAt, diff --git a/lib/models/sticker.freezed.dart b/lib/models/sticker.freezed.dart index 76121ae..70ca609 100644 --- a/lib/models/sticker.freezed.dart +++ b/lib/models/sticker.freezed.dart @@ -215,7 +215,7 @@ $SnStickerPackCopyWith<$Res>? get pack { /// @nodoc mixin _$SnStickerPack { - String get id; String get name; String get description; String get prefix; int get publisherId; SnPublisher? get publisher; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; + String get id; String get name; String get description; String get prefix; String get publisherId; SnPublisher? get publisher; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; /// Create a copy of SnStickerPack /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -248,7 +248,7 @@ abstract mixin class $SnStickerPackCopyWith<$Res> { factory $SnStickerPackCopyWith(SnStickerPack value, $Res Function(SnStickerPack) _then) = _$SnStickerPackCopyWithImpl; @useResult $Res call({ - String id, String name, String description, String prefix, int publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt + String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt }); @@ -272,7 +272,7 @@ as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable as String,prefix: null == prefix ? _self.prefix : prefix // ignore: cast_nullable_to_non_nullable as String,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable -as int,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as String,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable as SnPublisher?,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 @@ -306,7 +306,7 @@ class _SnStickerPack implements SnStickerPack { @override final String name; @override final String description; @override final String prefix; -@override final int publisherId; +@override final String publisherId; @override final SnPublisher? publisher; @override final DateTime createdAt; @override final DateTime updatedAt; @@ -345,7 +345,7 @@ abstract mixin class _$SnStickerPackCopyWith<$Res> implements $SnStickerPackCopy factory _$SnStickerPackCopyWith(_SnStickerPack value, $Res Function(_SnStickerPack) _then) = __$SnStickerPackCopyWithImpl; @override @useResult $Res call({ - String id, String name, String description, String prefix, int publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt + String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt }); @@ -369,7 +369,7 @@ as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable as String,prefix: null == prefix ? _self.prefix : prefix // ignore: cast_nullable_to_non_nullable as String,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable -as int,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as String,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable as SnPublisher?,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 diff --git a/lib/models/sticker.g.dart b/lib/models/sticker.g.dart index ea08eda..92d35ce 100644 --- a/lib/models/sticker.g.dart +++ b/lib/models/sticker.g.dart @@ -43,7 +43,7 @@ _SnStickerPack _$SnStickerPackFromJson(Map json) => name: json['name'] as String, description: json['description'] as String, prefix: json['prefix'] as String, - publisherId: (json['publisher_id'] as num).toInt(), + publisherId: json['publisher_id'] as String, publisher: json['publisher'] == null ? null diff --git a/lib/route.dart b/lib/route.dart index ee8055b..24d7190 100644 --- a/lib/route.dart +++ b/lib/route.dart @@ -24,7 +24,6 @@ class AppRouter extends RootStackRouter { AutoRoute(page: SettingsRoute.page, path: '/settings'), AutoRoute(page: LoginRoute.page, path: '/auth/login'), AutoRoute(page: CreateAccountRoute.page, path: '/auth/create-account'), - AutoRoute(page: MyselfProfileRoute.page, path: '/account/me'), AutoRoute(page: AccountSettingsRoute.page, path: '/account/settings'), AutoRoute( page: MyselfEventCalendarRoute.page, diff --git a/lib/route.gr.dart b/lib/route.gr.dart index 6fbe1d6..f5207f7 100644 --- a/lib/route.gr.dart +++ b/lib/route.gr.dart @@ -9,20 +9,19 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i26; -import 'package:flutter/material.dart' as _i27; -import 'package:island/models/post.dart' as _i28; +import 'package:auto_route/auto_route.dart' as _i25; +import 'package:flutter/material.dart' as _i26; +import 'package:island/models/post.dart' as _i27; import 'package:island/screens/account.dart' as _i2; -import 'package:island/screens/account/me.dart' as _i16; import 'package:island/screens/account/me/event_calendar.dart' as _i15; import 'package:island/screens/account/me/publishers.dart' as _i9; import 'package:island/screens/account/me/settings.dart' as _i3; -import 'package:island/screens/account/me/update.dart' as _i24; +import 'package:island/screens/account/me/update.dart' as _i23; import 'package:island/screens/account/profile.dart' as _i1; -import 'package:island/screens/account/relationship.dart' as _i21; +import 'package:island/screens/account/relationship.dart' as _i20; import 'package:island/screens/auth/create_account.dart' as _i7; import 'package:island/screens/auth/login.dart' as _i14; -import 'package:island/screens/auth/tabs.dart' as _i23; +import 'package:island/screens/auth/tabs.dart' as _i22; import 'package:island/screens/chat/chat.dart' as _i5; import 'package:island/screens/chat/room.dart' as _i6; import 'package:island/screens/chat/room_detail.dart' as _i4; @@ -30,21 +29,21 @@ import 'package:island/screens/creators/hub.dart' as _i8; import 'package:island/screens/creators/stickers/pack_detail.dart' as _i12; import 'package:island/screens/creators/stickers/stickers.dart' as _i11; import 'package:island/screens/explore.dart' as _i13; -import 'package:island/screens/posts/compose.dart' as _i17; -import 'package:island/screens/posts/detail.dart' as _i18; -import 'package:island/screens/posts/pub_profile.dart' as _i19; -import 'package:island/screens/realm/detail.dart' as _i20; +import 'package:island/screens/posts/compose.dart' as _i16; +import 'package:island/screens/posts/detail.dart' as _i17; +import 'package:island/screens/posts/pub_profile.dart' as _i18; +import 'package:island/screens/realm/detail.dart' as _i19; import 'package:island/screens/realm/realms.dart' as _i10; -import 'package:island/screens/settings.dart' as _i22; -import 'package:island/screens/wallet.dart' as _i25; +import 'package:island/screens/settings.dart' as _i21; +import 'package:island/screens/wallet.dart' as _i24; /// generated route for /// [_i1.AccountProfileScreen] -class AccountProfileRoute extends _i26.PageRouteInfo { +class AccountProfileRoute extends _i25.PageRouteInfo { AccountProfileRoute({ - _i27.Key? key, + _i26.Key? key, required String name, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( AccountProfileRoute.name, args: AccountProfileRouteArgs(key: key, name: name), @@ -54,7 +53,7 @@ class AccountProfileRoute extends _i26.PageRouteInfo { static const String name = 'AccountProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -70,7 +69,7 @@ class AccountProfileRoute extends _i26.PageRouteInfo { class AccountProfileRouteArgs { const AccountProfileRouteArgs({this.key, required this.name}); - final _i27.Key? key; + final _i26.Key? key; final String name; @@ -82,13 +81,13 @@ class AccountProfileRouteArgs { /// generated route for /// [_i2.AccountScreen] -class AccountRoute extends _i26.PageRouteInfo { - const AccountRoute({List<_i26.PageRouteInfo>? children}) +class AccountRoute extends _i25.PageRouteInfo { + const AccountRoute({List<_i25.PageRouteInfo>? children}) : super(AccountRoute.name, initialChildren: children); static const String name = 'AccountRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i2.AccountScreen(); @@ -98,13 +97,13 @@ class AccountRoute extends _i26.PageRouteInfo { /// generated route for /// [_i3.AccountSettingsScreen] -class AccountSettingsRoute extends _i26.PageRouteInfo { - const AccountSettingsRoute({List<_i26.PageRouteInfo>? children}) +class AccountSettingsRoute extends _i25.PageRouteInfo { + const AccountSettingsRoute({List<_i25.PageRouteInfo>? children}) : super(AccountSettingsRoute.name, initialChildren: children); static const String name = 'AccountSettingsRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i3.AccountSettingsScreen(); @@ -114,11 +113,11 @@ class AccountSettingsRoute extends _i26.PageRouteInfo { /// generated route for /// [_i4.ChatDetailScreen] -class ChatDetailRoute extends _i26.PageRouteInfo { +class ChatDetailRoute extends _i25.PageRouteInfo { ChatDetailRoute({ - _i27.Key? key, + _i26.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( ChatDetailRoute.name, args: ChatDetailRouteArgs(key: key, id: id), @@ -128,7 +127,7 @@ class ChatDetailRoute extends _i26.PageRouteInfo { static const String name = 'ChatDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -143,7 +142,7 @@ class ChatDetailRoute extends _i26.PageRouteInfo { class ChatDetailRouteArgs { const ChatDetailRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i26.Key? key; final String id; @@ -155,13 +154,13 @@ class ChatDetailRouteArgs { /// generated route for /// [_i5.ChatListScreen] -class ChatListRoute extends _i26.PageRouteInfo { - const ChatListRoute({List<_i26.PageRouteInfo>? children}) +class ChatListRoute extends _i25.PageRouteInfo { + const ChatListRoute({List<_i25.PageRouteInfo>? children}) : super(ChatListRoute.name, initialChildren: children); static const String name = 'ChatListRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i5.ChatListScreen(); @@ -171,11 +170,11 @@ class ChatListRoute extends _i26.PageRouteInfo { /// generated route for /// [_i6.ChatRoomScreen] -class ChatRoomRoute extends _i26.PageRouteInfo { +class ChatRoomRoute extends _i25.PageRouteInfo { ChatRoomRoute({ - _i27.Key? key, + _i26.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( ChatRoomRoute.name, args: ChatRoomRouteArgs(key: key, id: id), @@ -185,7 +184,7 @@ class ChatRoomRoute extends _i26.PageRouteInfo { static const String name = 'ChatRoomRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -200,7 +199,7 @@ class ChatRoomRoute extends _i26.PageRouteInfo { class ChatRoomRouteArgs { const ChatRoomRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i26.Key? key; final String id; @@ -212,13 +211,13 @@ class ChatRoomRouteArgs { /// generated route for /// [_i7.CreateAccountScreen] -class CreateAccountRoute extends _i26.PageRouteInfo { - const CreateAccountRoute({List<_i26.PageRouteInfo>? children}) +class CreateAccountRoute extends _i25.PageRouteInfo { + const CreateAccountRoute({List<_i25.PageRouteInfo>? children}) : super(CreateAccountRoute.name, initialChildren: children); static const String name = 'CreateAccountRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i7.CreateAccountScreen(); @@ -228,13 +227,13 @@ class CreateAccountRoute extends _i26.PageRouteInfo { /// generated route for /// [_i8.CreatorHubScreen] -class CreatorHubRoute extends _i26.PageRouteInfo { - const CreatorHubRoute({List<_i26.PageRouteInfo>? children}) +class CreatorHubRoute extends _i25.PageRouteInfo { + const CreatorHubRoute({List<_i25.PageRouteInfo>? children}) : super(CreatorHubRoute.name, initialChildren: children); static const String name = 'CreatorHubRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i8.CreatorHubScreen(); @@ -244,8 +243,8 @@ class CreatorHubRoute extends _i26.PageRouteInfo { /// generated route for /// [_i5.EditChatScreen] -class EditChatRoute extends _i26.PageRouteInfo { - EditChatRoute({_i27.Key? key, String? id, List<_i26.PageRouteInfo>? children}) +class EditChatRoute extends _i25.PageRouteInfo { + EditChatRoute({_i26.Key? key, String? id, List<_i25.PageRouteInfo>? children}) : super( EditChatRoute.name, args: EditChatRouteArgs(key: key, id: id), @@ -255,7 +254,7 @@ class EditChatRoute extends _i26.PageRouteInfo { static const String name = 'EditChatRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -270,7 +269,7 @@ class EditChatRoute extends _i26.PageRouteInfo { class EditChatRouteArgs { const EditChatRouteArgs({this.key, this.id}); - final _i27.Key? key; + final _i26.Key? key; final String? id; @@ -282,11 +281,11 @@ class EditChatRouteArgs { /// generated route for /// [_i9.EditPublisherScreen] -class EditPublisherRoute extends _i26.PageRouteInfo { +class EditPublisherRoute extends _i25.PageRouteInfo { EditPublisherRoute({ - _i27.Key? key, + _i26.Key? key, String? name, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( EditPublisherRoute.name, args: EditPublisherRouteArgs(key: key, name: name), @@ -296,7 +295,7 @@ class EditPublisherRoute extends _i26.PageRouteInfo { static const String name = 'EditPublisherRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -311,7 +310,7 @@ class EditPublisherRoute extends _i26.PageRouteInfo { class EditPublisherRouteArgs { const EditPublisherRouteArgs({this.key, this.name}); - final _i27.Key? key; + final _i26.Key? key; final String? name; @@ -323,11 +322,11 @@ class EditPublisherRouteArgs { /// generated route for /// [_i10.EditRealmScreen] -class EditRealmRoute extends _i26.PageRouteInfo { +class EditRealmRoute extends _i25.PageRouteInfo { EditRealmRoute({ - _i27.Key? key, + _i26.Key? key, String? slug, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( EditRealmRoute.name, args: EditRealmRouteArgs(key: key, slug: slug), @@ -337,7 +336,7 @@ class EditRealmRoute extends _i26.PageRouteInfo { static const String name = 'EditRealmRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -352,7 +351,7 @@ class EditRealmRoute extends _i26.PageRouteInfo { class EditRealmRouteArgs { const EditRealmRouteArgs({this.key, this.slug}); - final _i27.Key? key; + final _i26.Key? key; final String? slug; @@ -365,12 +364,12 @@ class EditRealmRouteArgs { /// generated route for /// [_i11.EditStickerPacksScreen] class EditStickerPacksRoute - extends _i26.PageRouteInfo { + extends _i25.PageRouteInfo { EditStickerPacksRoute({ - _i27.Key? key, + _i26.Key? key, required String pubName, String? packId, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( EditStickerPacksRoute.name, args: EditStickerPacksRouteArgs( @@ -384,7 +383,7 @@ class EditStickerPacksRoute static const String name = 'EditStickerPacksRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -411,7 +410,7 @@ class EditStickerPacksRouteArgs { this.packId, }); - final _i27.Key? key; + final _i26.Key? key; final String pubName; @@ -425,12 +424,12 @@ class EditStickerPacksRouteArgs { /// generated route for /// [_i12.EditStickersScreen] -class EditStickersRoute extends _i26.PageRouteInfo { +class EditStickersRoute extends _i25.PageRouteInfo { EditStickersRoute({ - _i27.Key? key, + _i26.Key? key, required String packId, required String? id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( EditStickersRoute.name, args: EditStickersRouteArgs(key: key, packId: packId, id: id), @@ -440,7 +439,7 @@ class EditStickersRoute extends _i26.PageRouteInfo { static const String name = 'EditStickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -467,7 +466,7 @@ class EditStickersRouteArgs { required this.id, }); - final _i27.Key? key; + final _i26.Key? key; final String packId; @@ -481,13 +480,13 @@ class EditStickersRouteArgs { /// generated route for /// [_i13.ExploreScreen] -class ExploreRoute extends _i26.PageRouteInfo { - const ExploreRoute({List<_i26.PageRouteInfo>? children}) +class ExploreRoute extends _i25.PageRouteInfo { + const ExploreRoute({List<_i25.PageRouteInfo>? children}) : super(ExploreRoute.name, initialChildren: children); static const String name = 'ExploreRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i13.ExploreScreen(); @@ -497,13 +496,13 @@ class ExploreRoute extends _i26.PageRouteInfo { /// generated route for /// [_i14.LoginScreen] -class LoginRoute extends _i26.PageRouteInfo { - const LoginRoute({List<_i26.PageRouteInfo>? children}) +class LoginRoute extends _i25.PageRouteInfo { + const LoginRoute({List<_i25.PageRouteInfo>? children}) : super(LoginRoute.name, initialChildren: children); static const String name = 'LoginRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i14.LoginScreen(); @@ -513,13 +512,13 @@ class LoginRoute extends _i26.PageRouteInfo { /// generated route for /// [_i9.ManagedPublisherScreen] -class ManagedPublisherRoute extends _i26.PageRouteInfo { - const ManagedPublisherRoute({List<_i26.PageRouteInfo>? children}) +class ManagedPublisherRoute extends _i25.PageRouteInfo { + const ManagedPublisherRoute({List<_i25.PageRouteInfo>? children}) : super(ManagedPublisherRoute.name, initialChildren: children); static const String name = 'ManagedPublisherRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i9.ManagedPublisherScreen(); @@ -529,13 +528,13 @@ class ManagedPublisherRoute extends _i26.PageRouteInfo { /// generated route for /// [_i15.MyselfEventCalendarScreen] -class MyselfEventCalendarRoute extends _i26.PageRouteInfo { - const MyselfEventCalendarRoute({List<_i26.PageRouteInfo>? children}) +class MyselfEventCalendarRoute extends _i25.PageRouteInfo { + const MyselfEventCalendarRoute({List<_i25.PageRouteInfo>? children}) : super(MyselfEventCalendarRoute.name, initialChildren: children); static const String name = 'MyselfEventCalendarRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i15.MyselfEventCalendarScreen(); @@ -543,31 +542,15 @@ class MyselfEventCalendarRoute extends _i26.PageRouteInfo { ); } -/// generated route for -/// [_i16.MyselfProfileScreen] -class MyselfProfileRoute extends _i26.PageRouteInfo { - const MyselfProfileRoute({List<_i26.PageRouteInfo>? children}) - : super(MyselfProfileRoute.name, initialChildren: children); - - static const String name = 'MyselfProfileRoute'; - - static _i26.PageInfo page = _i26.PageInfo( - name, - builder: (data) { - return const _i16.MyselfProfileScreen(); - }, - ); -} - /// generated route for /// [_i5.NewChatScreen] -class NewChatRoute extends _i26.PageRouteInfo { - const NewChatRoute({List<_i26.PageRouteInfo>? children}) +class NewChatRoute extends _i25.PageRouteInfo { + const NewChatRoute({List<_i25.PageRouteInfo>? children}) : super(NewChatRoute.name, initialChildren: children); static const String name = 'NewChatRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i5.NewChatScreen(); @@ -577,13 +560,13 @@ class NewChatRoute extends _i26.PageRouteInfo { /// generated route for /// [_i9.NewPublisherScreen] -class NewPublisherRoute extends _i26.PageRouteInfo { - const NewPublisherRoute({List<_i26.PageRouteInfo>? children}) +class NewPublisherRoute extends _i25.PageRouteInfo { + const NewPublisherRoute({List<_i25.PageRouteInfo>? children}) : super(NewPublisherRoute.name, initialChildren: children); static const String name = 'NewPublisherRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i9.NewPublisherScreen(); @@ -593,13 +576,13 @@ class NewPublisherRoute extends _i26.PageRouteInfo { /// generated route for /// [_i10.NewRealmScreen] -class NewRealmRoute extends _i26.PageRouteInfo { - const NewRealmRoute({List<_i26.PageRouteInfo>? children}) +class NewRealmRoute extends _i25.PageRouteInfo { + const NewRealmRoute({List<_i25.PageRouteInfo>? children}) : super(NewRealmRoute.name, initialChildren: children); static const String name = 'NewRealmRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i10.NewRealmScreen(); @@ -610,11 +593,11 @@ class NewRealmRoute extends _i26.PageRouteInfo { /// generated route for /// [_i11.NewStickerPacksScreen] class NewStickerPacksRoute - extends _i26.PageRouteInfo { + extends _i25.PageRouteInfo { NewStickerPacksRoute({ - _i27.Key? key, + _i26.Key? key, required String pubName, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( NewStickerPacksRoute.name, args: NewStickerPacksRouteArgs(key: key, pubName: pubName), @@ -624,7 +607,7 @@ class NewStickerPacksRoute static const String name = 'NewStickerPacksRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -641,7 +624,7 @@ class NewStickerPacksRoute class NewStickerPacksRouteArgs { const NewStickerPacksRouteArgs({this.key, required this.pubName}); - final _i27.Key? key; + final _i26.Key? key; final String pubName; @@ -653,11 +636,11 @@ class NewStickerPacksRouteArgs { /// generated route for /// [_i12.NewStickersScreen] -class NewStickersRoute extends _i26.PageRouteInfo { +class NewStickersRoute extends _i25.PageRouteInfo { NewStickersRoute({ - _i27.Key? key, + _i26.Key? key, required String packId, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( NewStickersRoute.name, args: NewStickersRouteArgs(key: key, packId: packId), @@ -667,7 +650,7 @@ class NewStickersRoute extends _i26.PageRouteInfo { static const String name = 'NewStickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -683,7 +666,7 @@ class NewStickersRoute extends _i26.PageRouteInfo { class NewStickersRouteArgs { const NewStickersRouteArgs({this.key, required this.packId}); - final _i27.Key? key; + final _i26.Key? key; final String packId; @@ -694,12 +677,12 @@ class NewStickersRouteArgs { } /// generated route for -/// [_i17.PostComposeScreen] -class PostComposeRoute extends _i26.PageRouteInfo { +/// [_i16.PostComposeScreen] +class PostComposeRoute extends _i25.PageRouteInfo { PostComposeRoute({ - _i27.Key? key, - _i28.SnPost? originalPost, - List<_i26.PageRouteInfo>? children, + _i26.Key? key, + _i27.SnPost? originalPost, + List<_i25.PageRouteInfo>? children, }) : super( PostComposeRoute.name, args: PostComposeRouteArgs(key: key, originalPost: originalPost), @@ -708,13 +691,13 @@ class PostComposeRoute extends _i26.PageRouteInfo { static const String name = 'PostComposeRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const PostComposeRouteArgs(), ); - return _i17.PostComposeScreen( + return _i16.PostComposeScreen( key: args.key, originalPost: args.originalPost, ); @@ -725,9 +708,9 @@ class PostComposeRoute extends _i26.PageRouteInfo { class PostComposeRouteArgs { const PostComposeRouteArgs({this.key, this.originalPost}); - final _i27.Key? key; + final _i26.Key? key; - final _i28.SnPost? originalPost; + final _i27.SnPost? originalPost; @override String toString() { @@ -736,12 +719,12 @@ class PostComposeRouteArgs { } /// generated route for -/// [_i18.PostDetailScreen] -class PostDetailRoute extends _i26.PageRouteInfo { +/// [_i17.PostDetailScreen] +class PostDetailRoute extends _i25.PageRouteInfo { PostDetailRoute({ - _i27.Key? key, + _i26.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( PostDetailRoute.name, args: PostDetailRouteArgs(key: key, id: id), @@ -751,14 +734,14 @@ class PostDetailRoute extends _i26.PageRouteInfo { static const String name = 'PostDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => PostDetailRouteArgs(id: pathParams.getString('id')), ); - return _i18.PostDetailScreen(key: args.key, id: args.id); + return _i17.PostDetailScreen(key: args.key, id: args.id); }, ); } @@ -766,7 +749,7 @@ class PostDetailRoute extends _i26.PageRouteInfo { class PostDetailRouteArgs { const PostDetailRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i26.Key? key; final String id; @@ -777,12 +760,12 @@ class PostDetailRouteArgs { } /// generated route for -/// [_i17.PostEditScreen] -class PostEditRoute extends _i26.PageRouteInfo { +/// [_i16.PostEditScreen] +class PostEditRoute extends _i25.PageRouteInfo { PostEditRoute({ - _i27.Key? key, + _i26.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( PostEditRoute.name, args: PostEditRouteArgs(key: key, id: id), @@ -792,14 +775,14 @@ class PostEditRoute extends _i26.PageRouteInfo { static const String name = 'PostEditRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => PostEditRouteArgs(id: pathParams.getString('id')), ); - return _i17.PostEditScreen(key: args.key, id: args.id); + return _i16.PostEditScreen(key: args.key, id: args.id); }, ); } @@ -807,7 +790,7 @@ class PostEditRoute extends _i26.PageRouteInfo { class PostEditRouteArgs { const PostEditRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i26.Key? key; final String id; @@ -818,13 +801,13 @@ class PostEditRouteArgs { } /// generated route for -/// [_i19.PublisherProfileScreen] +/// [_i18.PublisherProfileScreen] class PublisherProfileRoute - extends _i26.PageRouteInfo { + extends _i25.PageRouteInfo { PublisherProfileRoute({ - _i27.Key? key, + _i26.Key? key, required String name, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( PublisherProfileRoute.name, args: PublisherProfileRouteArgs(key: key, name: name), @@ -834,7 +817,7 @@ class PublisherProfileRoute static const String name = 'PublisherProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -842,7 +825,7 @@ class PublisherProfileRoute orElse: () => PublisherProfileRouteArgs(name: pathParams.getString('name')), ); - return _i19.PublisherProfileScreen(key: args.key, name: args.name); + return _i18.PublisherProfileScreen(key: args.key, name: args.name); }, ); } @@ -850,7 +833,7 @@ class PublisherProfileRoute class PublisherProfileRouteArgs { const PublisherProfileRouteArgs({this.key, required this.name}); - final _i27.Key? key; + final _i26.Key? key; final String name; @@ -861,12 +844,12 @@ class PublisherProfileRouteArgs { } /// generated route for -/// [_i20.RealmDetailScreen] -class RealmDetailRoute extends _i26.PageRouteInfo { +/// [_i19.RealmDetailScreen] +class RealmDetailRoute extends _i25.PageRouteInfo { RealmDetailRoute({ - _i27.Key? key, + _i26.Key? key, required String slug, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( RealmDetailRoute.name, args: RealmDetailRouteArgs(key: key, slug: slug), @@ -876,14 +859,14 @@ class RealmDetailRoute extends _i26.PageRouteInfo { static const String name = 'RealmDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => RealmDetailRouteArgs(slug: pathParams.getString('slug')), ); - return _i20.RealmDetailScreen(key: args.key, slug: args.slug); + return _i19.RealmDetailScreen(key: args.key, slug: args.slug); }, ); } @@ -891,7 +874,7 @@ class RealmDetailRoute extends _i26.PageRouteInfo { class RealmDetailRouteArgs { const RealmDetailRouteArgs({this.key, required this.slug}); - final _i27.Key? key; + final _i26.Key? key; final String slug; @@ -903,13 +886,13 @@ class RealmDetailRouteArgs { /// generated route for /// [_i10.RealmListScreen] -class RealmListRoute extends _i26.PageRouteInfo { - const RealmListRoute({List<_i26.PageRouteInfo>? children}) +class RealmListRoute extends _i25.PageRouteInfo { + const RealmListRoute({List<_i25.PageRouteInfo>? children}) : super(RealmListRoute.name, initialChildren: children); static const String name = 'RealmListRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { return const _i10.RealmListScreen(); @@ -918,33 +901,33 @@ class RealmListRoute extends _i26.PageRouteInfo { } /// generated route for -/// [_i21.RelationshipScreen] -class RelationshipRoute extends _i26.PageRouteInfo { - const RelationshipRoute({List<_i26.PageRouteInfo>? children}) +/// [_i20.RelationshipScreen] +class RelationshipRoute extends _i25.PageRouteInfo { + const RelationshipRoute({List<_i25.PageRouteInfo>? children}) : super(RelationshipRoute.name, initialChildren: children); static const String name = 'RelationshipRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { - return const _i21.RelationshipScreen(); + return const _i20.RelationshipScreen(); }, ); } /// generated route for -/// [_i22.SettingsScreen] -class SettingsRoute extends _i26.PageRouteInfo { - const SettingsRoute({List<_i26.PageRouteInfo>? children}) +/// [_i21.SettingsScreen] +class SettingsRoute extends _i25.PageRouteInfo { + const SettingsRoute({List<_i25.PageRouteInfo>? children}) : super(SettingsRoute.name, initialChildren: children); static const String name = 'SettingsRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { - return const _i22.SettingsScreen(); + return const _i21.SettingsScreen(); }, ); } @@ -952,12 +935,12 @@ class SettingsRoute extends _i26.PageRouteInfo { /// generated route for /// [_i12.StickerPackDetailScreen] class StickerPackDetailRoute - extends _i26.PageRouteInfo { + extends _i25.PageRouteInfo { StickerPackDetailRoute({ - _i27.Key? key, + _i26.Key? key, required String pubName, required String id, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( StickerPackDetailRoute.name, args: StickerPackDetailRouteArgs(key: key, pubName: pubName, id: id), @@ -967,7 +950,7 @@ class StickerPackDetailRoute static const String name = 'StickerPackDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -994,7 +977,7 @@ class StickerPackDetailRouteArgs { required this.id, }); - final _i27.Key? key; + final _i26.Key? key; final String pubName; @@ -1008,11 +991,11 @@ class StickerPackDetailRouteArgs { /// generated route for /// [_i11.StickersScreen] -class StickersRoute extends _i26.PageRouteInfo { +class StickersRoute extends _i25.PageRouteInfo { StickersRoute({ - _i27.Key? key, + _i26.Key? key, required String pubName, - List<_i26.PageRouteInfo>? children, + List<_i25.PageRouteInfo>? children, }) : super( StickersRoute.name, args: StickersRouteArgs(key: key, pubName: pubName), @@ -1022,7 +1005,7 @@ class StickersRoute extends _i26.PageRouteInfo { static const String name = 'StickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -1037,7 +1020,7 @@ class StickersRoute extends _i26.PageRouteInfo { class StickersRouteArgs { const StickersRouteArgs({this.key, required this.pubName}); - final _i27.Key? key; + final _i26.Key? key; final String pubName; @@ -1048,49 +1031,49 @@ class StickersRouteArgs { } /// generated route for -/// [_i23.TabsScreen] -class TabsRoute extends _i26.PageRouteInfo { - const TabsRoute({List<_i26.PageRouteInfo>? children}) +/// [_i22.TabsScreen] +class TabsRoute extends _i25.PageRouteInfo { + const TabsRoute({List<_i25.PageRouteInfo>? children}) : super(TabsRoute.name, initialChildren: children); static const String name = 'TabsRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { - return const _i23.TabsScreen(); + return const _i22.TabsScreen(); }, ); } /// generated route for -/// [_i24.UpdateProfileScreen] -class UpdateProfileRoute extends _i26.PageRouteInfo { - const UpdateProfileRoute({List<_i26.PageRouteInfo>? children}) +/// [_i23.UpdateProfileScreen] +class UpdateProfileRoute extends _i25.PageRouteInfo { + const UpdateProfileRoute({List<_i25.PageRouteInfo>? children}) : super(UpdateProfileRoute.name, initialChildren: children); static const String name = 'UpdateProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { - return const _i24.UpdateProfileScreen(); + return const _i23.UpdateProfileScreen(); }, ); } /// generated route for -/// [_i25.WalletScreen] -class WalletRoute extends _i26.PageRouteInfo { - const WalletRoute({List<_i26.PageRouteInfo>? children}) +/// [_i24.WalletScreen] +class WalletRoute extends _i25.PageRouteInfo { + const WalletRoute({List<_i25.PageRouteInfo>? children}) : super(WalletRoute.name, initialChildren: children); static const String name = 'WalletRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i25.PageInfo page = _i25.PageInfo( name, builder: (data) { - return const _i25.WalletScreen(); + return const _i24.WalletScreen(); }, ); } diff --git a/lib/screens/account/me.dart b/lib/screens/account/me.dart deleted file mode 100644 index d501cd2..0000000 --- a/lib/screens/account/me.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:auto_route/annotations.dart'; -import 'package:flutter/material.dart'; -import 'package:island/widgets/app_scaffold.dart'; - -@RoutePage() -class MyselfProfileScreen extends StatelessWidget { - const MyselfProfileScreen({super.key}); - - @override - Widget build(BuildContext context) { - return AppScaffold(appBar: AppBar(leading: const PageBackButton())); - } -} diff --git a/lib/screens/account/profile.dart b/lib/screens/account/profile.dart index 9a7e5ed..4b1626f 100644 --- a/lib/screens/account/profile.dart +++ b/lib/screens/account/profile.dart @@ -46,7 +46,7 @@ class AccountProfileScreen extends HookConsumerWidget { final iconShadow = Shadow( color: Colors.black54, blurRadius: 5.0, - offset: Offset(1.0, 1.0), + offset: const Offset(1.0, 1.0), ); return account.when( @@ -78,36 +78,39 @@ class AccountProfileScreen extends HookConsumerWidget { ), ), SliverToBoxAdapter( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 20, - children: [ - ProfilePictureWidget( - fileId: data.profile.pictureId!, - radius: 32, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( - spacing: 6, - children: [ - Text(data.nick).fontSize(20), - Text( - '@${data.name}', - ).fontSize(14).opacity(0.85), - ], - ), - AccountStatusWidget( - uname: name, - padding: EdgeInsets.zero, - ), - ], + child: Padding( + padding: const EdgeInsets.fromLTRB(24, 24, 24, 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ProfilePictureWidget( + fileId: data.profile.pictureId, + radius: 32, ), - ), - ], - ).padding(horizontal: 24, top: 24, bottom: 8), + const Gap(20), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + Text(data.nick).fontSize(20), + const Gap(6), + Text( + '@${data.name}', + ).fontSize(14).opacity(0.85), + ], + ), + AccountStatusWidget( + uname: name, + padding: EdgeInsets.zero, + ), + ], + ), + ), + ], + ), + ), ), if (data.badges.isNotEmpty) SliverToBoxAdapter( @@ -127,7 +130,7 @@ class AccountProfileScreen extends HookConsumerWidget { SliverToBoxAdapter( child: const Divider(height: 1).padding(bottom: 24), ), - if (data.profile.bio != null && data.profile.bio!.isNotEmpty) + if (data.profile.bio?.isNotEmpty ?? false) SliverToBoxAdapter( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index 897db28..1e294a6 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -18,7 +18,7 @@ import 'package:island/pods/websocket.dart'; import 'package:island/route.gr.dart'; import 'package:island/screens/posts/compose.dart'; import 'package:island/widgets/alert.dart'; -import 'package:island/widgets/chat/message_bubble.dart'; +import 'package:island/widgets/chat/message_item.dart'; import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/response.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; @@ -506,17 +506,17 @@ class ChatRoomScreen extends HookConsumerWidget { return chatIdentity.when( skipError: true, data: - (identity) => MessageBubble( + (identity) => MessageItem( message: message, isCurrentUser: identity?.id == message.senderId, onAction: (action) { switch (action) { - case MessageBubbleAction.delete: + case MessageItemAction.delete: messagesNotifier.deleteMessage( message.id, ); - case MessageBubbleAction.edit: + case MessageItemAction.edit: messageEditingTo.value = message.toRemoteMessage(); messageController.text = @@ -535,10 +535,10 @@ class ChatRoomScreen extends HookConsumerWidget { ), ) .toList(); - case MessageBubbleAction.forward: + case MessageItemAction.forward: messageForwardingTo.value = message.toRemoteMessage(); - case MessageBubbleAction.reply: + case MessageItemAction.reply: messageReplyingTo.value = message.toRemoteMessage(); } @@ -548,7 +548,7 @@ class ChatRoomScreen extends HookConsumerWidget { showAvatar: isLastInGroup, ), loading: - () => MessageBubble( + () => MessageItem( message: message, isCurrentUser: false, onAction: null, diff --git a/lib/widgets/account/status.dart b/lib/widgets/account/status.dart index 41d1b9c..bf3af72 100644 --- a/lib/widgets/account/status.dart +++ b/lib/widgets/account/status.dart @@ -115,7 +115,7 @@ class AccountStatusWidget extends HookConsumerWidget { child: Row( spacing: 4, children: [ - if (userStatus.value!.isOnline) + if (userStatus.value?.isOnline ?? false) Icon( Symbols.circle, fill: 1, diff --git a/lib/widgets/alert.dart b/lib/widgets/alert.dart index 0952e02..d821040 100644 --- a/lib/widgets/alert.dart +++ b/lib/widgets/alert.dart @@ -6,8 +6,16 @@ import 'package:styled_widget/styled_widget.dart'; export 'content/alert.native.dart' if (dart.library.html) 'content/alert.web.dart'; -void showSnackBar(BuildContext context, String message) { - showSnackBar(context, message); +void showSnackBar( + BuildContext context, + String message, { + SnackBarAction? action, +}) { + showSnackBar(context, message, action: action); +} + +void clearSnackBar(BuildContext context) { + ScaffoldMessenger.of(context).clearSnackBars(); } OverlayEntry? _loadingOverlay; diff --git a/lib/widgets/chat/message_bubble.dart b/lib/widgets/chat/message_item.dart similarity index 79% rename from lib/widgets/chat/message_bubble.dart rename to lib/widgets/chat/message_item.dart index bd9d307..85ee280 100644 --- a/lib/widgets/chat/message_bubble.dart +++ b/lib/widgets/chat/message_item.dart @@ -4,29 +4,29 @@ import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/database/message.dart'; import 'package:island/models/chat.dart'; +import 'package:island/screens/chat/room.dart'; import 'package:island/widgets/content/cloud_file_collection.dart'; import 'package:island/widgets/content/cloud_files.dart'; +import 'package:island/widgets/content/markdown.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:super_context_menu/super_context_menu.dart'; -import '../../screens/chat/room.dart'; - -class MessageBubbleAction { +class MessageItemAction { static const String edit = "edit"; static const String delete = "delete"; static const String reply = "reply"; static const String forward = "forward"; } -class MessageBubble extends HookConsumerWidget { +class MessageItem extends HookConsumerWidget { final LocalChatMessage message; final bool isCurrentUser; final Function(String action)? onAction; final Map? progress; final bool showAvatar; - const MessageBubble({ + const MessageItem({ super.key, required this.message, required this.isCurrentUser, @@ -45,6 +45,10 @@ class MessageBubble extends HookConsumerWidget { isCurrentUser ? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.5) : Theme.of(context).colorScheme.surfaceContainer; + final linkColor = Color.alphaBlend( + Theme.of(context).colorScheme.primary, + containerColor, + ); final remoteMessage = message.toRemoteMessage(); final sender = remoteMessage.sender; @@ -59,7 +63,7 @@ class MessageBubble extends HookConsumerWidget { title: 'edit'.tr(), image: MenuImage.icon(Symbols.edit), callback: () { - onAction!.call(MessageBubbleAction.edit); + onAction!.call(MessageItemAction.edit); }, ), if (isCurrentUser) @@ -67,7 +71,7 @@ class MessageBubble extends HookConsumerWidget { title: 'delete'.tr(), image: MenuImage.icon(Symbols.delete), callback: () { - onAction!.call(MessageBubbleAction.delete); + onAction!.call(MessageItemAction.delete); }, ), if (isCurrentUser) MenuSeparator(), @@ -75,14 +79,14 @@ class MessageBubble extends HookConsumerWidget { title: 'reply'.tr(), image: MenuImage.icon(Symbols.reply), callback: () { - onAction!.call(MessageBubbleAction.reply); + onAction!.call(MessageItemAction.reply); }, ), MenuAction( title: 'forward'.tr(), image: MenuImage.icon(Symbols.forward), callback: () { - onAction!.call(MessageBubbleAction.forward); + onAction!.call(MessageItemAction.forward); }, ), ], @@ -93,27 +97,20 @@ class MessageBubble extends HookConsumerWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), child: Column( - crossAxisAlignment: - isCurrentUser - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (showAvatar && !isCurrentUser) ...[ + if (showAvatar) ...[ Row( spacing: 8, mainAxisSize: MainAxisSize.min, children: [ - if (!isCurrentUser) - ProfilePictureWidget( - fileId: sender.account.profile.pictureId, - radius: 18, - ), + ProfilePictureWidget( + fileId: sender.account.profile.pictureId, + radius: 16, + ), Column( - crossAxisAlignment: - isCurrentUser - ? CrossAxisAlignment.end - : CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, spacing: 2, children: [ Text( @@ -124,41 +121,24 @@ class MessageBubble extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, spacing: 5, children: [ - if (isCurrentUser) - Badge( - label: - Text( - sender.role >= 100 - ? 'permissionOwner' - : sender.role >= 50 - ? 'permissionModerator' - : 'permissionMember', - ).tr(), - ), Text( sender.account.nick, style: Theme.of(context).textTheme.bodySmall, ), - if (!isCurrentUser) - Badge( - label: - Text( - sender.role >= 100 - ? 'permissionOwner' - : sender.role >= 50 - ? 'permissionModerator' - : 'permissionMember', - ).tr(), - ), + Badge( + label: + Text( + sender.role >= 100 + ? 'permissionOwner' + : sender.role >= 50 + ? 'permissionModerator' + : 'permissionMember', + ).tr(), + ), ], ), ], ), - if (isCurrentUser) - ProfilePictureWidget( - fileId: sender.account.profile.pictureId, - radius: 18, - ), ], ), const Gap(4), @@ -169,14 +149,6 @@ class MessageBubble extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - if (isCurrentUser) - _buildMessageIndicators( - context, - textColor, - remoteMessage, - message, - isCurrentUser, - ), Flexible( child: Container( padding: const EdgeInsets.symmetric( @@ -203,9 +175,14 @@ class MessageBubble extends HookConsumerWidget { isReply: false, ), if (remoteMessage.content?.isNotEmpty ?? false) - Text( - remoteMessage.content!, - style: TextStyle(color: textColor), + MarkdownTextContent( + content: remoteMessage.content!, + isSelectable: true, + linkStyle: TextStyle(color: linkColor), + textStyle: TextStyle( + color: textColor, + fontSize: 14, + ), ), if (remoteMessage.attachments.isNotEmpty) CloudFileList( @@ -260,14 +237,13 @@ class MessageBubble extends HookConsumerWidget { ), ), ), - if (!isCurrentUser) - _buildMessageIndicators( - context, - textColor, - remoteMessage, - message, - isCurrentUser, - ), + _buildMessageIndicators( + context, + textColor, + remoteMessage, + message, + isCurrentUser, + ), ], ), ], @@ -288,10 +264,6 @@ class MessageBubble extends HookConsumerWidget { spacing: 4, mainAxisSize: MainAxisSize.min, children: [ - Text( - DateFormat.Hm().format(message.createdAt.toLocal()), - style: TextStyle(fontSize: 11, color: textColor.withOpacity(0.7)), - ), if (remoteMessage.editedAt != null) Text( 'edited'.tr().toLowerCase(), diff --git a/lib/widgets/content/cloud_files.dart b/lib/widgets/content/cloud_files.dart index 9b0f300..153ef33 100644 --- a/lib/widgets/content/cloud_files.dart +++ b/lib/widgets/content/cloud_files.dart @@ -183,47 +183,75 @@ class SplitAvatarWidget extends ConsumerWidget { ), ], ) - else ...[ - Positioned( - top: 0, - left: 0, - child: _buildQuadrant(context, filesId[0], ref, radius), - ), - Positioned( - top: 0, - right: 0, - child: _buildQuadrant(context, filesId[1], ref, radius), - ), - Positioned( - bottom: 0, - left: 0, - child: _buildQuadrant(context, filesId[2], ref, radius), - ), - Positioned( - bottom: 0, - right: 0, - child: - filesId.length > 4 - ? Container( - width: radius, - height: radius, - color: Theme.of(context).colorScheme.primaryContainer, - child: Center( - child: Text( - '+${filesId.length - 3}', - style: TextStyle( - fontSize: radius * 0.4, - color: - Theme.of( - context, - ).colorScheme.onPrimaryContainer, - ), - ), + else + Column( + children: [ + Expanded( + child: Row( + children: [ + Expanded( + child: _buildQuadrant( + context, + filesId[0], + ref, + radius, ), - ) - : _buildQuadrant(context, filesId[3], ref, radius), + ), + Expanded( + child: _buildQuadrant( + context, + filesId[1], + ref, + radius, + ), + ), + ], + ), + ), + Expanded( + child: Row( + children: [ + Expanded( + child: _buildQuadrant( + context, + filesId[2], + ref, + radius, + ), + ), + Expanded( + child: + filesId.length > 4 + ? Container( + color: + Theme.of( + context, + ).colorScheme.primaryContainer, + child: Center( + child: Text( + '+${filesId.length - 3}', + style: TextStyle( + fontSize: radius * 0.4, + color: + Theme.of( + context, + ).colorScheme.onPrimaryContainer, + ), + ), + ), + ) + : _buildQuadrant( + context, + filesId[3], + ref, + radius, + ), + ), + ], + ), + ), + ], ), - ], ], ), ), diff --git a/lib/widgets/content/markdown.dart b/lib/widgets/content/markdown.dart index 7f29d31..b4abdad 100644 --- a/lib/widgets/content/markdown.dart +++ b/lib/widgets/content/markdown.dart @@ -1,14 +1,14 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_highlight/flutter_highlight.dart'; -import 'package:flutter_highlight/theme_map.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:flutter_markdown_latex/flutter_markdown_latex.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/pods/config.dart'; +import 'package:island/widgets/alert.dart'; import 'package:markdown/markdown.dart' as markdown; -import 'package:url_launcher/url_launcher_string.dart'; +import 'package:markdown_widget/markdown_widget.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'image.dart'; @@ -16,14 +16,18 @@ class MarkdownTextContent extends HookConsumerWidget { final String content; final bool isAutoWarp; final TextScaler? textScaler; - final Color? textColor; + final TextStyle? textStyle; + final TextStyle? linkStyle; + final bool isSelectable; const MarkdownTextContent({ super.key, required this.content, this.isAutoWarp = false, this.textScaler, - this.textColor, + this.textStyle, + this.linkStyle, + this.isSelectable = false, }); @override @@ -40,91 +44,111 @@ class MarkdownTextContent extends HookConsumerWidget { return matches.length == 1 && contentWithoutStickers.isEmpty; }, [content]); - return Markdown( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), + final isDark = Theme.of(context).brightness == Brightness.dark; + final config = + isDark ? MarkdownConfig.darkConfig : MarkdownConfig.defaultConfig; + + return MarkdownBlock( data: content, - padding: EdgeInsets.zero, - styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith( - textScaler: textScaler, - p: - textColor != null - ? Theme.of( - context, - ).textTheme.bodyMedium!.copyWith(color: textColor) - : null, - blockquote: TextStyle( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - blockquoteDecoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHigh, - borderRadius: const BorderRadius.all(Radius.circular(4)), - ), - horizontalRuleDecoration: BoxDecoration( - border: Border( - top: BorderSide(width: 1.0, color: Theme.of(context).dividerColor), + selectable: isSelectable, + config: config.copy( + configs: [ + isDark + ? PreConfig.darkConfig.copy( + textStyle: textStyle, + padding: EdgeInsets.zero, + margin: EdgeInsets.zero, + ) + : PreConfig().copy( + textStyle: textStyle, + padding: EdgeInsets.zero, + margin: EdgeInsets.zero, + ), + PConfig( + textStyle: textStyle ?? Theme.of(context).textTheme.bodyMedium!, ), - ), - codeblockDecoration: BoxDecoration( - border: Border.all(color: Theme.of(context).dividerColor, width: 0.3), - borderRadius: const BorderRadius.all(Radius.circular(4)), - color: Theme.of(context).colorScheme.surface.withOpacity(0.5), - ), - code: GoogleFonts.robotoMono(height: 1), - ), - builders: {'latex': LatexElementBuilder(), 'code': HighlightBuilder()}, - softLineBreak: true, - extensionSet: markdown.ExtensionSet( - [ - ...markdown.ExtensionSet.gitHubFlavored.blockSyntaxes, - markdown.CodeBlockSyntax(), - markdown.FencedCodeBlockSyntax(), - LatexBlockSyntax(), - ], - [ - ...markdown.ExtensionSet.gitHubFlavored.inlineSyntaxes, - if (isAutoWarp) markdown.LineBreakSyntax(), - _UserNameCardInlineSyntax(), - _StickerInlineSyntax(ref.read(serverUrlProvider)), - markdown.AutolinkSyntax(), - markdown.AutolinkExtensionSyntax(), - markdown.CodeSyntax(), - LatexInlineSyntax(), - ], - ), - onTapLink: (text, href, title) async { - if (href == null) return; - await launchUrlString(href, mode: LaunchMode.externalApplication); - }, - imageBuilder: (uri, title, alt) { - if (uri.scheme == 'solink') { - switch (uri.host) { - case 'stickers': - final size = doesEnlargeSticker ? 96.0 : 24.0; - return ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(8)), - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainer, - borderRadius: const BorderRadius.all(Radius.circular(8)), + LinkConfig( + style: + linkStyle ?? + TextStyle(color: Theme.of(context).colorScheme.primary), + onTap: (herf) { + final url = Uri.tryParse(herf); + if (url != null) { + if (url.scheme == 'solian') { + context.router.pushPath( + ['', url.host, ...url.pathSegments].join('/'), + ); + return; + } + final whitelistDomains = ['solian.app', 'solsynth.dev']; + if (whitelistDomains.contains(url.host)) { + launchUrl(url, mode: LaunchMode.externalApplication); + return; + } + showConfirmAlert( + 'openLinkConfirmDescription'.tr(args: [url.toString()]), + 'openLinkConfirm'.tr(), + ).then((value) { + if (value) { + launchUrl(url, mode: LaunchMode.externalApplication); + } + }); + } else { + showSnackBar( + context, + 'brokenLink'.tr(args: [herf]), + action: SnackBarAction( + label: 'copyToClipboard'.tr(), + onPressed: () { + Clipboard.setData(ClipboardData(text: herf)); + clearSnackBar(context); + }, ), - child: UniversalImage( - uri: '$baseUrl/stickers/lookup/${uri.pathSegments[0]}/open', - width: size, - height: size, - fit: BoxFit.cover, - noCacheOptimization: true, - ), - ), + ); + } + }, + ), + ImgConfig( + builder: (url, attributes) { + final uri = Uri.parse(url); + if (uri.scheme == 'solian') { + switch (uri.host) { + case 'stickers': + final size = doesEnlargeSticker ? 96.0 : 24.0; + return ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(8)), + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainer, + borderRadius: const BorderRadius.all( + Radius.circular(8), + ), + ), + child: UniversalImage( + uri: + '$baseUrl/stickers/lookup/${uri.pathSegments[0]}/open', + width: size, + height: size, + fit: BoxFit.cover, + noCacheOptimization: true, + ), + ), + ); + } + } + final content = UniversalImage( + uri: uri.toString(), + fit: BoxFit.cover, ); - } - } - final content = UniversalImage(uri: uri.toString(), fit: BoxFit.cover); - if (alt != null) { - return Tooltip(message: alt, child: content); - } - return content; - }, + return content; + }, + ), + ], + ), + generator: MarkdownGenerator( + inlineSyntaxList: [_UserNameCardInlineSyntax(), _StickerInlineSyntax()], + linesMargin: EdgeInsets.zero, + ), ); } } @@ -137,7 +161,7 @@ class _UserNameCardInlineSyntax extends markdown.InlineSyntax { final alias = match[0]!; final anchor = markdown.Element.text('a', alias) ..attributes['href'] = Uri.encodeFull( - 'solink://accounts/${alias.substring(1)}', + 'solian://account/${alias.substring(1)}', ); parser.addNode(anchor); @@ -146,72 +170,15 @@ class _UserNameCardInlineSyntax extends markdown.InlineSyntax { } class _StickerInlineSyntax extends markdown.InlineSyntax { - final String baseUrl; - _StickerInlineSyntax(this.baseUrl) : super(r':([-\w]+):'); + _StickerInlineSyntax() : super(r':([-\w]+):'); @override bool onMatch(markdown.InlineParser parser, Match match) { final placeholder = match[1]!; final image = markdown.Element.text('img', '') - ..attributes['src'] = Uri.encodeFull('solink://stickers/$placeholder'); + ..attributes['src'] = Uri.encodeFull('solian://stickers/$placeholder'); parser.addNode(image); return true; } } - -class HighlightBuilder extends MarkdownElementBuilder { - @override - Widget? visitElementAfterWithContext( - BuildContext context, - markdown.Element element, - TextStyle? preferredStyle, - TextStyle? parentStyle, - ) { - final isDark = Theme.of(context).brightness == Brightness.dark; - - if (element.attributes['class'] == null && - !element.textContent.trim().contains('\n')) { - return Container( - padding: EdgeInsets.only(top: 0.0, right: 4.0, bottom: 1.75, left: 4.0), - margin: EdgeInsets.symmetric(horizontal: 2.0), - color: Colors.black12, - child: Text( - element.textContent, - style: GoogleFonts.robotoMono(textStyle: preferredStyle), - ), - ); - } else { - var language = 'plaintext'; - final pattern = RegExp(r'^language-(.+)$'); - if (element.attributes['class'] != null && - pattern.hasMatch(element.attributes['class'] ?? '')) { - language = - pattern.firstMatch(element.attributes['class'] ?? '')?.group(1) ?? - 'plaintext'; - } - return ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(8)), - child: HighlightView( - element.textContent.trim(), - language: language, - theme: { - ...(isDark ? themeMap['a11y-dark']! : themeMap['a11y-light']!), - 'root': - (isDark - ? TextStyle( - backgroundColor: Colors.transparent, - color: Color(0xfff8f8f2), - ) - : TextStyle( - backgroundColor: Colors.transparent, - color: Color(0xff545454), - )), - }, - padding: EdgeInsets.all(12), - textStyle: GoogleFonts.robotoMono(textStyle: preferredStyle), - ), - ); - } - } -} diff --git a/pubspec.lock b/pubspec.lock index 3a6c839..546e154 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -732,7 +732,7 @@ packages: source: sdk version: "0.0.0" flutter_markdown: - dependency: "direct main" + dependency: transitive description: name: flutter_markdown sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" @@ -1109,6 +1109,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.15" + markdown_widget: + dependency: "direct main" + description: + name: markdown_widget + sha256: b52c13d3ee4d0e60c812e15b0593f142a3b8a2003cde1babb271d001a1dbdc1c + url: "https://pub.dev" + source: hosted + version: "2.3.2+8" matcher: dependency: transitive description: @@ -1501,6 +1509,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + scroll_to_index: + dependency: transitive + description: + name: scroll_to_index + sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176 + url: "https://pub.dev" + source: hosted + version: "3.0.1" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 76a7382..57549c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,7 +48,6 @@ dependencies: freezed_annotation: ^3.0.0 json_annotation: ^4.9.0 flutter_markdown_latex: ^0.3.4 - flutter_markdown: ^0.7.7 markdown: ^7.3.0 flutter_highlight: ^0.7.0 uuid: ^4.5.1 @@ -96,6 +95,7 @@ dependencies: riverpod_paging_utils: ^0.8.0 crypto: ^3.0.6 avatar_stack: ^3.0.0 + markdown_widget: ^2.3.2+8 dev_dependencies: flutter_test: