From bdc13978c3a68ccb44cbf3a8780a1a96ea45fe7b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Wed, 28 May 2025 23:21:13 +0800 Subject: [PATCH] :alien: Support the new Dyson Token --- lib/database/message_repository.dart | 4 +- lib/models/auth.dart | 11 +- lib/models/auth.freezed.dart | 85 +++++++-------- lib/models/auth.g.dart | 15 +-- lib/pods/network.dart | 120 +++------------------ lib/pods/userinfo.dart | 2 +- lib/pods/websocket.dart | 13 +-- lib/screens/account.dart | 4 +- lib/screens/account/me/update.dart | 13 +-- lib/screens/auth/login.dart | 7 +- lib/screens/chat/chat.dart | 13 +-- lib/screens/chat/room.dart | 13 +-- lib/screens/chat/room.g.dart | 2 +- lib/screens/creators/publishers.dart | 13 +-- lib/screens/notification.g.dart | 2 +- lib/screens/posts/compose.dart | 108 ++++++++++--------- lib/screens/posts/pub_profile.g.dart | 2 +- lib/screens/realm/realms.dart | 13 +-- lib/widgets/content/cloud_file_picker.dart | 13 +-- lib/widgets/content/video.native.dart | 13 +-- 20 files changed, 157 insertions(+), 309 deletions(-) diff --git a/lib/database/message_repository.dart b/lib/database/message_repository.dart index 2c202fd..aeb40f7 100644 --- a/lib/database/message_repository.dart +++ b/lib/database/message_repository.dart @@ -186,7 +186,7 @@ class MessageRepository { } Future sendMessage( - String atk, + String token, String baseUrl, String roomId, String content, @@ -232,7 +232,7 @@ class MessageRepository { final cloudFile = await putMediaToCloud( fileData: attachments[idx].data, - atk: atk, + atk: token, baseUrl: baseUrl, filename: attachments[idx].data.name ?? 'Post media', mimetype: diff --git a/lib/models/auth.dart b/lib/models/auth.dart index 3398787..b2078d4 100644 --- a/lib/models/auth.dart +++ b/lib/models/auth.dart @@ -4,14 +4,11 @@ part 'auth.freezed.dart'; part 'auth.g.dart'; @freezed -sealed class AppTokenPair with _$AppTokenPair { - const factory AppTokenPair({ - required String accessToken, - required String refreshToken, - }) = _AppTokenPair; +sealed class AppToken with _$AppToken { + const factory AppToken({required String token}) = _AppToken; - factory AppTokenPair.fromJson(Map json) => - _$AppTokenPairFromJson(json); + factory AppToken.fromJson(Map json) => + _$AppTokenFromJson(json); } @freezed diff --git a/lib/models/auth.freezed.dart b/lib/models/auth.freezed.dart index 6346ce0..e44a1ba 100644 --- a/lib/models/auth.freezed.dart +++ b/lib/models/auth.freezed.dart @@ -14,42 +14,42 @@ part of 'auth.dart'; T _$identity(T value) => value; /// @nodoc -mixin _$AppTokenPair { +mixin _$AppToken { - String get accessToken; String get refreshToken; -/// Create a copy of AppTokenPair + String get token; +/// Create a copy of AppToken /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @pragma('vm:prefer-inline') -$AppTokenPairCopyWith get copyWith => _$AppTokenPairCopyWithImpl(this as AppTokenPair, _$identity); +$AppTokenCopyWith get copyWith => _$AppTokenCopyWithImpl(this as AppToken, _$identity); - /// Serializes this AppTokenPair to a JSON map. + /// Serializes this AppToken to a JSON map. Map toJson(); @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is AppTokenPair&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is AppToken&&(identical(other.token, token) || other.token == token)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,accessToken,refreshToken); +int get hashCode => Object.hash(runtimeType,token); @override String toString() { - return 'AppTokenPair(accessToken: $accessToken, refreshToken: $refreshToken)'; + return 'AppToken(token: $token)'; } } /// @nodoc -abstract mixin class $AppTokenPairCopyWith<$Res> { - factory $AppTokenPairCopyWith(AppTokenPair value, $Res Function(AppTokenPair) _then) = _$AppTokenPairCopyWithImpl; +abstract mixin class $AppTokenCopyWith<$Res> { + factory $AppTokenCopyWith(AppToken value, $Res Function(AppToken) _then) = _$AppTokenCopyWithImpl; @useResult $Res call({ - String accessToken, String refreshToken + String token }); @@ -57,19 +57,18 @@ $Res call({ } /// @nodoc -class _$AppTokenPairCopyWithImpl<$Res> - implements $AppTokenPairCopyWith<$Res> { - _$AppTokenPairCopyWithImpl(this._self, this._then); +class _$AppTokenCopyWithImpl<$Res> + implements $AppTokenCopyWith<$Res> { + _$AppTokenCopyWithImpl(this._self, this._then); - final AppTokenPair _self; - final $Res Function(AppTokenPair) _then; + final AppToken _self; + final $Res Function(AppToken) _then; -/// Create a copy of AppTokenPair +/// Create a copy of AppToken /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? accessToken = null,Object? refreshToken = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? token = null,}) { return _then(_self.copyWith( -accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable -as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable as String, )); } @@ -80,47 +79,46 @@ as String, /// @nodoc @JsonSerializable() -class _AppTokenPair implements AppTokenPair { - const _AppTokenPair({required this.accessToken, required this.refreshToken}); - factory _AppTokenPair.fromJson(Map json) => _$AppTokenPairFromJson(json); +class _AppToken implements AppToken { + const _AppToken({required this.token}); + factory _AppToken.fromJson(Map json) => _$AppTokenFromJson(json); -@override final String accessToken; -@override final String refreshToken; +@override final String token; -/// Create a copy of AppTokenPair +/// Create a copy of AppToken /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) @pragma('vm:prefer-inline') -_$AppTokenPairCopyWith<_AppTokenPair> get copyWith => __$AppTokenPairCopyWithImpl<_AppTokenPair>(this, _$identity); +_$AppTokenCopyWith<_AppToken> get copyWith => __$AppTokenCopyWithImpl<_AppToken>(this, _$identity); @override Map toJson() { - return _$AppTokenPairToJson(this, ); + return _$AppTokenToJson(this, ); } @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppTokenPair&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppToken&&(identical(other.token, token) || other.token == token)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,accessToken,refreshToken); +int get hashCode => Object.hash(runtimeType,token); @override String toString() { - return 'AppTokenPair(accessToken: $accessToken, refreshToken: $refreshToken)'; + return 'AppToken(token: $token)'; } } /// @nodoc -abstract mixin class _$AppTokenPairCopyWith<$Res> implements $AppTokenPairCopyWith<$Res> { - factory _$AppTokenPairCopyWith(_AppTokenPair value, $Res Function(_AppTokenPair) _then) = __$AppTokenPairCopyWithImpl; +abstract mixin class _$AppTokenCopyWith<$Res> implements $AppTokenCopyWith<$Res> { + factory _$AppTokenCopyWith(_AppToken value, $Res Function(_AppToken) _then) = __$AppTokenCopyWithImpl; @override @useResult $Res call({ - String accessToken, String refreshToken + String token }); @@ -128,19 +126,18 @@ $Res call({ } /// @nodoc -class __$AppTokenPairCopyWithImpl<$Res> - implements _$AppTokenPairCopyWith<$Res> { - __$AppTokenPairCopyWithImpl(this._self, this._then); +class __$AppTokenCopyWithImpl<$Res> + implements _$AppTokenCopyWith<$Res> { + __$AppTokenCopyWithImpl(this._self, this._then); - final _AppTokenPair _self; - final $Res Function(_AppTokenPair) _then; + final _AppToken _self; + final $Res Function(_AppToken) _then; -/// Create a copy of AppTokenPair +/// Create a copy of AppToken /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? accessToken = null,Object? refreshToken = null,}) { - return _then(_AppTokenPair( -accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable -as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable +@override @pragma('vm:prefer-inline') $Res call({Object? token = null,}) { + return _then(_AppToken( +token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable as String, )); } diff --git a/lib/models/auth.g.dart b/lib/models/auth.g.dart index e34d032..e407493 100644 --- a/lib/models/auth.g.dart +++ b/lib/models/auth.g.dart @@ -6,17 +6,12 @@ part of 'auth.dart'; // JsonSerializableGenerator // ************************************************************************** -_AppTokenPair _$AppTokenPairFromJson(Map json) => - _AppTokenPair( - accessToken: json['access_token'] as String, - refreshToken: json['refresh_token'] as String, - ); +_AppToken _$AppTokenFromJson(Map json) => + _AppToken(token: json['token'] as String); -Map _$AppTokenPairToJson(_AppTokenPair instance) => - { - 'access_token': instance.accessToken, - 'refresh_token': instance.refreshToken, - }; +Map _$AppTokenToJson(_AppToken instance) => { + 'token': instance.token, +}; _SnAuthChallenge _$SnAuthChallengeFromJson(Map json) => _SnAuthChallenge( diff --git a/lib/pods/network.dart b/lib/pods/network.dart index d5403d7..3476063 100644 --- a/lib/pods/network.dart +++ b/lib/pods/network.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:developer'; import 'dart:io'; import 'package:flutter/foundation.dart'; @@ -68,16 +67,9 @@ final apiClientProvider = Provider((ref) { RequestInterceptorHandler handler, ) async { try { - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - ref.watch(serverUrlProvider), - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk != null) { - options.headers['Authorization'] = 'Bearer $atk'; + final token = await getToken(ref.watch(tokenProvider)); + if (token != null) { + options.headers['Authorization'] = 'AtField $token'; } } catch (err) { // ignore @@ -95,105 +87,21 @@ final apiClientProvider = Provider((ref) { return dio; }); -final tokenPairProvider = Provider((ref) { +final tokenProvider = Provider((ref) { final prefs = ref.watch(sharedPreferencesProvider); - final tkPairString = prefs.getString(kTokenPairStoreKey); - if (tkPairString == null) return null; - return AppTokenPair.fromJson(jsonDecode(tkPairString)); + final tokenString = prefs.getString(kTokenPairStoreKey); + if (tokenString == null) return null; + return AppToken.fromJson(jsonDecode(tokenString)); }); -Future<(String, String)?> refreshToken(String baseUrl, String? rtk) async { - if (rtk == null) return null; +// Token refresh functionality removed as per backend changes - final dio = Dio(); - dio.options.baseUrl = baseUrl; - - final resp = await dio.post( - '/auth/token', - data: {'grant_type': 'refresh_token', 'refresh_token': rtk}, - ); - - final String atk = resp.data['access_token']; - final String nRtk = resp.data['refresh_token']; - - return (atk, nRtk); +Future getToken(AppToken? token) async { + return token?.token; } -Completer? _refreshCompleter; - -Future getFreshAtk( - AppTokenPair? tkPair, - String baseUrl, { - Function(String, String)? onRefreshed, -}) async { - var atk = tkPair?.accessToken; - var rtk = tkPair?.refreshToken; - - if (_refreshCompleter != null) { - return await _refreshCompleter!.future; - } else { - _refreshCompleter = Completer(); - } - - try { - if (atk != null) { - final atkParts = atk.split('.'); - if (atkParts.length != 3) { - throw Exception('invalid format of access token'); - } - - var rawPayload = atkParts[1].replaceAll('-', '+').replaceAll('_', '/'); - switch (rawPayload.length % 4) { - case 0: - break; - case 2: - rawPayload += '=='; - break; - case 3: - rawPayload += '='; - break; - default: - throw Exception('illegal format of access token payload'); - } - - final b64 = utf8.fuse(base64Url); - final payload = b64.decode(rawPayload); - final exp = jsonDecode(payload)['exp']; - if (exp <= DateTime.now().millisecondsSinceEpoch ~/ 1000) { - log('[Auth] Access token need refresh, doing it at ${DateTime.now()}'); - final result = await refreshToken(baseUrl, rtk); - if (result == null) { - atk = null; - } else { - onRefreshed?.call(result.$1, result.$2); - atk = result.$1; - } - } - - if (atk != null) { - _refreshCompleter!.complete(atk); - return atk; - } else { - log('[Auth] Access token refresh failed...'); - _refreshCompleter!.complete(null); - } - } - } catch (err) { - log('[Auth] Failed to authenticate user... $err'); - _refreshCompleter!.completeError(err); - } finally { - _refreshCompleter = null; - } - - return null; -} - -Future setTokenPair( - SharedPreferences prefs, - String atk, - String rtk, -) async { - final tkPair = AppTokenPair(accessToken: atk, refreshToken: rtk); - final tkPairString = jsonEncode(tkPair); - prefs.setString(kTokenPairStoreKey, tkPairString); +Future setToken(SharedPreferences prefs, String token) async { + final appToken = AppToken(token: token); + final tokenString = jsonEncode(appToken); + prefs.setString(kTokenPairStoreKey, tokenString); } diff --git a/lib/pods/userinfo.dart b/lib/pods/userinfo.dart index 9a3de20..09978e0 100644 --- a/lib/pods/userinfo.dart +++ b/lib/pods/userinfo.dart @@ -13,7 +13,7 @@ class UserInfoNotifier extends StateNotifier> { Future getAccessToken() async { final prefs = _ref.read(sharedPreferencesProvider); - return prefs.getString('dyn_user_atk'); + return prefs.getString(kTokenPairStoreKey); } Future fetchUser() async { diff --git a/lib/pods/websocket.dart b/lib/pods/websocket.dart index afd8155..c65cfd0 100644 --- a/lib/pods/websocket.dart +++ b/lib/pods/websocket.dart @@ -54,25 +54,18 @@ class WebSocketService { _statusStreamController.sink.add(WebSocketState.connecting()); final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); + final token = await getToken(ref.watch(tokenProvider)); final url = '$baseUrl/ws'.replaceFirst('http', 'ws'); log('[WebSocket] Trying connecting to $url'); try { if (kIsWeb) { - _channel = WebSocketChannel.connect(Uri.parse('$url?tk=$atk')); + _channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token')); } else { _channel = IOWebSocketChannel.connect( Uri.parse(url), - headers: {'Authorization': 'Bearer $atk'}, + headers: {'Authorization': 'Bearer $token'}, ); } await _channel!.ready; diff --git a/lib/screens/account.dart b/lib/screens/account.dart index 4cf288f..1380e66 100644 --- a/lib/screens/account.dart +++ b/lib/screens/account.dart @@ -254,8 +254,8 @@ class AccountScreen extends HookConsumerWidget { contentPadding: EdgeInsets.symmetric(horizontal: 24), title: Text('Copy access token'), onTap: () async { - final tk = ref.watch(tokenPairProvider); - Clipboard.setData(ClipboardData(text: tk!.accessToken)); + final tk = ref.watch(tokenProvider); + Clipboard.setData(ClipboardData(text: tk!.token)); }, ), if (kDebugMode) diff --git a/lib/screens/account/me/update.dart b/lib/screens/account/me/update.dart index e5b7349..fddf7cb 100644 --- a/lib/screens/account/me/update.dart +++ b/lib/screens/account/me/update.dart @@ -59,19 +59,12 @@ class UpdateProfileScreen extends HookConsumerWidget { submitting.value = true; try { final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Token is null'); final cloudFile = await putMediaToCloud( fileData: result, - atk: atk, + atk: token, baseUrl: baseUrl, filename: result.name, mimetype: result.mimeType ?? 'image/jpeg', diff --git a/lib/screens/auth/login.dart b/lib/screens/auth/login.dart index b23b767..868ad6f 100644 --- a/lib/screens/auth/login.dart +++ b/lib/screens/auth/login.dart @@ -142,10 +142,9 @@ class _LoginCheckScreen extends HookConsumerWidget { '/auth/token', data: {'grant_type': 'authorization_code', 'code': result.id}, ); - final atk = tokenResp.data['access_token']; - final rtk = tokenResp.data['refresh_token']; - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); + final token = tokenResp.data['token']; + setToken(ref.watch(sharedPreferencesProvider), token); + ref.invalidate(tokenProvider); if (!context.mounted) return; final userNotifier = ref.read(userInfoProvider.notifier); userNotifier.fetchUser().then((_) { diff --git a/lib/screens/chat/chat.dart b/lib/screens/chat/chat.dart index 05aa681..3a180aa 100644 --- a/lib/screens/chat/chat.dart +++ b/lib/screens/chat/chat.dart @@ -522,19 +522,12 @@ class EditChatScreen extends HookConsumerWidget { submitting.value = true; try { final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Token is null'); final cloudFile = await putMediaToCloud( fileData: result, - atk: atk, + atk: token, baseUrl: baseUrl, filename: result.name, mimetype: result.mimeType ?? 'image/jpeg', diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index 7bde3ee..8c0c643 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -117,19 +117,12 @@ class MessagesNotifier extends _$MessagesNotifier { messageRepositoryProvider(_roomId).future, ); final baseUrl = ref.read(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Access token is null'); final currentMessages = state.value ?? []; await repository.sendMessage( - atk, + token, baseUrl, _roomId, content, diff --git a/lib/screens/chat/room.g.dart b/lib/screens/chat/room.g.dart index eb8927b..e1d8d5c 100644 --- a/lib/screens/chat/room.g.dart +++ b/lib/screens/chat/room.g.dart @@ -6,7 +6,7 @@ part of 'room.dart'; // RiverpodGenerator // ************************************************************************** -String _$messagesNotifierHash() => r'71a9fc1c6d024f6203f06225384c19335b9b6f2c'; +String _$messagesNotifierHash() => r'afc4d43f4948ec571118cef0321838a6cefc89c0'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/screens/creators/publishers.dart b/lib/screens/creators/publishers.dart index 874df08..5730e66 100644 --- a/lib/screens/creators/publishers.dart +++ b/lib/screens/creators/publishers.dart @@ -95,19 +95,12 @@ class EditPublisherScreen extends HookConsumerWidget { submitting.value = true; try { final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Token is null'); final cloudFile = await putMediaToCloud( fileData: result, - atk: atk, + atk: token, baseUrl: baseUrl, filename: result.name, mimetype: result.mimeType ?? 'image/jpeg', diff --git a/lib/screens/notification.g.dart b/lib/screens/notification.g.dart index 3db91f6..c3c41a8 100644 --- a/lib/screens/notification.g.dart +++ b/lib/screens/notification.g.dart @@ -7,7 +7,7 @@ part of 'notification.dart'; // ************************************************************************** String _$notificationUnreadCountNotifierHash() => - r'074143cf208a3afe1495be405198532a23ef77c8'; + r'372a2cc259d7d838cd4f33a9129f7396ef31dbb9'; /// See also [NotificationUnreadCountNotifier]. @ProviderFor(NotificationUnreadCountNotifier) diff --git a/lib/screens/posts/compose.dart b/lib/screens/posts/compose.dart index 0c43126..23967e7 100644 --- a/lib/screens/posts/compose.dart +++ b/lib/screens/posts/compose.dart @@ -125,21 +125,14 @@ class PostComposeScreen extends HookConsumerWidget { final attachment = attachments.value[index]; if (attachment is SnCloudFile) return; final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Token is null'); try { attachmentProgress.value = {...attachmentProgress.value, index: 0}; final cloudFile = await putMediaToCloud( fileData: attachment.data, - atk: atk, + atk: token, baseUrl: baseUrl, filename: attachment.data.name ?? 'Post media', mimetype: @@ -394,49 +387,32 @@ class PostComposeScreen extends HookConsumerWidget { final isWide = isWideScreen(context); return isWide ? Wrap( - spacing: 8, - runSpacing: 8, - children: [ - for (var idx = 0; idx < attachments.value.length; idx++) - SizedBox( - width: constraints.maxWidth / 2 - 4, - child: AttachmentPreview( - item: attachments.value[idx], - progress: attachmentProgress.value[idx], - onRequestUpload: () => uploadAttachment(idx), - onDelete: () => deleteAttachment(idx), - onMove: (delta) { - if (idx + delta < 0 || - idx + delta >= attachments.value.length) { - return; - } - final clone = List.of(attachments.value); - clone.insert( - idx + delta, - clone.removeAt(idx), - ); - attachments.value = clone; - }, - ), - ), - ], - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 8, - children: [ - for (var idx = 0; idx < attachments.value.length; idx++) - AttachmentPreview( + spacing: 8, + runSpacing: 8, + children: [ + for ( + var idx = 0; + idx < attachments.value.length; + idx++ + ) + SizedBox( + width: constraints.maxWidth / 2 - 4, + child: AttachmentPreview( item: attachments.value[idx], - progress: attachmentProgress.value[idx], - onRequestUpload: () => uploadAttachment(idx), + progress: + attachmentProgress.value[idx], + onRequestUpload: + () => uploadAttachment(idx), onDelete: () => deleteAttachment(idx), onMove: (delta) { if (idx + delta < 0 || - idx + delta >= attachments.value.length) { + idx + delta >= + attachments.value.length) { return; } - final clone = List.of(attachments.value); + final clone = List.of( + attachments.value, + ); clone.insert( idx + delta, clone.removeAt(idx), @@ -444,8 +420,42 @@ class PostComposeScreen extends HookConsumerWidget { attachments.value = clone; }, ), - ], - ); + ), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8, + children: [ + for ( + var idx = 0; + idx < attachments.value.length; + idx++ + ) + AttachmentPreview( + item: attachments.value[idx], + progress: attachmentProgress.value[idx], + onRequestUpload: + () => uploadAttachment(idx), + onDelete: () => deleteAttachment(idx), + onMove: (delta) { + if (idx + delta < 0 || + idx + delta >= + attachments.value.length) { + return; + } + final clone = List.of( + attachments.value, + ); + clone.insert( + idx + delta, + clone.removeAt(idx), + ); + attachments.value = clone; + }, + ), + ], + ); }, ), ], diff --git a/lib/screens/posts/pub_profile.g.dart b/lib/screens/posts/pub_profile.g.dart index 565d7a9..c197701 100644 --- a/lib/screens/posts/pub_profile.g.dart +++ b/lib/screens/posts/pub_profile.g.dart @@ -145,7 +145,7 @@ class _PublisherProviderElement String get uname => (origin as PublisherProvider).uname; } -String _$publisherBadgesHash() => r'b26d8804ddc9734c453bdf76af0a9336f166542c'; +String _$publisherBadgesHash() => r'a5781deded7e682a781ccd7854418f050438e3f4'; /// See also [publisherBadges]. @ProviderFor(publisherBadges) diff --git a/lib/screens/realm/realms.dart b/lib/screens/realm/realms.dart index 2a03db2..32f795b 100644 --- a/lib/screens/realm/realms.dart +++ b/lib/screens/realm/realms.dart @@ -211,19 +211,12 @@ class EditRealmScreen extends HookConsumerWidget { submitting.value = true; try { final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw ArgumentError('Access token is null'); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw ArgumentError('Access token is null'); final cloudFile = await putMediaToCloud( fileData: result, - atk: atk, + atk: token, baseUrl: baseUrl, filename: result.name, mimetype: result.mimeType ?? 'image/jpeg', diff --git a/lib/widgets/content/cloud_file_picker.dart b/lib/widgets/content/cloud_file_picker.dart index 5ab3be0..dd8be9b 100644 --- a/lib/widgets/content/cloud_file_picker.dart +++ b/lib/widgets/content/cloud_file_picker.dart @@ -43,15 +43,8 @@ class CloudFilePicker extends HookConsumerWidget { if (files.value.isEmpty) return; final baseUrl = ref.read(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); - if (atk == null) throw Exception("Unauthorized"); + final token = await getToken(ref.watch(tokenProvider)); + if (token == null) throw Exception("Unauthorized"); List result = List.empty(growable: true); @@ -64,7 +57,7 @@ class CloudFilePicker extends HookConsumerWidget { final cloudFile = await putMediaToCloud( fileData: file.data, - atk: atk, + atk: token, baseUrl: baseUrl, filename: file.data.name ?? 'Post media', mimetype: diff --git a/lib/widgets/content/video.native.dart b/lib/widgets/content/video.native.dart index 59cf436..3ba6d22 100644 --- a/lib/widgets/content/video.native.dart +++ b/lib/widgets/content/video.native.dart @@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:island/pods/config.dart'; import 'package:island/pods/network.dart'; import 'package:island/widgets/alert.dart'; import 'package:media_kit/media_kit.dart'; @@ -38,18 +37,10 @@ class _UniversalVideoState extends ConsumerState { final inCacheInfo = await DefaultCacheManager().getFileFromCache(url); if (inCacheInfo == null) { log('[MediaPlayer] Miss cache: $url'); - final baseUrl = ref.watch(serverUrlProvider); - final atk = await getFreshAtk( - ref.watch(tokenPairProvider), - baseUrl, - onRefreshed: (atk, rtk) { - setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk); - ref.invalidate(tokenPairProvider); - }, - ); + final token = await getToken(ref.watch(tokenProvider)); final fileStream = DefaultCacheManager().getFileStream( url, - headers: {'Authorization': 'Bearer $atk'}, + headers: {'Authorization': 'Bearer $token'}, withProgress: true, ); await for (var fileInfo in fileStream) {