mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-27 13:22:49 +02:00
chore(deps): update Flutter and Go dependencies
This commit is contained in:
@@ -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)));
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user