chore(deps): update Flutter and Go dependencies

This commit is contained in:
zarzet
2026-08-19 11:59:28 +07:00
parent 4b75555dd5
commit bdb10a2ae6
10 changed files with 209 additions and 114 deletions
+33 -5
View File
@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
import 'package:spotiflac_android/widgets/collection_scaffold.dart';
import 'package:spotiflac_android/theme/app_tokens.dart';
import 'package:spotiflac_android/widgets/track_card.dart';
@@ -463,12 +464,39 @@ class _LibraryTracksFolderScreenState
final picked = await FilePicker.pickFile(type: FileType.image);
if (picked == null) return;
final path = picked.path;
if (path == null || path.isEmpty) return;
Directory? materializedDir;
try {
var sourcePath = picked.path;
if (sourcePath == null || sourcePath.isEmpty) {
materializedDir = await Directory.systemTemp.createTemp(
'spotiflac_playlist_cover_',
);
final pickedExtension = p.extension(picked.name);
final materializedFile = File(
p.join(
materializedDir.path,
'selected_cover${pickedExtension.isEmpty ? '.img' : pickedExtension}',
),
);
await materializedFile.writeAsBytes(
await picked.readAsBytes(),
flush: true,
);
sourcePath = materializedFile.path;
}
await ref
.read(libraryCollectionsProvider.notifier)
.setPlaylistCover(playlistId, path);
await ref
.read(libraryCollectionsProvider.notifier)
.setPlaylistCover(playlistId, sourcePath);
} finally {
try {
if (materializedDir != null && await materializedDir.exists()) {
await materializedDir.delete(recursive: true);
}
} catch (_) {
// The cover has already been normalized into app storage.
}
}
}
Future<void> _removeCoverImage() async {
@@ -1,4 +1,4 @@
import 'dart:io';
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
@@ -76,13 +76,12 @@ class _BackupRestorePageState extends ConsumerState<BackupRestorePage> {
String? content;
try {
final result = await FilePicker.pickFiles(
final picked = await FilePicker.pickFile(
type: FileType.custom,
allowedExtensions: ['json', BackupService.fileExtension],
);
final path = result?.files.single.path;
if (path == null) return;
content = await File(path).readAsString();
if (picked == null) return;
content = utf8.decode(await picked.readAsBytes());
} catch (e) {
_log.e('Failed to read backup file: $e');
messenger.showSnackBar(SnackBar(content: Text(l10n.backupInvalidFile)));
+45 -17
View File
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:spotiflac_android/widgets/extension_row.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/models/settings.dart';
@@ -217,26 +218,45 @@ class _ExtensionsPageState extends ConsumerState<ExtensionsPage> {
}
Future<void> _installExtension() async {
final result = await FilePicker.pickFiles(type: FileType.any);
final selectedFiles = await FilePicker.pickFiles(type: FileType.any);
if (selectedFiles.isEmpty) return;
if (result != null && result.files.isNotEmpty) {
final selectedPaths = result.files
.map((file) => file.path)
.whereType<String>()
.toList();
final extensionPaths = selectedPaths.where((path) {
final lowerPath = path.toLowerCase();
return lowerPath.endsWith('.spotiflac-ext') ||
lowerPath.endsWith('.sflx');
}).toList();
final hasInvalidFile = selectedFiles.any((file) {
final lowerName = file.name.toLowerCase();
return !lowerName.endsWith('.spotiflac-ext') &&
!lowerName.endsWith('.sflx');
});
if (hasInvalidFile) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.snackbarSelectExtFile)),
);
}
return;
}
if (extensionPaths.length != selectedPaths.length) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.snackbarSelectExtFile)),
);
Directory? materializedDir;
try {
final extensionPaths = <String>[];
for (final selectedFile in selectedFiles) {
final localPath = selectedFile.path;
if (localPath != null && localPath.isNotEmpty) {
extensionPaths.add(localPath);
continue;
}
return;
materializedDir ??= await Directory.systemTemp.createTemp(
'spotiflac_extension_import_',
);
final safeName = p.basename(selectedFile.name);
final materializedFile = File(
p.join(materializedDir.path, '${extensionPaths.length}_$safeName'),
);
await materializedFile.writeAsBytes(
await selectedFile.readAsBytes(),
flush: true,
);
extensionPaths.add(materializedFile.path);
}
final installResult = await ref
@@ -251,6 +271,14 @@ class _ExtensionsPageState extends ConsumerState<ExtensionsPage> {
context,
).showSnackBar(SnackBar(content: Text(message)));
}
} finally {
try {
if (materializedDir != null && await materializedDir.exists()) {
await materializedDir.delete(recursive: true);
}
} catch (_) {
// The extension has already been copied into app storage.
}
}
}
+3 -3
View File
@@ -746,13 +746,13 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
if (picked == null) return;
final sourcePath = picked.path;
final pickedExtension = p.extension(picked.name).replaceFirst('.', '');
Uint8List? bytes;
final needsByteFallback =
!_hasValue(sourcePath) && !_hasValue(picked.extension);
final needsByteFallback = !_hasValue(sourcePath);
if (needsByteFallback) {
bytes = await picked.readAsBytes();
}
final extension = _resolveImageExtension(picked.extension, bytes);
final extension = _resolveImageExtension(pickedExtension, bytes);
final tempDir = await Directory.systemTemp.createTemp('edit_cover_');
final tempPath =
+1
View File
@@ -6,6 +6,7 @@ import 'package:spotiflac_android/widgets/app_bottom_sheet.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path/path.dart' as p;
import 'package:spotiflac_android/services/conversion_library_service.dart';
import 'package:spotiflac_android/services/library_database.dart';
import 'package:spotiflac_android/utils/file_access.dart';
+5 -6
View File
@@ -1,4 +1,4 @@
import 'dart:io';
import 'dart:convert';
import 'package:file_picker/file_picker.dart';
import 'package:path/path.dart' as p;
import 'package:spotiflac_android/models/track.dart';
@@ -14,15 +14,14 @@ class CsvImportService {
void Function(int current, int total)? onProgress,
}) async {
try {
final FilePickerResult? result = await FilePicker.pickFiles(
final picked = await FilePicker.pickFile(
type: FileType.custom,
allowedExtensions: ['csv', 'm3u', 'm3u8'],
);
if (result != null && result.files.single.path != null) {
final file = File(result.files.single.path!);
final content = await file.readAsString();
final extension = p.extension(file.path).toLowerCase();
if (picked != null) {
final content = utf8.decode(await picked.readAsBytes());
final extension = p.extension(picked.name).toLowerCase();
final tracks = (extension == '.m3u' || extension == '.m3u8')
? M3uPlaylistService.parseM3u(content)
: _parseCsv(content);