mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 15:57:25 +00:00
improve importing comic
This commit is contained in:
@@ -111,7 +111,7 @@ abstract class CBZ {
|
|||||||
var src = files[i];
|
var src = files[i];
|
||||||
var dst = File(
|
var dst = File(
|
||||||
FilePath.join(dest.path, '${i + 1}.${src.path.split('.').last}'));
|
FilePath.join(dest.path, '${i + 1}.${src.path.split('.').last}'));
|
||||||
src.copy(dst.path);
|
await src.copy(dst.path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dest.createSync();
|
dest.createSync();
|
||||||
@@ -129,7 +129,7 @@ abstract class CBZ {
|
|||||||
var src = chapter.value[i];
|
var src = chapter.value[i];
|
||||||
var dst = File(FilePath.join(
|
var dst = File(FilePath.join(
|
||||||
chapterDir.path, '${i + 1}.${src.path.split('.').last}'));
|
chapterDir.path, '${i + 1}.${src.path.split('.').last}'));
|
||||||
src.copy(dst.path);
|
await src.copy(dst.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,16 +18,14 @@ class ImportComic {
|
|||||||
const ImportComic({this.selectedFolder});
|
const ImportComic({this.selectedFolder});
|
||||||
|
|
||||||
Future<bool> cbz() async {
|
Future<bool> cbz() async {
|
||||||
var xFile = await selectFile(ext: ['cbz']);
|
var file = await selectFile(ext: ['cbz']);
|
||||||
if(xFile == null) {
|
if(file == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var controller = showLoadingDialog(App.rootContext, allowCancel: false);
|
var controller = showLoadingDialog(App.rootContext, allowCancel: false);
|
||||||
var isSuccessful = false;
|
var isSuccessful = false;
|
||||||
try {
|
try {
|
||||||
var cache = FilePath.join(App.cachePath, xFile.name);
|
var comic = await CBZ.import(File(file.path));
|
||||||
await xFile.saveTo(cache);
|
|
||||||
var comic = await CBZ.import(File(cache));
|
|
||||||
if (selectedFolder != null) {
|
if (selectedFolder != null) {
|
||||||
LocalFavoritesManager().addComic(
|
LocalFavoritesManager().addComic(
|
||||||
selectedFolder!,
|
selectedFolder!,
|
||||||
@@ -41,7 +39,6 @@ class ImportComic {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await File(cache).deleteIgnoreError();
|
|
||||||
isSuccessful = true;
|
isSuccessful = true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Log.error("Import Comic", e.toString(), s);
|
Log.error("Import Comic", e.toString(), s);
|
||||||
|
@@ -24,11 +24,6 @@ class IO {
|
|||||||
static bool _isSelectingFiles = false;
|
static bool _isSelectingFiles = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A finalizer that can be used to dispose resources related to file operations.
|
|
||||||
final _finalizer = Finalizer<Function>((e) {
|
|
||||||
e();
|
|
||||||
});
|
|
||||||
|
|
||||||
class FilePath {
|
class FilePath {
|
||||||
const FilePath._();
|
const FilePath._();
|
||||||
|
|
||||||
@@ -162,53 +157,43 @@ String findValidDirectoryName(String path, String directory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DirectoryPicker {
|
class DirectoryPicker {
|
||||||
DirectoryPicker() {
|
/// Pick a directory.
|
||||||
_finalizer.attach(this, dispose);
|
///
|
||||||
}
|
/// The directory may not be usable after the instance is GCed.
|
||||||
|
DirectoryPicker();
|
||||||
|
|
||||||
String? _directory;
|
static final _finalizer = Finalizer<String>((path) {
|
||||||
|
if (path.startsWith(App.cachePath)) {
|
||||||
|
Directory(path).deleteIgnoreError();
|
||||||
|
}
|
||||||
|
if (App.isIOS || App.isMacOS) {
|
||||||
|
_methodChannel.invokeMethod("stopAccessingSecurityScopedResource");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
final _methodChannel = const MethodChannel("venera/method_channel");
|
static const _methodChannel = MethodChannel("venera/method_channel");
|
||||||
|
|
||||||
Future<Directory?> pickDirectory() async {
|
Future<Directory?> pickDirectory() async {
|
||||||
IO._isSelectingFiles = true;
|
IO._isSelectingFiles = true;
|
||||||
try {
|
try {
|
||||||
|
String? directory;
|
||||||
if (App.isWindows || App.isLinux) {
|
if (App.isWindows || App.isLinux) {
|
||||||
var d = await file_selector.getDirectoryPath();
|
directory = await file_selector.getDirectoryPath();
|
||||||
_directory = d;
|
|
||||||
return d == null ? null : Directory(d);
|
|
||||||
} else if (App.isAndroid) {
|
} else if (App.isAndroid) {
|
||||||
var d = await _methodChannel.invokeMethod<String?>("getDirectoryPath");
|
directory = await _methodChannel.invokeMethod<String?>("getDirectoryPath");
|
||||||
_directory = d;
|
|
||||||
return d == null ? null : Directory(d);
|
|
||||||
} else {
|
} else {
|
||||||
// ios, macos
|
// ios, macos
|
||||||
var d = await _methodChannel.invokeMethod<String?>("getDirectoryPath");
|
directory = await _methodChannel.invokeMethod<String?>("getDirectoryPath");
|
||||||
_directory = d;
|
|
||||||
return d == null ? null : Directory(d);
|
|
||||||
}
|
}
|
||||||
|
if (directory == null) return null;
|
||||||
|
_finalizer.attach(this, directory);
|
||||||
|
return Directory(directory);
|
||||||
} finally {
|
} finally {
|
||||||
Future.delayed(const Duration(milliseconds: 100), () {
|
Future.delayed(const Duration(milliseconds: 100), () {
|
||||||
IO._isSelectingFiles = false;
|
IO._isSelectingFiles = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
|
||||||
if (_directory == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (App.isAndroid &&
|
|
||||||
_directory != null &&
|
|
||||||
_directory!.startsWith(App.cachePath)) {
|
|
||||||
await Directory(_directory!).deleteIgnoreError(recursive: true);
|
|
||||||
_directory = null;
|
|
||||||
}
|
|
||||||
if (App.isIOS || App.isMacOS) {
|
|
||||||
await _methodChannel.invokeMethod("stopAccessingSecurityScopedResource");
|
|
||||||
_directory = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class IOSDirectoryPicker {
|
class IOSDirectoryPicker {
|
||||||
@@ -231,7 +216,7 @@ class IOSDirectoryPicker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<file_selector.XFile?> selectFile({required List<String> ext}) async {
|
Future<FileSelectResult?> selectFile({required List<String> ext}) async {
|
||||||
IO._isSelectingFiles = true;
|
IO._isSelectingFiles = true;
|
||||||
try {
|
try {
|
||||||
var extensions = App.isMacOS || App.isIOS ? null : ext;
|
var extensions = App.isMacOS || App.isIOS ? null : ext;
|
||||||
@@ -239,13 +224,13 @@ Future<file_selector.XFile?> selectFile({required List<String> ext}) async {
|
|||||||
label: 'files',
|
label: 'files',
|
||||||
extensions: extensions,
|
extensions: extensions,
|
||||||
);
|
);
|
||||||
file_selector.XFile? file;
|
FileSelectResult? file;
|
||||||
if (App.isAndroid) {
|
if (App.isAndroid) {
|
||||||
const selectFileChannel = MethodChannel("venera/select_file");
|
const selectFileChannel = MethodChannel("venera/select_file");
|
||||||
String mimeType = "*/*";
|
String mimeType = "*/*";
|
||||||
if(ext.length == 1) {
|
if (ext.length == 1) {
|
||||||
mimeType = FileType.fromExtension(ext[0]).mime;
|
mimeType = FileType.fromExtension(ext[0]).mime;
|
||||||
if(mimeType == "application/octet-stream") {
|
if (mimeType == "application/octet-stream") {
|
||||||
mimeType = "*/*";
|
mimeType = "*/*";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,12 +239,13 @@ Future<file_selector.XFile?> selectFile({required List<String> ext}) async {
|
|||||||
mimeType,
|
mimeType,
|
||||||
);
|
);
|
||||||
if (filePath == null) return null;
|
if (filePath == null) return null;
|
||||||
file = _AndroidFileSelectResult(filePath);
|
file = FileSelectResult(filePath);
|
||||||
} else {
|
} else {
|
||||||
file = await file_selector.openFile(
|
var xFile = await file_selector.openFile(
|
||||||
acceptedTypeGroups: <file_selector.XTypeGroup>[typeGroup],
|
acceptedTypeGroups: <file_selector.XTypeGroup>[typeGroup],
|
||||||
);
|
);
|
||||||
if (file == null) return null;
|
if (xFile == null) return null;
|
||||||
|
file = FileSelectResult(xFile.path);
|
||||||
}
|
}
|
||||||
if (!ext.contains(file.path.split(".").last)) {
|
if (!ext.contains(file.path.split(".").last)) {
|
||||||
App.rootContext.showMessage(message: "Invalid file type");
|
App.rootContext.showMessage(message: "Invalid file type");
|
||||||
@@ -360,15 +346,26 @@ String bytesToReadableString(int bytes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AndroidFileSelectResult extends s.XFile {
|
class FileSelectResult {
|
||||||
_AndroidFileSelectResult(super.path) {
|
final String path;
|
||||||
_finalizer.attach(this, dispose);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
static final _finalizer = Finalizer<String>((path) {
|
||||||
print("dispose $path");
|
|
||||||
if (path.startsWith(App.cachePath)) {
|
if (path.startsWith(App.cachePath)) {
|
||||||
File(path).deleteIgnoreError();
|
File(path).deleteIgnoreError();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FileSelectResult(this.path) {
|
||||||
|
_finalizer.attach(this, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> saveTo(String path) async {
|
||||||
|
await File(this.path).copy(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Uint8List> readAsBytes() {
|
||||||
|
return File(path).readAsBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
String get name => File(path).name;
|
||||||
}
|
}
|
Reference in New Issue
Block a user