[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 <kimura@texas0295.top>
This commit is contained in:
Texas0295
2025-09-21 22:10:25 +08:00
parent cbdc7acdcd
commit 1391fa0dde
6 changed files with 48 additions and 77 deletions

View File

@@ -24,7 +24,7 @@ sealed class SnFilePool with _$SnFilePool {
_$SnFilePoolFromJson(json); _$SnFilePoolFromJson(json);
} }
extension SnFilePoolList on SnFilePool { extension SnFilePoolList on List<SnFilePool> {
static List<SnFilePool> listFromResponse(dynamic data) { static List<SnFilePool> listFromResponse(dynamic data) {
if (data is List) { if (data is List) {
return data return data
@@ -34,4 +34,20 @@ extension SnFilePoolList on SnFilePool {
} }
throw ArgumentError('Unexpected response format: $data'); throw ArgumentError('Unexpected response format: $data');
} }
List<SnFilePool> 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();
}
} }

View File

@@ -1,14 +1,28 @@
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/services/pool_service.dart';
import 'package:island/models/file_pool.dart'; import 'package:island/models/file_pool.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
final poolServiceProvider = Provider<PoolService>((ref) { final poolsProvider = FutureProvider<List<SnFilePool>>((ref) async {
final dio = ref.watch(apiClientProvider); 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<List<SnFilePool>>((ref) async { String resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) {
final service = ref.watch(poolServiceProvider); final settings = ref.watch(appSettingsNotifierProvider);
return service.fetchPools(); 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'; }

View File

@@ -21,7 +21,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:island/pods/config.dart'; import 'package:island/pods/config.dart';
import 'package:island/pods/pool_provider.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 { class SettingsScreen extends HookConsumerWidget {
const SettingsScreen({super.key}); const SettingsScreen({super.key});
@@ -372,8 +372,8 @@ class SettingsScreen extends HookConsumerWidget {
poolsAsync.when( poolsAsync.when(
data: (pools) { data: (pools) {
final validPools = filterValidPools(pools); final validPools = pools.filterValid();
final currentPoolId = resolveDefaultPoolId(ref, validPools); final currentPoolId = resolveDefaultPoolId(ref, pools);
return ListTile( return ListTile(
isThreeLine: true, isThreeLine: true,
@@ -392,14 +392,12 @@ class SettingsScreen extends HookConsumerWidget {
child: DropdownButton2<String>( child: DropdownButton2<String>(
isExpanded: true, isExpanded: true,
items: items:
validPools validPools.map((p) {
.map( return DropdownMenuItem<String>(
(p) => DropdownMenuItem<String>( value: p.id,
value: p.id, child: Text(p.name).fontSize(14),
child: Text(p.name).fontSize(14), );
), }).toList(),
)
.toList(),
value: currentPoolId, value: currentPoolId,
onChanged: (value) { onChanged: (value) {
ref ref

View File

@@ -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<List<SnFilePool>> 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}');
}
}
}

View File

@@ -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<SnFilePool> filterValidPools(List<SnFilePool> 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<SnFilePool> 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
}

View File

@@ -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_poll.dart';
import 'package:island/widgets/post/compose_recorder.dart'; import 'package:island/widgets/post/compose_recorder.dart';
import 'package:island/pods/pool_provider.dart'; import 'package:island/pods/pool_provider.dart';
import 'package:island/utils/pool_utils.dart';
import 'package:pasteboard/pasteboard.dart'; import 'package:pasteboard/pasteboard.dart';
import 'package:textfield_tags/textfield_tags.dart'; import 'package:textfield_tags/textfield_tags.dart';
import 'dart:async'; import 'dart:async';