mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-01-11 22:40:36 +00:00
local folders now also scans for subtitles
- added help button to show an example of a local folder
This commit is contained in:
parent
05d0ddf0d6
commit
5a6552e6f6
20 changed files with 205 additions and 8 deletions
|
|
@ -547,6 +547,7 @@
|
|||
"sequels": "Sequels",
|
||||
"recommendations": "Recommendations",
|
||||
"recommendations_similarity": "Similarity:",
|
||||
"local_folder_structure": "Structure of a local folder",
|
||||
"local_folder": "Local folders",
|
||||
"add_local_folder": "Add local folder",
|
||||
"rescan_local_folder": "Rescan all local folders now",
|
||||
|
|
|
|||
|
|
@ -3351,6 +3351,12 @@ abstract class AppLocalizations {
|
|||
/// **'Similarity:'**
|
||||
String get recommendations_similarity;
|
||||
|
||||
/// No description provided for @local_folder_structure.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Structure of a local folder'**
|
||||
String get local_folder_structure;
|
||||
|
||||
/// No description provided for @local_folder.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -1734,6 +1734,9 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1736,6 +1736,9 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1747,6 +1747,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1735,6 +1735,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1752,6 +1752,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1753,6 +1753,9 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1737,6 +1737,9 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1741,6 +1741,9 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1750,6 +1750,9 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1749,6 +1749,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1751,6 +1751,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1735,6 +1735,9 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1741,6 +1741,9 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -1706,6 +1706,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
|
||||
@override
|
||||
String get local_folder_structure => 'Structure of a local folder';
|
||||
|
||||
@override
|
||||
String get local_folder => 'Local folders';
|
||||
|
||||
|
|
|
|||
|
|
@ -332,8 +332,14 @@ class _SubtitlesWidgetSearchState extends ConsumerState<SubtitlesWidgetSearch> {
|
|||
try {
|
||||
final subtitle = subtitles![index];
|
||||
final storageProvider = StorageProvider();
|
||||
final animeDir =
|
||||
widget.chapter.archivePath != null &&
|
||||
widget.chapter.manga.value?.source == "local"
|
||||
? Directory(path.dirname(widget.chapter.archivePath!))
|
||||
: null;
|
||||
final chapterDirectory = (await storageProvider.getMangaChapterDirectory(
|
||||
widget.chapter,
|
||||
mangaMainDirectory: animeDir,
|
||||
))!;
|
||||
final subtitleFile = File(
|
||||
path.join(
|
||||
|
|
|
|||
|
|
@ -131,7 +131,9 @@ Future<void> _scanDirectory(Ref ref, Directory? dir) async {
|
|||
final files = children.whereType<File>().toList();
|
||||
|
||||
// Determine itemtype
|
||||
final hasImagesFolders = subDirs.isNotEmpty;
|
||||
final hasImagesFolders = subDirs
|
||||
.where((e) => !e.path.endsWith("_subtitles"))
|
||||
.isNotEmpty;
|
||||
final hasArchives = files.any((f) => _isArchive(f.path));
|
||||
final hasVideos = files.any((f) => _isVideo(f.path));
|
||||
final hasEpubs = files.any((f) => _isEpub(f.path));
|
||||
|
|
|
|||
|
|
@ -132,12 +132,21 @@ class _DownloadsScreenState extends ConsumerState<DownloadsScreen> {
|
|||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
context.l10n.local_folder,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
context.l10n.local_folder,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
OutlinedButton.icon(
|
||||
onPressed: () => _showHelpDialog(context),
|
||||
label: const Icon(Icons.question_mark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
FutureBuilder(
|
||||
|
|
@ -163,6 +172,133 @@ class _DownloadsScreenState extends ConsumerState<DownloadsScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
void _showHelpDialog(BuildContext context) {
|
||||
final data = (
|
||||
"LocalFolder",
|
||||
[
|
||||
(
|
||||
"MangaName",
|
||||
[
|
||||
("cover.jpg", Icons.image_outlined),
|
||||
(
|
||||
"Chapter1",
|
||||
[
|
||||
("Page1.jpg", Icons.image_outlined),
|
||||
("Page2.jpeg", Icons.image_outlined),
|
||||
("Page3.png", Icons.image_outlined),
|
||||
("Page4.webp", Icons.image_outlined),
|
||||
],
|
||||
),
|
||||
("Chapter2.cbz", Icons.folder_zip_outlined),
|
||||
("Chapter3.zip", Icons.folder_zip_outlined),
|
||||
("Chapter4.cbt", Icons.folder_zip_outlined),
|
||||
("Chapter5.tar", Icons.folder_zip_outlined),
|
||||
],
|
||||
),
|
||||
(
|
||||
"AnimeName",
|
||||
[
|
||||
("cover.jpg", Icons.image_outlined),
|
||||
("Episode1.mp4", Icons.video_file_outlined),
|
||||
(
|
||||
"Episode1_subtitles",
|
||||
[
|
||||
("en.srt", Icons.subtitles_outlined),
|
||||
("de.srt", Icons.subtitles_outlined),
|
||||
],
|
||||
),
|
||||
("Episode2.mov", Icons.video_file_outlined),
|
||||
("Episode3.avi", Icons.video_file_outlined),
|
||||
("Episode4.flv", Icons.video_file_outlined),
|
||||
("Episode5.wmv", Icons.video_file_outlined),
|
||||
("Episode6.mpeg", Icons.video_file_outlined),
|
||||
("Episode7.mkv", Icons.video_file_outlined),
|
||||
],
|
||||
),
|
||||
(
|
||||
"NovelName",
|
||||
[
|
||||
("cover.jpg", Icons.image_outlined),
|
||||
("NovelName.epub", Icons.book_outlined),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Widget buildSubFolder((String, dynamic) data, int level) {
|
||||
if (data.$2 is List) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
for (int i = 1; i < level; i++)
|
||||
const WidgetSpan(child: SizedBox(width: 20)),
|
||||
if (level > 0)
|
||||
WidgetSpan(child: Icon(Icons.subdirectory_arrow_right)),
|
||||
WidgetSpan(child: Icon(Icons.folder)),
|
||||
const WidgetSpan(child: SizedBox(width: 5)),
|
||||
TextSpan(text: data.$1),
|
||||
],
|
||||
),
|
||||
),
|
||||
...(data.$2 as List<(String, dynamic)>).map(
|
||||
(e) => buildSubFolder(e, level + 1),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
for (int i = 1; i < level; i++)
|
||||
const WidgetSpan(child: SizedBox(width: 20)),
|
||||
if (level > 0)
|
||||
WidgetSpan(child: Icon(Icons.subdirectory_arrow_right)),
|
||||
WidgetSpan(child: Icon(data.$2 as IconData)),
|
||||
const WidgetSpan(child: SizedBox(width: 5)),
|
||||
TextSpan(text: data.$1),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: Text(context.l10n.local_folder_structure),
|
||||
content: SizedBox(
|
||||
width: context.width(0.6),
|
||||
height: context.height(0.8),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: SingleChildScrollView(child: buildSubFolder(data, 0)),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.l10n.cancel),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLocalFolder(
|
||||
AppLocalizations l10n,
|
||||
List<String> localFolders,
|
||||
|
|
|
|||
|
|
@ -32,9 +32,13 @@ Future<(List<Video>, bool, List<String>, Directory?)> getVideoList(
|
|||
);
|
||||
List<String> infoHashes = [];
|
||||
if (await File(mp4animePath).exists() || isLocalArchive) {
|
||||
final animeDir =
|
||||
episode.archivePath != null && episode.manga.value?.source == "local"
|
||||
? Directory(p.dirname(episode.archivePath!))
|
||||
: null;
|
||||
final chapterDirectory = (await storageProvider.getMangaChapterDirectory(
|
||||
episode,
|
||||
mangaMainDirectory: mangaDirectory,
|
||||
mangaMainDirectory: animeDir ?? mangaDirectory,
|
||||
))!;
|
||||
final path = isLocalArchive ? episode.archivePath : mp4animePath;
|
||||
final subtitlesDir = Directory(
|
||||
|
|
|
|||
Loading…
Reference in a new issue