From 1391fa0ddefef9c3ed3ac8a1c7c91c29b65ac5e9 Mon Sep 17 00:00:00 2001 From: Texas0295 Date: Sun, 21 Sep 2025 22:10:25 +0800 Subject: [PATCH] [REF] unify pool handling with extension methods - Move pool filtering and parsing logic into SnFilePool extension - Replace PoolService and pool_utils with unified extension - Update settings screen to use pools.filterValid() + resolveDefaultPoolId - Cleanup references in compose_shared.dart - Remove obsolete files: pool_service.dart, pool_utils.dart Signed-off-by: Texas0295 --- lib/models/file_pool.dart | 18 +++++++++++++- lib/pods/pool_provider.dart | 30 ++++++++++++++++------ lib/screens/settings.dart | 20 +++++++-------- lib/services/pool_service.dart | 19 -------------- lib/utils/pool_utils.dart | 37 ---------------------------- lib/widgets/post/compose_shared.dart | 1 - 6 files changed, 48 insertions(+), 77 deletions(-) delete mode 100644 lib/services/pool_service.dart delete mode 100644 lib/utils/pool_utils.dart diff --git a/lib/models/file_pool.dart b/lib/models/file_pool.dart index f84461f8..3659a667 100644 --- a/lib/models/file_pool.dart +++ b/lib/models/file_pool.dart @@ -24,7 +24,7 @@ sealed class SnFilePool with _$SnFilePool { _$SnFilePoolFromJson(json); } -extension SnFilePoolList on SnFilePool { +extension SnFilePoolList on List { static List listFromResponse(dynamic data) { if (data is List) { return data @@ -34,4 +34,20 @@ extension SnFilePoolList on SnFilePool { } throw ArgumentError('Unexpected response format: $data'); } + + List filterValid() { + return where((p) { + final accept = p.policyConfig?['accept_types']; + + if (accept is List) { + final acceptsOnlyMedia = accept.every((t) => + t is String && + (t.startsWith('image/') || + t.startsWith('video/') || + t.startsWith('audio/'))); + if (acceptsOnlyMedia) return false; + } + return true; + }).toList(); + } } diff --git a/lib/pods/pool_provider.dart b/lib/pods/pool_provider.dart index b267fed8..c9de0159 100644 --- a/lib/pods/pool_provider.dart +++ b/lib/pods/pool_provider.dart @@ -1,14 +1,28 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:island/services/pool_service.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/models/file_pool.dart'; +import 'package:island/pods/config.dart'; import 'package:island/pods/network.dart'; -final poolServiceProvider = Provider((ref) { +final poolsProvider = FutureProvider>((ref) async { final dio = ref.watch(apiClientProvider); - return PoolService(dio); + final response = await dio.get('/drive/pools'); + final pools = SnFilePoolList.listFromResponse(response.data); + return pools.filterValid(); }); -final poolsProvider = FutureProvider>((ref) async { - final service = ref.watch(poolServiceProvider); - return service.fetchPools(); -}); +String resolveDefaultPoolId(WidgetRef ref, List pools) { + final settings = ref.watch(appSettingsNotifierProvider); + final validPools = pools.filterValid(); + + final configuredId = settings.defaultPoolId; + if (configuredId != null && validPools.any((p) => p.id == configuredId)) { + return configuredId; + } + + if (validPools.isNotEmpty) { + return validPools.first.id; + } + + // DEFAULT: Solar Network Driver + return '500e5ed8-bd44-4359-bc0a-ec85e2adf447'; } + diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index cd28b948..272babd9 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -21,7 +21,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:island/pods/config.dart'; import 'package:island/pods/pool_provider.dart'; -import 'package:island/utils/pool_utils.dart'; +import 'package:island/models/file_pool.dart'; class SettingsScreen extends HookConsumerWidget { const SettingsScreen({super.key}); @@ -372,8 +372,8 @@ class SettingsScreen extends HookConsumerWidget { poolsAsync.when( data: (pools) { - final validPools = filterValidPools(pools); - final currentPoolId = resolveDefaultPoolId(ref, validPools); + final validPools = pools.filterValid(); + final currentPoolId = resolveDefaultPoolId(ref, pools); return ListTile( isThreeLine: true, @@ -392,14 +392,12 @@ class SettingsScreen extends HookConsumerWidget { child: DropdownButton2( isExpanded: true, items: - validPools - .map( - (p) => DropdownMenuItem( - value: p.id, - child: Text(p.name).fontSize(14), - ), - ) - .toList(), + validPools.map((p) { + return DropdownMenuItem( + value: p.id, + child: Text(p.name).fontSize(14), + ); + }).toList(), value: currentPoolId, onChanged: (value) { ref diff --git a/lib/services/pool_service.dart b/lib/services/pool_service.dart deleted file mode 100644 index 8cef98e6..00000000 --- a/lib/services/pool_service.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:dio/dio.dart'; - -import 'package:island/models/file_pool.dart'; - -class PoolService { - final Dio _dio; - - PoolService(this._dio); - - Future> fetchPools() async { - final response = await _dio.get('/drive/pools'); - - if (response.statusCode == 200) { - return SnFilePoolList.listFromResponse(response.data); - } else { - throw Exception('Failed to fetch pools: ${response.statusCode}'); - } - } -} diff --git a/lib/utils/pool_utils.dart b/lib/utils/pool_utils.dart deleted file mode 100644 index e3476a90..00000000 --- a/lib/utils/pool_utils.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:island/models/file_pool.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:island/pods/config.dart'; - -List filterValidPools(List pools) { - return pools.where((p) { - final accept = p.policyConfig?['accept_types']; - - if (accept is List) { - final acceptsOnlyMedia = accept.every((t) => - t is String && - (t.startsWith('image/') || - t.startsWith('video/') || - t.startsWith('audio/'))); - if (acceptsOnlyMedia) return false; - } - - return true; - }).toList(); -} - -String resolveDefaultPoolId(WidgetRef ref, List pools) { - final settings = ref.watch(appSettingsNotifierProvider); - final validPools = filterValidPools(pools); - - final configuredId = settings.defaultPoolId; - if (configuredId != null && - validPools.any((p) => p.id == configuredId)) { - return configuredId; - } - - if (validPools.isNotEmpty) { - return validPools.first.id; - } - - return '500e5ed8-bd44-4359-bc0a-ec85e2adf447'; // Solar Network Driver -} diff --git a/lib/widgets/post/compose_shared.dart b/lib/widgets/post/compose_shared.dart index e94f0e5d..c9302376 100644 --- a/lib/widgets/post/compose_shared.dart +++ b/lib/widgets/post/compose_shared.dart @@ -21,7 +21,6 @@ import 'package:island/widgets/post/compose_link_attachments.dart'; import 'package:island/widgets/post/compose_poll.dart'; import 'package:island/widgets/post/compose_recorder.dart'; import 'package:island/pods/pool_provider.dart'; -import 'package:island/utils/pool_utils.dart'; import 'package:pasteboard/pasteboard.dart'; import 'package:textfield_tags/textfield_tags.dart'; import 'dart:async';