mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-20 23:22:07 +00:00
feat #682 option to split chapter whe importing local epub
This commit is contained in:
parent
f7ec660543
commit
0df04bcfad
26 changed files with 367 additions and 66 deletions
|
|
@ -196,6 +196,8 @@
|
|||
"total_episodes": "Gesamtepisoden",
|
||||
"import_local_file": "Lokale Datei importieren",
|
||||
"import_files": "Dateien",
|
||||
"split_epub_chapters": "In Kapitel aufteilen",
|
||||
"split_epub_chapters_description": "Jedes EPUB-Kapitel als separaten Eintrag importieren",
|
||||
"nothing_read_recently": "Kürzlich nichts gelesen",
|
||||
"status": "Status",
|
||||
"not_started": "Nicht begonnen",
|
||||
|
|
|
|||
|
|
@ -388,6 +388,8 @@
|
|||
"total_episodes": "Total episodes",
|
||||
"import_local_file": "Import Local file",
|
||||
"import_files": "Files",
|
||||
"split_epub_chapters": "Split into chapters",
|
||||
"split_epub_chapters_description": "Import each EPUB chapter as a separate entry",
|
||||
"nothing_read_recently": "Nothing read recently",
|
||||
"status": "Status",
|
||||
"not_started": "Not started",
|
||||
|
|
@ -830,5 +832,6 @@
|
|||
"extension_server_jar_imported": "Extension server JAR was imported.",
|
||||
"could_not_launch_apk_bridge_page": "Could not launch the ApkBridge page.",
|
||||
"proxy_server_ip_hint": "Server IP (e.g., 10.0.0.5 or https://example.com)",
|
||||
"not_configured": "Not configured"
|
||||
"not_configured": "Not configured",
|
||||
"webview": "Webview"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1619,6 +1619,18 @@ abstract class AppLocalizations {
|
|||
/// **'Files'**
|
||||
String get import_files;
|
||||
|
||||
/// No description provided for @split_epub_chapters.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Split into chapters'**
|
||||
String get split_epub_chapters;
|
||||
|
||||
/// No description provided for @split_epub_chapters_description.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Import each EPUB chapter as a separate entry'**
|
||||
String get split_epub_chapters_description;
|
||||
|
||||
/// No description provided for @nothing_read_recently.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -4240,6 +4252,12 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'Not configured'**
|
||||
String get not_configured;
|
||||
|
||||
/// No description provided for @webview.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Webview'**
|
||||
String get webview;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -869,6 +869,13 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'ملفات';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'لم يتم قراءة شيء مؤخراً';
|
||||
|
||||
|
|
@ -2286,4 +2293,7 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,6 +871,13 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'ফাইল';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'শেহতীয়াকৈ একো পঢ়া নাই';
|
||||
|
||||
|
|
@ -2292,4 +2299,7 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -873,6 +873,13 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Dateien';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'In Kapitel aufteilen';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Jedes EPUB-Kapitel als separaten Eintrag importieren';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Kürzlich nichts gelesen';
|
||||
|
||||
|
|
@ -2308,4 +2315,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,6 +871,13 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Files';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Nothing read recently';
|
||||
|
||||
|
|
@ -2286,4 +2293,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -875,6 +875,13 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Archivos';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Nada leído recientemente';
|
||||
|
||||
|
|
@ -2315,6 +2322,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
||||
/// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`).
|
||||
|
|
|
|||
|
|
@ -877,6 +877,13 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Fichiers';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Rien de lu recemment';
|
||||
|
||||
|
|
@ -2316,4 +2323,7 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,6 +871,13 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'फ़ाइलें';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'हाल ही में कुछ भी नहीं पढ़ा';
|
||||
|
||||
|
|
@ -2292,4 +2299,7 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -875,6 +875,13 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'File';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Tidak ada yang dibaca baru-baru ini';
|
||||
|
||||
|
|
@ -2298,4 +2305,7 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -875,6 +875,13 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'File';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Niente letto di recente';
|
||||
|
||||
|
|
@ -2312,4 +2319,7 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -864,6 +864,13 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'ファイル';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => '最近読んだものがありません';
|
||||
|
||||
|
|
@ -2258,4 +2265,7 @@ class AppLocalizationsJa extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -875,6 +875,13 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Arquivos';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Nada lido recentemente';
|
||||
|
||||
|
|
@ -2310,6 +2317,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
||||
/// The translations for Portuguese, as used in Brazil (`pt_BR`).
|
||||
|
|
|
|||
|
|
@ -876,6 +876,13 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Файлы';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Недавно ничего не читалось';
|
||||
|
||||
|
|
@ -2316,4 +2323,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,6 +871,13 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'ไฟล์';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'ยังไม่ได้อ่านอะไรเลย';
|
||||
|
||||
|
|
@ -2286,4 +2293,7 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,6 +871,13 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => 'Dosyalar';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => 'Son Zamanlarda Okunan Bir Şey Yok';
|
||||
|
||||
|
|
@ -2299,4 +2306,7 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -862,6 +862,13 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get import_files => '文件';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters => 'Split into chapters';
|
||||
|
||||
@override
|
||||
String get split_epub_chapters_description =>
|
||||
'Import each EPUB chapter as a separate entry';
|
||||
|
||||
@override
|
||||
String get nothing_read_recently => '最近未阅读';
|
||||
|
||||
|
|
@ -2239,4 +2246,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get not_configured => 'Not configured';
|
||||
|
||||
@override
|
||||
String get webview => 'Webview';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -295,21 +295,37 @@ Future<void> _scanDirectory(Ref ref, Directory? dir) async {
|
|||
if (manga.itemType == ItemType.novel) {
|
||||
final book = await parseEpubFromPath(
|
||||
epubPath: chapterPath,
|
||||
fullData: false,
|
||||
fullData: true,
|
||||
);
|
||||
|
||||
if (book.cover != null) {
|
||||
manga.customCoverImage = book.cover!.getCoverImage;
|
||||
saveManga++;
|
||||
}
|
||||
chaptersToSave.add(
|
||||
Chapter(
|
||||
mangaId: manga.id,
|
||||
name: book.name,
|
||||
archivePath: chapterPath,
|
||||
downloadSize: null,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
final chaps = book.chapters;
|
||||
if (chaps.isNotEmpty) {
|
||||
for (int i = 0; i < chaps.length; i++) {
|
||||
final epubChapter = chaps[i];
|
||||
chaptersToSave.add(
|
||||
Chapter(
|
||||
mangaId: manga.id,
|
||||
name: epubChapter.name,
|
||||
archivePath: chapterPath,
|
||||
url: epubChapter.path,
|
||||
downloadSize: null,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
chaptersToSave.add(
|
||||
Chapter(
|
||||
mangaId: manga.id,
|
||||
name: book.name,
|
||||
archivePath: chapterPath,
|
||||
downloadSize: null,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
final chapterFile = File(chapterPath);
|
||||
final chap = Chapter(
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ Future importArchivesFromFile(
|
|||
Manga? mManga, {
|
||||
required ItemType itemType,
|
||||
required bool init,
|
||||
bool splitChapters = true,
|
||||
}) async {
|
||||
final keepAlile = ref.keepAlive();
|
||||
try {
|
||||
|
|
@ -72,7 +73,7 @@ Future importArchivesFromFile(
|
|||
if (itemType == ItemType.novel) {
|
||||
final book = await parseEpubFromPath(
|
||||
epubPath: file.path!,
|
||||
fullData: false,
|
||||
fullData: splitChapters,
|
||||
);
|
||||
|
||||
if (book.cover != null) {
|
||||
|
|
@ -80,14 +81,32 @@ Future importArchivesFromFile(
|
|||
manga..customCoverImage = book.cover!.getCoverImage,
|
||||
);
|
||||
}
|
||||
chapters.add(
|
||||
Chapter(
|
||||
mangaId: mangaId,
|
||||
name: book.name,
|
||||
archivePath: file.path,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
final chaps = book.chapters;
|
||||
|
||||
if (splitChapters && chaps.isNotEmpty) {
|
||||
for (int i = 0; i < chaps.length; i++) {
|
||||
final epubChapter = chaps[i];
|
||||
chapters.add(
|
||||
Chapter(
|
||||
mangaId: mangaId,
|
||||
name: epubChapter.name,
|
||||
archivePath: file.path,
|
||||
url: epubChapter.path,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Fallback: single chapter if no spine chapters found
|
||||
chapters.add(
|
||||
Chapter(
|
||||
mangaId: mangaId,
|
||||
name: book.name,
|
||||
archivePath: file.path,
|
||||
updatedAt: DateTime.now().millisecondsSinceEpoch,
|
||||
)..manga.value = manga,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
chapters.add(
|
||||
Chapter(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ final class ImportArchivesFromFileProvider
|
|||
with $FutureModifier<dynamic>, $FutureProvider<dynamic> {
|
||||
ImportArchivesFromFileProvider._({
|
||||
required ImportArchivesFromFileFamily super.from,
|
||||
required (Manga?, {ItemType itemType, bool init}) super.argument,
|
||||
required (Manga?, {ItemType itemType, bool init, bool splitChapters})
|
||||
super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'importArchivesFromFileProvider',
|
||||
|
|
@ -43,12 +44,15 @@ final class ImportArchivesFromFileProvider
|
|||
|
||||
@override
|
||||
FutureOr<dynamic> create(Ref ref) {
|
||||
final argument = this.argument as (Manga?, {ItemType itemType, bool init});
|
||||
final argument =
|
||||
this.argument
|
||||
as (Manga?, {ItemType itemType, bool init, bool splitChapters});
|
||||
return importArchivesFromFile(
|
||||
ref,
|
||||
argument.$1,
|
||||
itemType: argument.itemType,
|
||||
init: argument.init,
|
||||
splitChapters: argument.splitChapters,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -65,13 +69,13 @@ final class ImportArchivesFromFileProvider
|
|||
}
|
||||
|
||||
String _$importArchivesFromFileHash() =>
|
||||
r'52d80a07200627e1bc650b06d1fd8aed66c03e4c';
|
||||
r'f7b2e8cb611bfc32c83e1dcffffb2ad7122f1067';
|
||||
|
||||
final class ImportArchivesFromFileFamily extends $Family
|
||||
with
|
||||
$FunctionalFamilyOverride<
|
||||
FutureOr<dynamic>,
|
||||
(Manga?, {ItemType itemType, bool init})
|
||||
(Manga?, {ItemType itemType, bool init, bool splitChapters})
|
||||
> {
|
||||
ImportArchivesFromFileFamily._()
|
||||
: super(
|
||||
|
|
@ -86,8 +90,14 @@ final class ImportArchivesFromFileFamily extends $Family
|
|||
Manga? mManga, {
|
||||
required ItemType itemType,
|
||||
required bool init,
|
||||
bool splitChapters = true,
|
||||
}) => ImportArchivesFromFileProvider._(
|
||||
argument: (mManga, itemType: itemType, init: init),
|
||||
argument: (
|
||||
mManga,
|
||||
itemType: itemType,
|
||||
init: init,
|
||||
splitChapters: splitChapters,
|
||||
),
|
||||
from: this,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ void showImportLocalDialog(BuildContext context, ItemType itemType) {
|
|||
ItemType.novel => ".epub",
|
||||
};
|
||||
bool isLoading = false;
|
||||
bool splitChapters = true;
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: !isLoading,
|
||||
|
|
@ -274,50 +275,75 @@ void showImportLocalDialog(BuildContext context, ItemType itemType) {
|
|||
return Consumer(
|
||||
builder: (context, ref, child) {
|
||||
return SizedBox(
|
||||
height: 100,
|
||||
height: itemType == ItemType.novel ? 150 : 100,
|
||||
child: Stack(
|
||||
children: [
|
||||
Row(
|
||||
Column(
|
||||
children: [
|
||||
if (itemType == ItemType.novel)
|
||||
SwitchListTile(
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(
|
||||
l10n.split_epub_chapters,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
subtitle: Text(
|
||||
l10n.split_epub_chapters_description,
|
||||
style: const TextStyle(fontSize: 10),
|
||||
),
|
||||
value: splitChapters,
|
||||
onChanged: (v) =>
|
||||
setState(() => splitChapters = v),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
itemType: itemType,
|
||||
null,
|
||||
init: true,
|
||||
).future,
|
||||
);
|
||||
setState(() => isLoading = false);
|
||||
if (!context.mounted) return;
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
const Icon(Icons.archive_outlined),
|
||||
Text(
|
||||
"${l10n.import_files} ( $filesText )",
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall!.color,
|
||||
fontSize: 10,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
setState(() => isLoading = true);
|
||||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
itemType: itemType,
|
||||
null,
|
||||
init: true,
|
||||
splitChapters: splitChapters,
|
||||
).future,
|
||||
);
|
||||
setState(() => isLoading = false);
|
||||
if (!context.mounted) return;
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
const Icon(Icons.archive_outlined),
|
||||
Text(
|
||||
"${l10n.import_files} ( $filesText )",
|
||||
style: TextStyle(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall!.color,
|
||||
fontSize: 10,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -868,12 +868,24 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
manga: manga,
|
||||
);
|
||||
} else {
|
||||
final splitChapters =
|
||||
manga.itemType ==
|
||||
ItemType.novel
|
||||
? await _showSplitChaptersDialog(
|
||||
context,
|
||||
)
|
||||
: true;
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
itemType:
|
||||
manga.itemType,
|
||||
manga,
|
||||
init: false,
|
||||
splitChapters:
|
||||
splitChapters,
|
||||
).future,
|
||||
);
|
||||
}
|
||||
|
|
@ -1859,11 +1871,19 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
if (manga!.source == "torrent") {
|
||||
addTorrent(context, manga: manga);
|
||||
} else {
|
||||
final splitChapters =
|
||||
manga.itemType == ItemType.novel
|
||||
? await _showSplitChaptersDialog(
|
||||
context,
|
||||
)
|
||||
: true;
|
||||
if (!context.mounted) return;
|
||||
await ref.watch(
|
||||
importArchivesFromFileProvider(
|
||||
itemType: manga.itemType,
|
||||
manga,
|
||||
init: false,
|
||||
splitChapters: splitChapters,
|
||||
).future,
|
||||
);
|
||||
}
|
||||
|
|
@ -1988,7 +2008,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'WebView',
|
||||
context.l10n.webview,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: context.secondaryColor,
|
||||
|
|
@ -2564,3 +2584,25 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _showSplitChaptersDialog(BuildContext context) async {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(l10n.split_epub_chapters),
|
||||
content: Text(l10n.split_epub_chapters_description),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
child: Text(l10n.split_epub_chapters),
|
||||
),
|
||||
],
|
||||
),
|
||||
) ??
|
||||
true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,23 @@ Future<(String, EpubNovel?)> getHtmlContent(
|
|||
fullData: true,
|
||||
);
|
||||
String htmlContent = "";
|
||||
for (var subChapter in book.chapters) {
|
||||
htmlContent += "\n<hr/>\n${subChapter.content}";
|
||||
if (chapter.url != null && chapter.url!.isNotEmpty) {
|
||||
// Load specific chapter by its spine idref
|
||||
final matches = book.chapters.where((c) => c.path == chapter.url);
|
||||
if (matches.isNotEmpty) {
|
||||
htmlContent = matches.first.content;
|
||||
} else {
|
||||
// Fallback: try via Rust direct access
|
||||
htmlContent = await getChapterContent(
|
||||
epubPath: chapter.archivePath!,
|
||||
chapterPath: chapter.url!,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Legacy: no chapter url, concatenate all (old single-chapter imports)
|
||||
for (var subChapter in book.chapters) {
|
||||
htmlContent += "\n<hr/>\n${subChapter.content}";
|
||||
}
|
||||
}
|
||||
result = (_buildHtml(htmlContent), book);
|
||||
} catch (_) {}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ final class GetHtmlContentProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$getHtmlContentHash() => r'03e421b7f7e821526c47f3b460fc9d866f56c9f6';
|
||||
String _$getHtmlContentHash() => r'b3f9bf922e2aad2d4e34a64cf08a6a755b743921';
|
||||
|
||||
final class GetHtmlContentFamily extends $Family
|
||||
with $FunctionalFamilyOverride<FutureOr<(String, EpubNovel?)>, Chapter> {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ final class HeadersProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$headersHash() => r'b73ec60e965527495b5ac8ee96c8e23cc1392a56';
|
||||
String _$headersHash() => r'35df3bf8876e8be44fa4a8fbe57097f1329601b7';
|
||||
|
||||
final class HeadersFamily extends $Family
|
||||
with
|
||||
|
|
|
|||
Loading…
Reference in a new issue