From 6d92a16a626a6e0f29d81c6992c3432ff3f27535 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 25 Jul 2024 01:18:47 +0800 Subject: [PATCH] :recycle: Refactored auth system --- lib/main.dart | 8 +- lib/providers/account_status.dart | 6 +- lib/providers/auth.dart | 39 ++-- lib/providers/call.dart | 2 +- lib/providers/content/attachment.dart | 6 +- lib/providers/content/channel.dart | 22 +- lib/providers/content/posts.dart | 2 +- lib/providers/content/realm.dart | 4 +- lib/providers/message/adaptor.dart | 4 +- lib/providers/websocket.dart | 4 +- lib/screens/account.dart | 188 +++++++-------- lib/screens/account/notification.dart | 4 +- lib/screens/account/personalize.dart | 24 +- lib/screens/channel/channel_chat.dart | 24 +- lib/screens/channel/channel_detail.dart | 10 +- lib/screens/channel/channel_organize.dart | 2 +- lib/screens/chat.dart | 67 +++--- lib/screens/home.dart | 71 +++--- lib/screens/posts/post_editor.dart | 2 +- lib/screens/realms.dart | 57 ++--- lib/screens/realms/realm_detail.dart | 3 +- lib/screens/realms/realm_organize.dart | 2 +- lib/screens/realms/realm_view.dart | 66 +++--- lib/widgets/account/relative_select.dart | 3 +- .../attachments/attachment_publish.dart | 8 +- lib/widgets/channel/channel_deletion.dart | 4 +- lib/widgets/channel/channel_member.dart | 9 +- lib/widgets/chat/call/call_prejoin.dart | 2 +- lib/widgets/chat/call/chat_call_action.dart | 4 +- lib/widgets/chat/chat_event_action.dart | 9 +- lib/widgets/chat/chat_event_deletion.dart | 2 +- lib/widgets/chat/chat_message_input.dart | 8 +- lib/widgets/current_state_action.dart | 61 ++--- .../navigation/app_navigation_drawer.dart | 216 +++++++++--------- lib/widgets/posts/post_action.dart | 9 +- lib/widgets/posts/post_quick_action.dart | 2 +- lib/widgets/realms/realm_deletion.dart | 4 +- lib/widgets/realms/realm_member.dart | 9 +- 38 files changed, 444 insertions(+), 523 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index efdb30a..1b7af0a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -106,9 +106,11 @@ class SolianApp extends StatelessWidget { Get.lazyPut(() => ChatCallProvider()); final AuthProvider auth = Get.find(); - if (await auth.isAuthorized) { - Get.find().connect(); + auth.refreshAuthorizeStatus().then((_) { + if (auth.isAuthorized.isFalse) return; + + Get.find().connect(); Get.find().refreshAvailableChannel(); try { @@ -118,6 +120,6 @@ class SolianApp extends StatelessWidget { 'pushNotifyRegisterFailed'.trParams({'reason': err.toString()}), ); } - } + }); } } diff --git a/lib/providers/account_status.dart b/lib/providers/account_status.dart index a0fb030..c519348 100644 --- a/lib/providers/account_status.dart +++ b/lib/providers/account_status.dart @@ -33,7 +33,7 @@ class StatusProvider extends GetConnect { Future getCurrentStatus() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('auth'); @@ -53,7 +53,7 @@ class StatusProvider extends GetConnect { DateTime? clearAt, }) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('auth'); @@ -82,7 +82,7 @@ class StatusProvider extends GetConnect { Future clearStatus() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('auth'); diff --git a/lib/providers/auth.dart b/lib/providers/auth.dart index e0025c2..de57dfb 100644 --- a/lib/providers/auth.dart +++ b/lib/providers/auth.dart @@ -60,7 +60,10 @@ class AuthProvider extends GetConnect { @override void onInit() { httpClient.baseUrl = ServiceFinder.buildUrl('auth', null); - loadCredentials(); + refreshAuthorizeStatus().then((_) { + loadCredentials(); + refreshUserProfile(); + }); } Future refreshCredentials() async { @@ -116,7 +119,7 @@ class AuthProvider extends GetConnect { } Future ensureCredentials() async { - if (!await isAuthorized) throw Exception('unauthorized'); + if (isAuthorized.isFalse) throw Exception('unauthorized'); if (credentials == null) await loadCredentials(); if (credentials!.isExpired) { @@ -126,7 +129,7 @@ class AuthProvider extends GetConnect { } Future loadCredentials() async { - if (await isAuthorized) { + if (isAuthorized.isTrue) { final content = await storage.read(key: 'auth_credentials'); credentials = TokenSet.fromJson(jsonDecode(content!)); } @@ -137,7 +140,7 @@ class AuthProvider extends GetConnect { String username, String password, ) async { - _cachedUserProfileResponse = null; + userProfile.value = null; final client = ServiceFinder.configureClient('auth'); @@ -172,6 +175,8 @@ class AuthProvider extends GetConnect { value: jsonEncode(credentials!.toJson()), ); + await refreshUserProfile(); + Get.find().connect(); Get.find().notifyPrefetch(); @@ -179,7 +184,8 @@ class AuthProvider extends GetConnect { } void signout() { - _cachedUserProfileResponse = null; + isAuthorized.value = false; + userProfile.value = null; Get.find().disconnect(); Get.find().notifications.clear(); @@ -195,30 +201,21 @@ class AuthProvider extends GetConnect { // Data Layer - Response? _cachedUserProfileResponse; + RxBool isAuthorized = false.obs; + Rx?> userProfile = Rx(null); - Future get isAuthorized => storage.containsKey(key: 'auth_credentials'); - - Future getProfile({noCache = false}) async { - if (!noCache && _cachedUserProfileResponse != null) { - return _cachedUserProfileResponse!; - } + Future refreshAuthorizeStatus() async { + isAuthorized.value = await storage.containsKey(key: 'auth_credentials'); + } + Future refreshUserProfile() async { final client = configureClient('auth'); final resp = await client.get('/users/me'); if (resp.statusCode != 200) { throw Exception(resp.bodyString); - } else { - _cachedUserProfileResponse = resp; } - return resp; - } - - Future getProfileWithCheck({noCache = false}) async { - if (!await isAuthorized) return null; - - return await getProfile(noCache: noCache); + userProfile.value = resp.body; } } diff --git a/lib/providers/call.dart b/lib/providers/call.dart index 6a87ce4..47c508e 100644 --- a/lib/providers/call.dart +++ b/lib/providers/call.dart @@ -55,7 +55,7 @@ class ChatCallProvider extends GetxController { Future<(String, String)> getRoomToken() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); diff --git a/lib/providers/content/attachment.dart b/lib/providers/content/attachment.dart index fb6d3d4..e046954 100644 --- a/lib/providers/content/attachment.dart +++ b/lib/providers/content/attachment.dart @@ -86,7 +86,7 @@ class AttachmentProvider extends GetConnect { Map? metadata, ) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient( 'files', @@ -130,7 +130,7 @@ class AttachmentProvider extends GetConnect { bool isMature = false, }) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('files'); @@ -152,7 +152,7 @@ class AttachmentProvider extends GetConnect { Future deleteAttachment(int id) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('files'); diff --git a/lib/providers/content/channel.dart b/lib/providers/content/channel.dart index 252e147..ce173ac 100644 --- a/lib/providers/content/channel.dart +++ b/lib/providers/content/channel.dart @@ -16,7 +16,7 @@ class ChannelProvider extends GetxController { Future refreshAvailableChannel() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); isLoading.value = true; final resp = await listAvailableChannel(); @@ -29,7 +29,7 @@ class ChannelProvider extends GetxController { Future getChannel(String alias, {String realm = 'global'}) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -44,7 +44,7 @@ class ChannelProvider extends GetxController { Future getMyChannelProfile(String alias, {String realm = 'global'}) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -59,7 +59,7 @@ class ChannelProvider extends GetxController { Future getChannelOngoingCall(String alias, {String realm = 'global'}) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -75,7 +75,7 @@ class ChannelProvider extends GetxController { Future listChannel({String scope = 'global'}) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -89,7 +89,7 @@ class ChannelProvider extends GetxController { Future listAvailableChannel({String realm = 'global'}) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -103,7 +103,7 @@ class ChannelProvider extends GetxController { Future createChannel(String scope, dynamic payload) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); @@ -118,7 +118,7 @@ class ChannelProvider extends GetxController { Future createDirectChannel( BuildContext context, String scope) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final related = await showModalBottomSheet( useRootNavigator: true, @@ -129,14 +129,14 @@ class ChannelProvider extends GetxController { ); if (related == null) return null; - final prof = await auth.getProfile(); + final prof = auth.userProfile.value!; final client = auth.configureClient('messaging'); final resp = await client.post('/channels/$scope/dm', { 'alias': const Uuid().v4().replaceAll('-', '').substring(0, 12), 'name': 'DM', 'description': - 'A direct message channel between @${prof.body['name']} and @${related.name}', + 'A direct message channel between @${prof['name']} and @${related.name}', 'related_user': related.id, 'is_encrypted': false, }); @@ -149,7 +149,7 @@ class ChannelProvider extends GetxController { Future updateChannel(String scope, int id, dynamic payload) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('messaging'); diff --git a/lib/providers/content/posts.dart b/lib/providers/content/posts.dart index 21a8566..d177db9 100644 --- a/lib/providers/content/posts.dart +++ b/lib/providers/content/posts.dart @@ -27,7 +27,7 @@ class PostProvider extends GetConnect { Future listDraft(int page) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final queries = [ 'take=${10}', diff --git a/lib/providers/content/realm.dart b/lib/providers/content/realm.dart index 7e92b33..96cc5dc 100644 --- a/lib/providers/content/realm.dart +++ b/lib/providers/content/realm.dart @@ -4,7 +4,7 @@ import 'package:solian/providers/auth.dart'; class RealmProvider extends GetxController { Future getRealm(String alias) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('auth'); @@ -18,7 +18,7 @@ class RealmProvider extends GetxController { Future listAvailableRealm() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) throw Exception('unauthorized'); + if (auth.isAuthorized.isFalse) throw Exception('unauthorized'); final client = auth.configureClient('auth'); diff --git a/lib/providers/message/adaptor.dart b/lib/providers/message/adaptor.dart index a23894e..daeeec2 100644 --- a/lib/providers/message/adaptor.dart +++ b/lib/providers/message/adaptor.dart @@ -18,7 +18,7 @@ Future createHistoryDb() async { Future getRemoteEvent(int id, Channel channel, String scope) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return null; + if (auth.isAuthorized.isFalse) return null; final client = auth.configureClient('messaging'); @@ -48,7 +48,7 @@ Future<(List, int)?> getRemoteEvents( } final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return null; + if (auth.isAuthorized.isFalse) return null; final client = auth.configureClient('messaging'); diff --git a/lib/providers/websocket.dart b/lib/providers/websocket.dart index bf83a67..6b1c57a 100644 --- a/lib/providers/websocket.dart +++ b/lib/providers/websocket.dart @@ -102,7 +102,7 @@ class WebSocketProvider extends GetxController { Future notifyPrefetch() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('auth'); @@ -119,7 +119,7 @@ class WebSocketProvider extends GetxController { Future registerPushNotifications() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; late final String? token; late final String provider; diff --git a/lib/screens/account.dart b/lib/screens/account.dart index 27cfdf4..553a89a 100644 --- a/lib/screens/account.dart +++ b/lib/screens/account.dart @@ -29,93 +29,85 @@ class _AccountScreenState extends State { (const Icon(Icons.info_outline), 'about'.tr, 'about'), ]; - final AuthProvider provider = Get.find(); + final AuthProvider auth = Get.find(); return Material( color: Theme.of(context).colorScheme.surface, child: SafeArea( - child: FutureBuilder( - future: provider.isAuthorized, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center(child: CircularProgressIndicator()); - } - - if (snapshot.hasData && snapshot.data == false) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ActionCard( - icon: const Icon(Icons.login, color: Colors.white), - title: 'signin'.tr, - caption: 'signinCaption'.tr, - onTap: () { - showModalBottomSheet( - useRootNavigator: true, - isDismissible: false, - isScrollControlled: true, - context: context, - builder: (context) => const SignInPopup(), - ).then((val) async { - if (val == true) { - await provider.getProfile(noCache: true); - setState(() {}); - } - }); - }, - ), - ActionCard( - icon: const Icon(Icons.add, color: Colors.white), - title: 'signup'.tr, - caption: 'signupCaption'.tr, - onTap: () { - showModalBottomSheet( - useRootNavigator: true, - isDismissible: false, - isScrollControlled: true, - context: context, - builder: (context) => const SignUpPopup(), - ).then((_) { - setState(() {}); - }); - }, - ), - ], - ), - ); - } - - return CenteredContainer( - child: ListView( + child: Obx(() { + if (auth.isAuthorized.isFalse) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - const AccountHeading().paddingOnly(bottom: 8, top: 8), - ...(actionItems.map( - (x) => ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 34), - leading: x.$1, - title: Text(x.$2), - onTap: () { - AppRouter.instance - .pushNamed(x.$3) - .then((_) => setState(() {})); - }, - ), - )), - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 34), - leading: const Icon(Icons.logout), - title: Text('signout'.tr), + ActionCard( + icon: const Icon(Icons.login, color: Colors.white), + title: 'signin'.tr, + caption: 'signinCaption'.tr, onTap: () { - provider.signout(); - setState(() {}); + showModalBottomSheet( + useRootNavigator: true, + isDismissible: false, + isScrollControlled: true, + context: context, + builder: (context) => const SignInPopup(), + ).then((val) async { + if (val == true) { + await auth.refreshUserProfile(); + } + }); + }, + ), + ActionCard( + icon: const Icon(Icons.add, color: Colors.white), + title: 'signup'.tr, + caption: 'signupCaption'.tr, + onTap: () { + showModalBottomSheet( + useRootNavigator: true, + isDismissible: false, + isScrollControlled: true, + context: context, + builder: (context) => const SignUpPopup(), + ).then((_) { + setState(() {}); + }); }, ), ], ), ); - }, - ), + } + + return CenteredContainer( + child: ListView( + children: [ + const AccountHeading().paddingOnly(bottom: 8, top: 8), + ...(actionItems.map( + (x) => ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 34), + leading: x.$1, + title: Text(x.$2), + onTap: () { + AppRouter.instance + .pushNamed(x.$3) + .then((_) => setState(() {})); + }, + ), + )), + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 34), + leading: const Icon(Icons.logout), + title: Text('signout'.tr), + onTap: () { + auth.signout(); + setState(() {}); + }, + ), + ], + ), + ); + }), ), ); } @@ -139,33 +131,25 @@ class _AccountHeadingState extends State { @override Widget build(BuildContext context) { - final AuthProvider provider = Get.find(); + final AuthProvider auth = Get.find(); - return FutureBuilder( - future: provider.getProfile(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const LinearProgressIndicator(); - } - - final prof = snapshot.data!; - return AccountHeadingWidget( - avatar: prof.body['avatar'], - banner: prof.body['banner'], - name: prof.body['name'], - nick: prof.body['nick'], - desc: prof.body['description'], - status: _status, - badges: prof.body['badges'] - ?.map((e) => AccountBadge.fromJson(e)) - .toList() - .cast(), - onEditStatus: () { - setState(() { - _status = Get.find().getCurrentStatus(); - }); - }, - ); + final prof = auth.userProfile.value!; + + return AccountHeadingWidget( + avatar: prof['avatar'], + banner: prof['banner'], + name: prof['name'], + nick: prof['nick'], + desc: prof['description'], + status: _status, + badges: prof['badges'] + ?.map((e) => AccountBadge.fromJson(e)) + .toList() + .cast(), + onEditStatus: () { + setState(() { + _status = Get.find().getCurrentStatus(); + }); }, ); } diff --git a/lib/screens/account/notification.dart b/lib/screens/account/notification.dart index 76fb468..756f477 100644 --- a/lib/screens/account/notification.dart +++ b/lib/screens/account/notification.dart @@ -18,7 +18,7 @@ class _NotificationScreenState extends State { Future markAllRead() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -42,7 +42,7 @@ class _NotificationScreenState extends State { Future markOneRead(notify.Notification element, int index) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final WebSocketProvider provider = Get.find(); diff --git a/lib/screens/account/personalize.dart b/lib/screens/account/personalize.dart index 7ecfce8..b2e8eb4 100644 --- a/lib/screens/account/personalize.dart +++ b/lib/screens/account/personalize.dart @@ -53,17 +53,17 @@ class _PersonalizeScreenState extends State { setState(() => _isBusy = true); final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(noCache: true); + final prof = auth.userProfile.value!; setState(() { - _usernameController.text = prof.body['name']; - _nicknameController.text = prof.body['nick']; - _descriptionController.text = prof.body['description']; - _firstNameController.text = prof.body['profile']['first_name']; - _lastNameController.text = prof.body['profile']['last_name']; - _avatar = prof.body['avatar']; - _banner = prof.body['banner']; - if (prof.body['profile']['birthday'] != null) { - _birthday = DateTime.parse(prof.body['profile']['birthday']); + _usernameController.text = prof['name']; + _nicknameController.text = prof['nick']; + _descriptionController.text = prof['description']; + _firstNameController.text = prof['profile']['first_name']; + _lastNameController.text = prof['profile']['last_name']; + _avatar = prof['avatar']; + _banner = prof['banner']; + if (prof['profile']['birthday'] != null) { + _birthday = DateTime.parse(prof['profile']['birthday']); _birthdayController.text = DateFormat('yyyy-MM-dd').format(_birthday!.toLocal()); } @@ -74,7 +74,7 @@ class _PersonalizeScreenState extends State { Future updateImage(String position) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final image = await _imagePicker.pickImage(source: ImageSource.gallery); if (image == null) return; @@ -120,7 +120,7 @@ class _PersonalizeScreenState extends State { void updatePersonalize() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); diff --git a/lib/screens/channel/channel_chat.dart b/lib/screens/channel/channel_chat.dart index 92b3ea8..b67b224 100644 --- a/lib/screens/channel/channel_chat.dart +++ b/lib/screens/channel/channel_chat.dart @@ -44,7 +44,7 @@ class _ChannelChatScreenState extends State { bool _isBusy = false; int? _accountId; - String? _overrideAlias; + String? _newAlias; Channel? _channel; Call? _ongoingCall; @@ -53,26 +53,20 @@ class _ChannelChatScreenState extends State { late final ChatEventController _chatController; - getProfile() async { - final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(); - _accountId = prof.body['id']; - } - - getChannel({String? overrideAlias}) async { + getChannel({String? alias}) async { final ChannelProvider provider = Get.find(); setState(() => _isBusy = true); - if (overrideAlias != null) _overrideAlias = overrideAlias; + if (alias != null) _newAlias = alias; try { final resp = await provider.getChannel( - _overrideAlias ?? widget.alias, + _newAlias ?? widget.alias, realm: widget.realm, ); final respProfile = await provider.getMyChannelProfile( - _overrideAlias ?? widget.alias, + _newAlias ?? widget.alias, realm: widget.realm, ); setState(() { @@ -93,7 +87,7 @@ class _ChannelChatScreenState extends State { try { final resp = await provider.getChannelOngoingCall( - _overrideAlias ?? widget.alias, + _newAlias ?? widget.alias, realm: widget.realm, ); if (resp != null) { @@ -150,16 +144,16 @@ class _ChannelChatScreenState extends State { @override void initState() { + _accountId = Get.find().userProfile.value!['id']; + _chatController = ChatEventController(); _chatController.initialize(); getChannel().then((_) { _chatController.getEvents(_channel!, widget.realm); - listenMessages(); }); - getProfile(); getOngoingCall(); super.initState(); @@ -225,7 +219,7 @@ class _ChannelChatScreenState extends State { if (value == false) AppRouter.instance.pop(); if (value != null) { final resp = Channel.fromJson(value as Map); - getChannel(overrideAlias: resp.alias); + getChannel(alias: resp.alias); } }); }, diff --git a/lib/screens/channel/channel_detail.dart b/lib/screens/channel/channel_detail.dart index 2d1a224..79fd6ec 100644 --- a/lib/screens/channel/channel_detail.dart +++ b/lib/screens/channel/channel_detail.dart @@ -41,9 +41,9 @@ class _ChannelDetailScreenState extends State { void checkOwner() async { final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(); setState(() { - _isOwned = prof.body['id'] == widget.channel.account.externalId; + _isOwned = + auth.userProfile.value!['id'] == widget.channel.account.externalId; }); } @@ -75,14 +75,14 @@ class _ChannelDetailScreenState extends State { void applyProfileChanges() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); final client = auth.configureClient('messaging'); - final resp = await client.put( - '/channels/${widget.realm}/${widget.channel.alias}/members/me', { + final resp = await client + .put('/channels/${widget.realm}/${widget.channel.alias}/members/me', { 'nick': null, 'notify_level': _notifyLevel, }); diff --git a/lib/screens/channel/channel_organize.dart b/lib/screens/channel/channel_organize.dart index d85a2b2..386cab7 100644 --- a/lib/screens/channel/channel_organize.dart +++ b/lib/screens/channel/channel_organize.dart @@ -39,7 +39,7 @@ class _ChannelOrganizeScreenState extends State { void applyChannel() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; if (_aliasController.value.text.isEmpty) randomizeAlias(); diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index 21bcbda..4753dca 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -97,49 +97,42 @@ class _ChatScreenState extends State { ), ], ), - body: FutureBuilder( - future: auth.getProfileWithCheck(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator(), - ); - } else if (snapshot.data == null) { - return SigninRequiredOverlay( - onSignedIn: () => _channels.refreshAvailableChannel(), - ); - } + body: Obx(() { + if (auth.isAuthorized.isFalse) { + return SigninRequiredOverlay( + onSignedIn: () => _channels.refreshAvailableChannel(), + ); + } - final selfId = snapshot.data!.body['id']; + final selfId = auth.userProfile.value!['id']; - return Column( - children: [ - Obx(() { - if (_channels.isLoading.isFalse) { - return const SizedBox(); - } else { - return const LinearProgressIndicator(); - } - }), - const ChatCallCurrentIndicator(), - Expanded( - child: CenteredContainer( - child: RefreshIndicator( - onRefresh: _channels.refreshAvailableChannel, - child: Obx( - () => ChannelListWidget( - noCategory: true, - channels: _channels.directChannels, - selfId: selfId, - ), + return Column( + children: [ + Obx(() { + if (_channels.isLoading.isFalse) { + return const SizedBox(); + } else { + return const LinearProgressIndicator(); + } + }), + const ChatCallCurrentIndicator(), + Expanded( + child: CenteredContainer( + child: RefreshIndicator( + onRefresh: _channels.refreshAvailableChannel, + child: Obx( + () => ChannelListWidget( + noCategory: true, + channels: _channels.directChannels, + selfId: selfId, ), ), ), ), - ], - ); - }, - ), + ), + ], + ); + }), ), ); } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 101eb50..ce9b86b 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -107,42 +107,39 @@ class FeedCreationButton extends StatelessWidget { Widget build(BuildContext context) { final AuthProvider auth = Get.find(); - return FutureBuilder( - future: auth.isAuthorized, - builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data == true) { - return PopupMenuButton( - icon: const Icon(Icons.edit_square), - itemBuilder: (BuildContext context) => [ - PopupMenuItem( - child: ListTile( - title: Text('postEditor'.tr), - leading: const Icon(Icons.article), - contentPadding: const EdgeInsets.symmetric(horizontal: 8), - ), - onTap: () { - AppRouter.instance.pushNamed('postEditor').then((val) { - if (val != null && onCreated != null) { - onCreated!(); - } - }); - }, - ), - if (!hideDraftBox) - PopupMenuItem( - child: ListTile( - title: Text('draftBoxOpen'.tr), - leading: const Icon(Icons.drafts), - contentPadding: const EdgeInsets.symmetric(horizontal: 8), - ), - onTap: () { - AppRouter.instance.pushNamed('draftBox'); - }, - ), - ], - ); - } - return const SizedBox(); - }); + if (auth.isAuthorized.isFalse) { + return const SizedBox(); + } + + return PopupMenuButton( + icon: const Icon(Icons.edit_square), + itemBuilder: (BuildContext context) => [ + PopupMenuItem( + child: ListTile( + title: Text('postEditor'.tr), + leading: const Icon(Icons.article), + contentPadding: const EdgeInsets.symmetric(horizontal: 8), + ), + onTap: () { + AppRouter.instance.pushNamed('postEditor').then((val) { + if (val != null && onCreated != null) { + onCreated!(); + } + }); + }, + ), + if (!hideDraftBox) + PopupMenuItem( + child: ListTile( + title: Text('draftBoxOpen'.tr), + leading: const Icon(Icons.drafts), + contentPadding: const EdgeInsets.symmetric(horizontal: 8), + ), + onTap: () { + AppRouter.instance.pushNamed('draftBox'); + }, + ), + ], + ); } } diff --git a/lib/screens/posts/post_editor.dart b/lib/screens/posts/post_editor.dart index 11f46a1..2905368 100644 --- a/lib/screens/posts/post_editor.dart +++ b/lib/screens/posts/post_editor.dart @@ -69,7 +69,7 @@ class _PostPublishScreenState extends State { void applyPost() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; if (_contentController.value.text.isEmpty) return; setState(() => _isBusy = true); diff --git a/lib/screens/realms.dart b/lib/screens/realms.dart index 2c6ff75..070e110 100644 --- a/lib/screens/realms.dart +++ b/lib/screens/realms.dart @@ -28,7 +28,7 @@ class _RealmListScreenState extends State { getRealms() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -81,42 +81,33 @@ class _RealmListScreenState extends State { ), ], ), - body: FutureBuilder( - future: auth.isAuthorized, - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator(), - ); - } else if (snapshot.data == false) { - return SigninRequiredOverlay( - onSignedIn: () { - getRealms(); - }, - ); - } + body: Obx(() { + if (auth.isAuthorized.isFalse) { + return SigninRequiredOverlay( + onSignedIn: () => getRealms(), + ); + } - return Column( - children: [ - if (_isBusy) const LinearProgressIndicator().animate().scaleX(), - Expanded( - child: CenteredContainer( - child: RefreshIndicator( - onRefresh: () => getRealms(), - child: ListView.builder( - itemCount: _realms.length, - itemBuilder: (context, index) { - final element = _realms[index]; - return buildRealm(element); - }, - ), + return Column( + children: [ + if (_isBusy) const LinearProgressIndicator().animate().scaleX(), + Expanded( + child: CenteredContainer( + child: RefreshIndicator( + onRefresh: () => getRealms(), + child: ListView.builder( + itemCount: _realms.length, + itemBuilder: (context, index) { + final element = _realms[index]; + return buildRealm(element); + }, ), ), ), - ], - ); - }, - ), + ), + ], + ); + }), ), ); } diff --git a/lib/screens/realms/realm_detail.dart b/lib/screens/realms/realm_detail.dart index 9ba7a70..d083c83 100644 --- a/lib/screens/realms/realm_detail.dart +++ b/lib/screens/realms/realm_detail.dart @@ -26,9 +26,8 @@ class _RealmDetailScreenState extends State { void checkOwner() async { final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(); setState(() { - _isOwned = prof.body['id'] == widget.realm.accountId; + _isOwned = auth.userProfile.value!['id'] == widget.realm.accountId; }); } diff --git a/lib/screens/realms/realm_organize.dart b/lib/screens/realms/realm_organize.dart index 68a3fbf..4e7a98d 100644 --- a/lib/screens/realms/realm_organize.dart +++ b/lib/screens/realms/realm_organize.dart @@ -37,7 +37,7 @@ class _RealmOrganizeScreenState extends State { void applyRealm() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; if (_aliasController.value.text.isEmpty) randomizeAlias(); diff --git a/lib/screens/realms/realm_view.dart b/lib/screens/realms/realm_view.dart index 51fd581..2690c4f 100644 --- a/lib/screens/realms/realm_view.dart +++ b/lib/screens/realms/realm_view.dart @@ -244,44 +244,38 @@ class RealmChannelListWidget extends StatelessWidget { Widget build(BuildContext context) { final AuthProvider auth = Get.find(); - return FutureBuilder( - future: auth.getProfile(), - builder: (context, snapshot) { - return RefreshIndicator( - onRefresh: onRefresh, - child: Column( - children: [ - ListTile( - leading: const Icon(Icons.add_box), - contentPadding: const EdgeInsets.only(left: 32, right: 8), - tileColor: Theme.of(context).colorScheme.surfaceContainer, - title: Text('channelNew'.tr), - subtitle: Text( - 'channelNewInRealmHint' - .trParams({'realm': '#${realm.alias}'}), - ), - onTap: () { - AppRouter.instance - .pushNamed( - 'channelOrganizing', - extra: ChannelOrganizeArguments(realm: realm), - ) - .then((value) { - if (value != null) onRefresh(); - }); - }, - ), - Expanded( - child: ChannelListWidget( - channels: channels, - selfId: snapshot.data?.body['id'] ?? 0, - noCategory: true, - ), + return RefreshIndicator( + onRefresh: onRefresh, + child: Column( + children: [ + ListTile( + leading: const Icon(Icons.add_box), + contentPadding: const EdgeInsets.only(left: 32, right: 8), + tileColor: Theme.of(context).colorScheme.surfaceContainer, + title: Text('channelNew'.tr), + subtitle: Text( + 'channelNewInRealmHint'.trParams({'realm': '#${realm.alias}'}), + ), + onTap: () { + AppRouter.instance + .pushNamed( + 'channelOrganizing', + extra: ChannelOrganizeArguments(realm: realm), ) - ], + .then((value) { + if (value != null) onRefresh(); + }); + }, ), - ); - }, + Expanded( + child: ChannelListWidget( + channels: channels, + selfId: auth.userProfile.value!['id'], + noCategory: true, + ), + ) + ], + ), ); } } diff --git a/lib/widgets/account/relative_select.dart b/lib/widgets/account/relative_select.dart index f6cf379..8218938 100644 --- a/lib/widgets/account/relative_select.dart +++ b/lib/widgets/account/relative_select.dart @@ -23,8 +23,7 @@ class _RelativeSelectorState extends State { getFriends() async { final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(); - _accountId = prof.body['id']; + _accountId = auth.userProfile.value!['id']; final RelationshipProvider provider = Get.find(); final resp = await provider.listRelationWithStatus(1); diff --git a/lib/widgets/attachments/attachment_publish.dart b/lib/widgets/attachments/attachment_publish.dart index b2e0f53..0c600d5 100644 --- a/lib/widgets/attachments/attachment_publish.dart +++ b/lib/widgets/attachments/attachment_publish.dart @@ -44,7 +44,7 @@ class _AttachmentPublishPopupState extends State { Future pickPhotoToUpload() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final medias = await _imagePicker.pickMultiImage(); if (medias.isEmpty) return; @@ -73,7 +73,7 @@ class _AttachmentPublishPopupState extends State { Future pickVideoToUpload() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final media = await _imagePicker.pickVideo(source: ImageSource.gallery); if (media == null) return; @@ -96,7 +96,7 @@ class _AttachmentPublishPopupState extends State { Future pickFileToUpload() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; FilePickerResult? result = await FilePicker.platform.pickFiles( allowMultiple: true, @@ -121,7 +121,7 @@ class _AttachmentPublishPopupState extends State { Future takeMediaToUpload(bool isVideo) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; XFile? media; if (isVideo) { diff --git a/lib/widgets/channel/channel_deletion.dart b/lib/widgets/channel/channel_deletion.dart index d0a85f0..5f4fc13 100644 --- a/lib/widgets/channel/channel_deletion.dart +++ b/lib/widgets/channel/channel_deletion.dart @@ -25,7 +25,7 @@ class _ChannelDeletionDialogState extends State { Future deleteChannel() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -44,7 +44,7 @@ class _ChannelDeletionDialogState extends State { Future leaveChannel() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); diff --git a/lib/widgets/channel/channel_member.dart b/lib/widgets/channel/channel_member.dart index f71975d..9f8ef7c 100644 --- a/lib/widgets/channel/channel_member.dart +++ b/lib/widgets/channel/channel_member.dart @@ -31,10 +31,9 @@ class _ChannelMemberListPopupState extends State { void getProfile() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; - final prof = await auth.getProfile(); - setState(() => _accountId = prof.body['id']); + setState(() => _accountId = auth.userProfile.value!['id']); } void getMembers() async { @@ -72,7 +71,7 @@ class _ChannelMemberListPopupState extends State { void addMember(String username) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -93,7 +92,7 @@ class _ChannelMemberListPopupState extends State { void removeMember(ChannelMember item) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); diff --git a/lib/widgets/chat/call/call_prejoin.dart b/lib/widgets/chat/call/call_prejoin.dart index 2dedbbf..82beabe 100644 --- a/lib/widgets/chat/call/call_prejoin.dart +++ b/lib/widgets/chat/call/call_prejoin.dart @@ -28,7 +28,7 @@ class _ChatCallPrejoinPopupState extends State { void performJoin() async { final AuthProvider auth = Get.find(); final ChatCallProvider provider = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); diff --git a/lib/widgets/chat/call/chat_call_action.dart b/lib/widgets/chat/call/chat_call_action.dart index f9e870d..feb3bd3 100644 --- a/lib/widgets/chat/call/chat_call_action.dart +++ b/lib/widgets/chat/call/chat_call_action.dart @@ -31,7 +31,7 @@ class _ChatCallButtonState extends State { Future makeCall() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('messaging'); @@ -55,7 +55,7 @@ class _ChatCallButtonState extends State { Future endsCall() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('messaging'); diff --git a/lib/widgets/chat/chat_event_action.dart b/lib/widgets/chat/chat_event_action.dart index e095106..708e7fc 100644 --- a/lib/widgets/chat/chat_event_action.dart +++ b/lib/widgets/chat/chat_event_action.dart @@ -35,15 +35,14 @@ class _ChatEventActionState extends State { void checkAbleToModifyContent() async { if (!['messages.new'].contains(widget.item.type)) return; - final AuthProvider provider = Get.find(); - if (!await provider.isAuthorized) return; + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); - final prof = await provider.getProfile(); setState(() { - _canModifyContent = - prof.body?['id'] == widget.item.sender.account.externalId; + _canModifyContent = auth.userProfile.value!['id'] == + widget.item.sender.account.externalId; _isBusy = false; }); } diff --git a/lib/widgets/chat/chat_event_deletion.dart b/lib/widgets/chat/chat_event_deletion.dart index bb38e92..9645b2a 100644 --- a/lib/widgets/chat/chat_event_deletion.dart +++ b/lib/widgets/chat/chat_event_deletion.dart @@ -28,7 +28,7 @@ class _ChatEventDeletionDialogState extends State { void performAction() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('messaging'); diff --git a/lib/widgets/chat/chat_message_input.dart b/lib/widgets/chat/chat_message_input.dart index bee48bd..dea6695 100644 --- a/lib/widgets/chat/chat_message_input.dart +++ b/lib/widgets/chat/chat_message_input.dart @@ -59,8 +59,8 @@ class _ChatMessageInputState extends State { _focusNode.requestFocus(); final AuthProvider auth = Get.find(); - final prof = await auth.getProfile(); - if (!await auth.isAuthorized) return; + final prof = auth.userProfile.value!; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('messaging'); @@ -87,9 +87,9 @@ class _ChatMessageInputState extends State { id: 0, createdAt: DateTime.now(), updatedAt: DateTime.now(), - account: Account.fromJson(prof.body), + account: Account.fromJson(prof), channelId: widget.channel.id, - accountId: prof.body['id'], + accountId: prof['id'], notify: 0, ); final message = Event( diff --git a/lib/widgets/current_state_action.dart b/lib/widgets/current_state_action.dart index 1f65469..439b5fd 100644 --- a/lib/widgets/current_state_action.dart +++ b/lib/widgets/current_state_action.dart @@ -17,47 +17,30 @@ class BackgroundStateWidget extends StatelessWidget { final connecting = ws.isConnecting.isTrue; return Row(children: [ - if (disconnected && !connecting) - FutureBuilder( - future: auth.isAuthorized, - builder: (context, snapshot) { - if (!snapshot.hasData || snapshot.data == false) { - return const SizedBox(); - } - return IconButton( - tooltip: [ - if (ws.isConnected.isFalse) - 'Lost Connection with Solar Network...', - ].join('\n'), - icon: const Icon(Icons.wifi_off) - .animate(onPlay: (c) => c.repeat()) - .fadeIn(duration: 800.ms) - .then() - .fadeOut(duration: 800.ms), - onPressed: () { - if (ws.isConnected.isFalse) ws.connect(); - }, - ); + if (auth.isAuthorized.isTrue && disconnected && !connecting) + IconButton( + tooltip: [ + if (ws.isConnected.isFalse) + 'Lost Connection with Solar Network...', + ].join('\n'), + icon: const Icon(Icons.wifi_off) + .animate(onPlay: (c) => c.repeat()) + .fadeIn(duration: 800.ms) + .then() + .fadeOut(duration: 800.ms), + onPressed: () { + if (ws.isConnected.isFalse) ws.connect(); }, ), - if (connecting) - FutureBuilder( - future: auth.isAuthorized, - builder: (context, snapshot) { - if (!snapshot.hasData || snapshot.data == false) { - return const SizedBox(); - } - return IconButton( - tooltip: [ - if (ws.isConnecting.isTrue) - 'Waiting Solar Network Connection...', - ].join('\n'), - icon: const Icon(Icons.sync) - .animate(onPlay: (c) => c.repeat()) - .rotate(duration: 1850.ms, begin: 1, end: 0), - onPressed: () {}, - ); - }, + if (auth.isAuthorized.isTrue && connecting) + IconButton( + tooltip: [ + if (ws.isConnecting.isTrue) 'Waiting Solar Network Connection...', + ].join('\n'), + icon: const Icon(Icons.sync) + .animate(onPlay: (c) => c.repeat()) + .rotate(duration: 1850.ms, begin: 1, end: 0), + onPressed: () {}, ), ]); }); diff --git a/lib/widgets/navigation/app_navigation_drawer.dart b/lib/widgets/navigation/app_navigation_drawer.dart index abb7a98..182f2e9 100644 --- a/lib/widgets/navigation/app_navigation_drawer.dart +++ b/lib/widgets/navigation/app_navigation_drawer.dart @@ -27,7 +27,6 @@ class _AppNavigationDrawerState extends State { AccountStatus? _accountStatus; - late final AuthProvider _auth; late final ChannelProvider _channels; void getStatus() async { @@ -57,7 +56,6 @@ class _AppNavigationDrawerState extends State { @override void initState() { super.initState(); - _auth = Get.find(); _channels = Get.find(); detectSelectedIndex(); getStatus(); @@ -83,86 +81,83 @@ class _AppNavigationDrawerState extends State { closeDrawer(); }, children: [ - FutureBuilder( - future: auth.getProfileWithCheck(), - builder: (context, snapshot) { - if (snapshot.data == null) { - return ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 28), - leading: const Icon(Icons.account_circle), - title: Text('guest'.tr), - subtitle: Text('unsignedIn'.tr), - onTap: () { - AppRouter.instance.goNamed('account'); - setState(() => _selectedIndex = null); - closeDrawer(); - }, - ); - } - + Obx(() { + if (auth.isAuthorized.isFalse) { return ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 24), - title: Text( - snapshot.data!.body['nick'], - maxLines: 1, - overflow: TextOverflow.fade, - ), - subtitle: Builder( - builder: (context) { - if (_accountStatus == null) { - return Text('loading'.tr); - } - final info = StatusProvider.determineStatus( - _accountStatus!, - ); - return Text( - info.$3, - maxLines: 1, - overflow: TextOverflow.fade, - ); - }, - ), - leading: Builder(builder: (context) { - final badgeColor = _accountStatus != null - ? StatusProvider.determineStatus( - _accountStatus!, - ).$2 - : Colors.grey; - - return badges.Badge( - showBadge: _accountStatus != null, - badgeStyle: badges.BadgeStyle(badgeColor: badgeColor), - position: badges.BadgePosition.bottomEnd( - bottom: 0, - end: -2, - ), - child: AccountAvatar( - content: snapshot.data!.body['avatar'], - ), - ); - }), - trailing: IconButton( - icon: const Icon(Icons.face_retouching_natural), - onPressed: () { - showModalBottomSheet( - useRootNavigator: true, - context: context, - builder: (context) => AccountStatusAction( - currentStatus: _accountStatus!.status, - ), - ).then((val) { - if (val == true) getStatus(); - }); - }, - ), + contentPadding: const EdgeInsets.symmetric(horizontal: 28), + leading: const Icon(Icons.account_circle), + title: Text('guest'.tr), + subtitle: Text('unsignedIn'.tr), onTap: () { AppRouter.instance.goNamed('account'); setState(() => _selectedIndex = null); closeDrawer(); }, ); - }, - ).paddingOnly(top: 8), + } + + return ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 24), + title: Text( + auth.userProfile.value!['nick'], + maxLines: 1, + overflow: TextOverflow.fade, + ), + subtitle: Builder( + builder: (context) { + if (_accountStatus == null) { + return Text('loading'.tr); + } + final info = StatusProvider.determineStatus( + _accountStatus!, + ); + return Text( + info.$3, + maxLines: 1, + overflow: TextOverflow.fade, + ); + }, + ), + leading: Builder(builder: (context) { + final badgeColor = _accountStatus != null + ? StatusProvider.determineStatus( + _accountStatus!, + ).$2 + : Colors.grey; + + return badges.Badge( + showBadge: _accountStatus != null, + badgeStyle: badges.BadgeStyle(badgeColor: badgeColor), + position: badges.BadgePosition.bottomEnd( + bottom: 0, + end: -2, + ), + child: AccountAvatar( + content: auth.userProfile.value!['avatar'], + ), + ); + }), + trailing: IconButton( + icon: const Icon(Icons.face_retouching_natural), + onPressed: () { + showModalBottomSheet( + useRootNavigator: true, + context: context, + builder: (context) => AccountStatusAction( + currentStatus: _accountStatus!.status, + ), + ).then((val) { + if (val == true) getStatus(); + }); + }, + ), + onTap: () { + AppRouter.instance.goNamed('account'); + setState(() => _selectedIndex = null); + closeDrawer(); + }, + ); + }).paddingOnly(top: 8), const Divider(thickness: 0.3, height: 1).paddingOnly( bottom: 12, top: 8, @@ -176,49 +171,46 @@ class _AppNavigationDrawerState extends State { const Divider(thickness: 0.3, height: 1).paddingOnly( top: 12, ), - FutureBuilder( - future: _auth.getProfileWithCheck(), - builder: (context, snapshot) { - if (!snapshot.hasData || snapshot.data == null) { - return const SizedBox(); - } + Obx(() { + if (auth.isAuthorized.isFalse) { + return const SizedBox(); + } - final selfId = snapshot.data!.body['id']; + final selfId = auth.userProfile.value!['id']; - return Column( - children: [ - Theme( - data: Theme.of(context).copyWith(dividerColor: Colors.transparent), - child: ExpansionTile( - title: Text('channels'.tr), - tilePadding: const EdgeInsets.symmetric(horizontal: 24), - children: [ - Obx( - () => SizedBox( - height: 360, - child: RefreshIndicator( - onRefresh: () => - _channels.refreshAvailableChannel(), - child: ChannelListWidget( - channels: _channels.groupChannels, - selfId: selfId, - isDense: true, - useReplace: true, - onSelected: (_) { - setState(() => _selectedIndex = null); - closeDrawer(); - }, - ), + return Column( + children: [ + Theme( + data: Theme.of(context) + .copyWith(dividerColor: Colors.transparent), + child: ExpansionTile( + title: Text('channels'.tr), + tilePadding: const EdgeInsets.symmetric(horizontal: 24), + children: [ + Obx( + () => SizedBox( + height: 360, + child: RefreshIndicator( + onRefresh: () => _channels.refreshAvailableChannel(), + child: ChannelListWidget( + channels: _channels.groupChannels, + selfId: selfId, + isDense: true, + useReplace: true, + onSelected: (_) { + setState(() => _selectedIndex = null); + closeDrawer(); + }, ), ), ), - ], - ), + ), + ], ), - ], - ); - }, - ), + ), + ], + ); + }), ], ); } diff --git a/lib/widgets/posts/post_action.dart b/lib/widgets/posts/post_action.dart index cad8de3..ec5b531 100644 --- a/lib/widgets/posts/post_action.dart +++ b/lib/widgets/posts/post_action.dart @@ -25,14 +25,13 @@ class _PostActionState extends State { bool _canModifyContent = false; void checkAbleToModifyContent() async { - final AuthProvider provider = Get.find(); - if (!await provider.isAuthorized) return; + final AuthProvider auth = Get.find(); + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); - final prof = await provider.getProfile(); setState(() { - _canModifyContent = prof.body?['id'] == widget.item.author.externalId; + _canModifyContent = auth.userProfile.value!['id'] == widget.item.author.externalId; _isBusy = false; }); } @@ -153,7 +152,7 @@ class _PostDeletionDialogState extends State { void performAction() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('interactive'); diff --git a/lib/widgets/posts/post_quick_action.dart b/lib/widgets/posts/post_quick_action.dart index bebdf67..91c7747 100644 --- a/lib/widgets/posts/post_quick_action.dart +++ b/lib/widgets/posts/post_quick_action.dart @@ -47,7 +47,7 @@ class _PostQuickActionState extends State { final AuthProvider auth = Get.find(); if (_isSubmitting) return; - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; final client = auth.configureClient('interactive'); diff --git a/lib/widgets/realms/realm_deletion.dart b/lib/widgets/realms/realm_deletion.dart index 9022928..a7ffe34 100644 --- a/lib/widgets/realms/realm_deletion.dart +++ b/lib/widgets/realms/realm_deletion.dart @@ -23,7 +23,7 @@ class _RealmDeletionDialogState extends State { Future deleteRealm() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -41,7 +41,7 @@ class _RealmDeletionDialogState extends State { Future leaveRealm() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); diff --git a/lib/widgets/realms/realm_member.dart b/lib/widgets/realms/realm_member.dart index d091c01..864b469 100644 --- a/lib/widgets/realms/realm_member.dart +++ b/lib/widgets/realms/realm_member.dart @@ -29,10 +29,9 @@ class _RealmMemberListPopupState extends State { void getProfile() async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; - final prof = await auth.getProfile(); - setState(() => _accountId = prof.body['id']); + setState(() => _accountId = auth.userProfile.value!['id']); } void getMembers() async { @@ -69,7 +68,7 @@ class _RealmMemberListPopupState extends State { void addMember(String username) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true); @@ -90,7 +89,7 @@ class _RealmMemberListPopupState extends State { void removeMember(RealmMember item) async { final AuthProvider auth = Get.find(); - if (!await auth.isAuthorized) return; + if (auth.isAuthorized.isFalse) return; setState(() => _isBusy = true);