mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Local Comic: Add "Open Folder" button (#443)
This commit is contained in:
@@ -398,6 +398,7 @@
|
|||||||
"Clear Unfavorited": "清除未收藏",
|
"Clear Unfavorited": "清除未收藏",
|
||||||
"Reverse": "反转",
|
"Reverse": "反转",
|
||||||
"Delete Chapters": "删除章节",
|
"Delete Chapters": "删除章节",
|
||||||
|
"Open Folder": "打开文件夹",
|
||||||
"Path copied to clipboard": "路径已复制到剪贴板",
|
"Path copied to clipboard": "路径已复制到剪贴板",
|
||||||
"Reverse default chapter order": "反转默认章节顺序"
|
"Reverse default chapter order": "反转默认章节顺序"
|
||||||
},
|
},
|
||||||
@@ -800,6 +801,7 @@
|
|||||||
"Clear Unfavorited": "清除未收藏",
|
"Clear Unfavorited": "清除未收藏",
|
||||||
"Reverse": "反轉",
|
"Reverse": "反轉",
|
||||||
"Delete Chapters": "刪除章節",
|
"Delete Chapters": "刪除章節",
|
||||||
|
"Open Folder": "打開資料夾",
|
||||||
"Path copied to clipboard": "路徑已複製到剪貼簿",
|
"Path copied to clipboard": "路徑已複製到剪貼簿",
|
||||||
"Reverse default chapter order": "反轉預設章節順序"
|
"Reverse default chapter order": "反轉預設章節順序"
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ import 'package:venera/utils/io.dart';
|
|||||||
import 'package:venera/utils/pdf.dart';
|
import 'package:venera/utils/pdf.dart';
|
||||||
import 'package:venera/utils/translations.dart';
|
import 'package:venera/utils/translations.dart';
|
||||||
import 'package:zip_flutter/zip_flutter.dart';
|
import 'package:zip_flutter/zip_flutter.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
class LocalComicsPage extends StatefulWidget {
|
class LocalComicsPage extends StatefulWidget {
|
||||||
const LocalComicsPage({super.key});
|
const LocalComicsPage({super.key});
|
||||||
@@ -143,6 +144,14 @@ class _LocalComicsPageState extends State<LocalComicsPage> {
|
|||||||
addFavorite(selectedComics.keys.toList());
|
addFavorite(selectedComics.keys.toList());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (selectedComics.length == 1)
|
||||||
|
MenuEntry(
|
||||||
|
icon: Icons.folder_open,
|
||||||
|
text: "Open Folder".tl,
|
||||||
|
onClick: () {
|
||||||
|
openComicFolder(selectedComics.keys.first);
|
||||||
|
},
|
||||||
|
),
|
||||||
if (selectedComics.length == 1)
|
if (selectedComics.length == 1)
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.chrome_reader_mode_outlined,
|
icon: Icons.chrome_reader_mode_outlined,
|
||||||
@@ -313,6 +322,13 @@ class _LocalComicsPageState extends State<LocalComicsPage> {
|
|||||||
},
|
},
|
||||||
menuBuilder: (c) {
|
menuBuilder: (c) {
|
||||||
return [
|
return [
|
||||||
|
MenuEntry(
|
||||||
|
icon: Icons.folder_open,
|
||||||
|
text: "Open Folder".tl,
|
||||||
|
onClick: () {
|
||||||
|
openComicFolder(c as LocalComic);
|
||||||
|
},
|
||||||
|
),
|
||||||
MenuEntry(
|
MenuEntry(
|
||||||
icon: Icons.delete,
|
icon: Icons.delete,
|
||||||
text: "Delete".tl,
|
text: "Delete".tl,
|
||||||
@@ -519,6 +535,49 @@ class _LocalComicsPageState extends State<LocalComicsPage> {
|
|||||||
typedef ExportComicFunc = Future<File> Function(
|
typedef ExportComicFunc = Future<File> Function(
|
||||||
LocalComic comic, String outFilePath);
|
LocalComic comic, String outFilePath);
|
||||||
|
|
||||||
|
/// Opens the folder containing the comic in the system file explorer
|
||||||
|
Future<void> openComicFolder(LocalComic comic) async {
|
||||||
|
try {
|
||||||
|
final folderPath = comic.baseDir;
|
||||||
|
|
||||||
|
if (App.isWindows) {
|
||||||
|
await Process.run('explorer', [folderPath]);
|
||||||
|
} else if (App.isMacOS) {
|
||||||
|
await Process.run('open', [folderPath]);
|
||||||
|
} else if (App.isLinux) {
|
||||||
|
// Try different file managers commonly found on Linux
|
||||||
|
try {
|
||||||
|
await Process.run('xdg-open', [folderPath]);
|
||||||
|
} catch (e) {
|
||||||
|
// Fallback to other common file managers
|
||||||
|
try {
|
||||||
|
await Process.run('nautilus', [folderPath]);
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
await Process.run('dolphin', [folderPath]);
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
await Process.run('thunar', [folderPath]);
|
||||||
|
} catch (e) {
|
||||||
|
// Last resort: use the URL launcher with file:// protocol
|
||||||
|
await launchUrlString('file://$folderPath');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// For mobile platforms, use the URL launcher with file:// protocol
|
||||||
|
await launchUrlString('file://$folderPath');
|
||||||
|
}
|
||||||
|
} catch (e, s) {
|
||||||
|
Log.error("Open Folder", "Failed to open comic folder: $e", s);
|
||||||
|
// Show error message to user
|
||||||
|
if (App.rootContext.mounted) {
|
||||||
|
App.rootContext.showMessage(message: "Failed to open folder: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void showDeleteChaptersPopWindow(BuildContext context, LocalComic comic) {
|
void showDeleteChaptersPopWindow(BuildContext context, LocalComic comic) {
|
||||||
var chapters = <String>[];
|
var chapters = <String>[];
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user