diff --git a/app/build.gradle b/app/build.gradle
index 4a163d768..ccdc454a6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -77,6 +77,7 @@ android {
'-opt-in=kotlin.contracts.ExperimentalContracts',
'-opt-in=coil3.annotation.ExperimentalCoilApi',
'-opt-in=coil3.annotation.InternalCoilApi',
+ '-opt-in=kotlinx.serialization.ExperimentalSerializationApi',
'-Xjspecify-annotations=strict',
'-Xtype-enhancement-improvements-strict-mode'
]
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 00337a665..3075e06f8 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -20,7 +20,7 @@
-keep class org.koitharu.kotatsu.core.exceptions.* { *; }
-keep class org.koitharu.kotatsu.settings.NotificationSettingsLegacyFragment
-keep class org.koitharu.kotatsu.core.prefs.ScreenshotsPolicy { *; }
--keep class org.koitharu.kotatsu.settings.backup.PeriodicalBackupSettingsFragment { *; }
+-keep class org.koitharu.kotatsu.backups.ui.periodical.PeriodicalBackupSettingsFragment { *; }
-keep class org.jsoup.parser.Tag
-keep class org.jsoup.internal.StringUtil
diff --git a/app/src/androidTest/assets/manga/bad_ids.json b/app/src/androidTest/assets/manga/bad_ids.json
index d0f9001a0..b2fc2189f 100644
--- a/app/src/androidTest/assets/manga/bad_ids.json
+++ b/app/src/androidTest/assets/manga/bad_ids.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,13 +30,15 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": "Продолжение истории о загадочной девушке по имени Эманон, которая помнит всё, что происходило на Земле за последние три миллиарда лет. \n
Начало истории читайте в \"Воспоминаниях Эманон\". \n
",
"chapters": [
{
"id": 1552943969433540704,
- "name": "1 - 1",
+ "title": "1 - 1",
"number": 1,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/1",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -43,8 +46,9 @@
},
{
"id": 1552943969433540705,
- "name": "1 - 2",
+ "title": "1 - 2",
"number": 2,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/2",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -52,8 +56,9 @@
},
{
"id": 1552943969433540706,
- "name": "1 - 3",
+ "title": "1 - 3",
"number": 3,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/3",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -61,8 +66,9 @@
},
{
"id": 1552943969433540707,
- "name": "1 - 4",
+ "title": "1 - 4",
"number": 4,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/4",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -70,8 +76,9 @@
},
{
"id": 1552943969433540708,
- "name": "1 - 5",
+ "title": "1 - 5",
"number": 5,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/5",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -79,8 +86,9 @@
},
{
"id": 1552943969433541665,
- "name": "2 - 1",
+ "title": "2 - 1",
"number": 6,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/1",
"scanlator": "Sup!",
"uploadDate": 1415570400000,
@@ -88,8 +96,9 @@
},
{
"id": 1552943969433541666,
- "name": "2 - 2",
+ "title": "2 - 2",
"number": 7,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/2",
"scanlator": "Sup!",
"uploadDate": 1419976800000,
@@ -97,8 +106,9 @@
},
{
"id": 1552943969433541667,
- "name": "2 - 3",
+ "title": "2 - 3",
"number": 8,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/3",
"scanlator": "Sup!",
"uploadDate": 1427922000000,
@@ -106,8 +116,9 @@
},
{
"id": 1552943969433541668,
- "name": "2 - 4",
+ "title": "2 - 4",
"number": 9,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/4",
"scanlator": "Sup!",
"uploadDate": 1436907600000,
@@ -115,8 +126,9 @@
},
{
"id": 1552943969433541669,
- "name": "2 - 5",
+ "title": "2 - 5",
"number": 10,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/5",
"scanlator": "Sup!",
"uploadDate": 1446674400000,
@@ -124,8 +136,9 @@
},
{
"id": 1552943969433541670,
- "name": "2 - 6",
+ "title": "2 - 6",
"number": 11,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/6",
"scanlator": "Sup!",
"uploadDate": 1451512800000,
@@ -133,8 +146,9 @@
},
{
"id": 1552943969433542626,
- "name": "3 - 1",
+ "title": "3 - 1",
"number": 12,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/1",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -142,8 +156,9 @@
},
{
"id": 1552943969433542627,
- "name": "3 - 2",
+ "title": "3 - 2",
"number": 13,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/2",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -151,8 +166,9 @@
},
{
"id": 1552943969433542628,
- "name": "3 - 3",
+ "title": "3 - 3",
"number": 14,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/3",
"scanlator": "",
"uploadDate": 1465851600000,
@@ -160,4 +176,4 @@
}
],
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/assets/manga/empty.json b/app/src/androidTest/assets/manga/empty.json
index 369f0e237..3716b0db7 100644
--- a/app/src/androidTest/assets/manga/empty.json
+++ b/app/src/androidTest/assets/manga/empty.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,8 +30,9 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": "Продолжение истории о загадочной девушке по имени Эманон, которая помнит всё, что происходило на Земле за последние три миллиарда лет. \n
Начало истории читайте в \"Воспоминаниях Эманон\". \n",
"chapters": [],
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/assets/manga/first_chapters.json b/app/src/androidTest/assets/manga/first_chapters.json
index 697dec9c8..ed45c3cf6 100644
--- a/app/src/androidTest/assets/manga/first_chapters.json
+++ b/app/src/androidTest/assets/manga/first_chapters.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,13 +30,15 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": "Продолжение истории о загадочной девушке по имени Эманон, которая помнит всё, что происходило на Земле за последние три миллиарда лет. \n
Начало истории читайте в \"Воспоминаниях Эманон\". \n",
"chapters": [
{
"id": 3552943969433540704,
- "name": "1 - 1",
+ "title": "1 - 1",
"number": 1,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/1",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -43,8 +46,9 @@
},
{
"id": 3552943969433540705,
- "name": "1 - 2",
+ "title": "1 - 2",
"number": 2,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/2",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -52,8 +56,9 @@
},
{
"id": 3552943969433540706,
- "name": "1 - 3",
+ "title": "1 - 3",
"number": 3,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/3",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -61,8 +66,9 @@
},
{
"id": 3552943969433540707,
- "name": "1 - 4",
+ "title": "1 - 4",
"number": 4,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/4",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -70,8 +76,9 @@
},
{
"id": 3552943969433540708,
- "name": "1 - 5",
+ "title": "1 - 5",
"number": 5,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/5",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -79,8 +86,9 @@
},
{
"id": 3552943969433541665,
- "name": "2 - 1",
+ "title": "2 - 1",
"number": 6,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/1",
"scanlator": "Sup!",
"uploadDate": 1415570400000,
@@ -88,8 +96,9 @@
},
{
"id": 3552943969433541666,
- "name": "2 - 2",
+ "title": "2 - 2",
"number": 7,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/2",
"scanlator": "Sup!",
"uploadDate": 1419976800000,
@@ -97,8 +106,9 @@
},
{
"id": 3552943969433541667,
- "name": "2 - 3",
+ "title": "2 - 3",
"number": 8,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/3",
"scanlator": "Sup!",
"uploadDate": 1427922000000,
@@ -106,8 +116,9 @@
},
{
"id": 3552943969433541668,
- "name": "2 - 4",
+ "title": "2 - 4",
"number": 9,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/4",
"scanlator": "Sup!",
"uploadDate": 1436907600000,
@@ -115,8 +126,9 @@
},
{
"id": 3552943969433541669,
- "name": "2 - 5",
+ "title": "2 - 5",
"number": 10,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/5",
"scanlator": "Sup!",
"uploadDate": 1446674400000,
@@ -124,8 +136,9 @@
},
{
"id": 3552943969433541670,
- "name": "2 - 6",
+ "title": "2 - 6",
"number": 11,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/6",
"scanlator": "Sup!",
"uploadDate": 1451512800000,
@@ -133,4 +146,4 @@
}
],
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/assets/manga/full.json b/app/src/androidTest/assets/manga/full.json
index 9667baa9c..194bf6cd8 100644
--- a/app/src/androidTest/assets/manga/full.json
+++ b/app/src/androidTest/assets/manga/full.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,13 +30,15 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": "Продолжение истории о загадочной девушке по имени Эманон, которая помнит всё, что происходило на Земле за последние три миллиарда лет. \n
Начало истории читайте в \"Воспоминаниях Эманон\". \n",
"chapters": [
{
"id": 3552943969433540704,
- "name": "1 - 1",
+ "title": "1 - 1",
"number": 1,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/1",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -43,8 +46,9 @@
},
{
"id": 3552943969433540705,
- "name": "1 - 2",
+ "title": "1 - 2",
"number": 2,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/2",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -52,8 +56,9 @@
},
{
"id": 3552943969433540706,
- "name": "1 - 3",
+ "title": "1 - 3",
"number": 3,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/3",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -61,8 +66,9 @@
},
{
"id": 3552943969433540707,
- "name": "1 - 4",
+ "title": "1 - 4",
"number": 4,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/4",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -70,8 +76,9 @@
},
{
"id": 3552943969433540708,
- "name": "1 - 5",
+ "title": "1 - 5",
"number": 5,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/5",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -79,8 +86,9 @@
},
{
"id": 3552943969433541665,
- "name": "2 - 1",
+ "title": "2 - 1",
"number": 6,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/1",
"scanlator": "Sup!",
"uploadDate": 1415570400000,
@@ -88,8 +96,9 @@
},
{
"id": 3552943969433541666,
- "name": "2 - 2",
+ "title": "2 - 2",
"number": 7,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/2",
"scanlator": "Sup!",
"uploadDate": 1419976800000,
@@ -97,8 +106,9 @@
},
{
"id": 3552943969433541667,
- "name": "2 - 3",
+ "title": "2 - 3",
"number": 8,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/3",
"scanlator": "Sup!",
"uploadDate": 1427922000000,
@@ -106,8 +116,9 @@
},
{
"id": 3552943969433541668,
- "name": "2 - 4",
+ "title": "2 - 4",
"number": 9,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/4",
"scanlator": "Sup!",
"uploadDate": 1436907600000,
@@ -115,8 +126,9 @@
},
{
"id": 3552943969433541669,
- "name": "2 - 5",
+ "title": "2 - 5",
"number": 10,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/5",
"scanlator": "Sup!",
"uploadDate": 1446674400000,
@@ -124,8 +136,9 @@
},
{
"id": 3552943969433541670,
- "name": "2 - 6",
+ "title": "2 - 6",
"number": 11,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/6",
"scanlator": "Sup!",
"uploadDate": 1451512800000,
@@ -133,8 +146,9 @@
},
{
"id": 3552943969433542626,
- "name": "3 - 1",
+ "title": "3 - 1",
"number": 12,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/1",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -142,8 +156,9 @@
},
{
"id": 3552943969433542627,
- "name": "3 - 2",
+ "title": "3 - 2",
"number": 13,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/2",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -151,8 +166,9 @@
},
{
"id": 3552943969433542628,
- "name": "3 - 3",
+ "title": "3 - 3",
"number": 14,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/3",
"scanlator": "",
"uploadDate": 1465851600000,
@@ -160,4 +176,4 @@
}
],
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/assets/manga/header.json b/app/src/androidTest/assets/manga/header.json
index dc56dbf8e..061d634bf 100644
--- a/app/src/androidTest/assets/manga/header.json
+++ b/app/src/androidTest/assets/manga/header.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,7 +30,8 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": null,
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/assets/manga/without_middle_chapter.json b/app/src/androidTest/assets/manga/without_middle_chapter.json
index 97d797b53..1e7c5d90f 100644
--- a/app/src/androidTest/assets/manga/without_middle_chapter.json
+++ b/app/src/androidTest/assets/manga/without_middle_chapter.json
@@ -1,6 +1,7 @@
{
"id": -2096681732556647985,
"title": "Странствия Эманон",
+ "altTitles": [],
"url": "/stranstviia_emanon",
"publicUrl": "https://readmanga.io/stranstviia_emanon",
"rating": 0.9400894,
@@ -29,13 +30,15 @@
}
],
"state": "FINISHED",
+ "authors": [],
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
"description": "Продолжение истории о загадочной девушке по имени Эманон, которая помнит всё, что происходило на Земле за последние три миллиарда лет. \n
Начало истории читайте в \"Воспоминаниях Эманон\". \n",
"chapters": [
{
"id": 3552943969433540704,
- "name": "1 - 1",
+ "title": "1 - 1",
"number": 1,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/1",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -43,8 +46,9 @@
},
{
"id": 3552943969433540705,
- "name": "1 - 2",
+ "title": "1 - 2",
"number": 2,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/2",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -52,8 +56,9 @@
},
{
"id": 3552943969433540706,
- "name": "1 - 3",
+ "title": "1 - 3",
"number": 3,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/3",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -61,8 +66,9 @@
},
{
"id": 3552943969433540707,
- "name": "1 - 4",
+ "title": "1 - 4",
"number": 4,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/4",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -70,8 +76,9 @@
},
{
"id": 3552943969433540708,
- "name": "1 - 5",
+ "title": "1 - 5",
"number": 5,
+ "volume": 0,
"url": "/stranstviia_emanon/vol1/5",
"scanlator": "Sad-Robot",
"uploadDate": 1342731600000,
@@ -79,8 +86,9 @@
},
{
"id": 3552943969433541666,
- "name": "2 - 2",
+ "title": "2 - 2",
"number": 7,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/2",
"scanlator": "Sup!",
"uploadDate": 1419976800000,
@@ -88,8 +96,9 @@
},
{
"id": 3552943969433541667,
- "name": "2 - 3",
+ "title": "2 - 3",
"number": 8,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/3",
"scanlator": "Sup!",
"uploadDate": 1427922000000,
@@ -97,8 +106,9 @@
},
{
"id": 3552943969433541668,
- "name": "2 - 4",
+ "title": "2 - 4",
"number": 9,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/4",
"scanlator": "Sup!",
"uploadDate": 1436907600000,
@@ -106,8 +116,9 @@
},
{
"id": 3552943969433541669,
- "name": "2 - 5",
+ "title": "2 - 5",
"number": 10,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/5",
"scanlator": "Sup!",
"uploadDate": 1446674400000,
@@ -115,8 +126,9 @@
},
{
"id": 3552943969433541670,
- "name": "2 - 6",
+ "title": "2 - 6",
"number": 11,
+ "volume": 0,
"url": "/stranstviia_emanon/vol2/6",
"scanlator": "Sup!",
"uploadDate": 1451512800000,
@@ -124,8 +136,9 @@
},
{
"id": 3552943969433542626,
- "name": "3 - 1",
+ "title": "3 - 1",
"number": 12,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/1",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -133,8 +146,9 @@
},
{
"id": 3552943969433542627,
- "name": "3 - 2",
+ "title": "3 - 2",
"number": 13,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/2",
"scanlator": "Sup!",
"uploadDate": 1461618000000,
@@ -142,8 +156,9 @@
},
{
"id": 3552943969433542628,
- "name": "3 - 3",
+ "title": "3 - 3",
"number": 14,
+ "volume": 0,
"url": "/stranstviia_emanon/vol3/3",
"scanlator": "",
"uploadDate": 1465851600000,
@@ -151,4 +166,4 @@
}
],
"source": "READMANGA_RU"
-}
\ No newline at end of file
+}
diff --git a/app/src/androidTest/kotlin/org/koitharu/kotatsu/SampleData.kt b/app/src/androidTest/kotlin/org/koitharu/kotatsu/SampleData.kt
index b7d4ad7e3..11e1a48f7 100644
--- a/app/src/androidTest/kotlin/org/koitharu/kotatsu/SampleData.kt
+++ b/app/src/androidTest/kotlin/org/koitharu/kotatsu/SampleData.kt
@@ -1,19 +1,29 @@
package org.koitharu.kotatsu
import androidx.test.platform.app.InstrumentationRegistry
-import com.squareup.moshi.*
+import com.squareup.moshi.FromJson
+import com.squareup.moshi.JsonAdapter
+import com.squareup.moshi.JsonReader
+import com.squareup.moshi.JsonWriter
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.ToJson
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import okio.buffer
import okio.source
import org.koitharu.kotatsu.core.model.FavouriteCategory
+import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.parsers.model.Manga
-import java.util.*
+import org.koitharu.kotatsu.parsers.model.MangaSource
+import java.time.Instant
+import java.util.Date
import kotlin.reflect.KClass
object SampleData {
private val moshi = Moshi.Builder()
.add(DateAdapter())
+ .add(InstantAdapter())
+ .add(MangaSourceAdapter())
.add(KotlinJsonAdapterFactory())
.build()
@@ -51,4 +61,36 @@ object SampleData {
writer.value(value?.time ?: 0L)
}
}
-}
\ No newline at end of file
+
+ private class MangaSourceAdapter : JsonAdapter() {
+
+ @FromJson
+ override fun fromJson(reader: JsonReader): MangaSource? {
+ val name = reader.nextString() ?: return null
+ return MangaSource(name)
+ }
+
+ @ToJson
+ override fun toJson(writer: JsonWriter, value: MangaSource?) {
+ writer.value(value?.name)
+ }
+ }
+
+ private class InstantAdapter : JsonAdapter() {
+
+ @FromJson
+ override fun fromJson(reader: JsonReader): Instant? {
+ val ms = reader.nextLong()
+ return if (ms == 0L) {
+ null
+ } else {
+ Instant.ofEpochMilli(ms)
+ }
+ }
+
+ @ToJson
+ override fun toJson(writer: JsonWriter, value: Instant?) {
+ writer.value(value?.toEpochMilli() ?: 0L)
+ }
+ }
+}
diff --git a/app/src/androidTest/kotlin/org/koitharu/kotatsu/settings/backup/AppBackupAgentTest.kt b/app/src/androidTest/kotlin/org/koitharu/kotatsu/settings/backup/AppBackupAgentTest.kt
index f01cc9521..22912dcd7 100644
--- a/app/src/androidTest/kotlin/org/koitharu/kotatsu/settings/backup/AppBackupAgentTest.kt
+++ b/app/src/androidTest/kotlin/org/koitharu/kotatsu/settings/backup/AppBackupAgentTest.kt
@@ -15,7 +15,8 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.koitharu.kotatsu.SampleData
-import org.koitharu.kotatsu.core.backup.BackupRepository
+import org.koitharu.kotatsu.backups.data.BackupRepository
+import org.koitharu.kotatsu.backups.domain.AppBackupAgent
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.db.entity.toMangaTags
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b936a49d0..1410f3e96 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -48,7 +48,7 @@
+ android:label="@string/creating_backup" />
+
?
+ ) {
+ progress?.emit(Progress.INDETERMINATE)
+ var commonProgress = Progress(0, BackupSection.entries.size)
+ for (section in BackupSection.entries) {
+ when (section) {
+ BackupSection.INDEX -> output.writeJsonArray(
+ section = BackupSection.INDEX,
+ data = flowOf(BackupIndex()),
+ serializer = serializer(),
+ )
+
+ BackupSection.HISTORY -> output.writeJsonArray(
+ section = BackupSection.HISTORY,
+ data = database.getHistoryDao().dump().map { HistoryBackup(it) },
+ serializer = serializer(),
+ )
+
+ BackupSection.CATEGORIES -> output.writeJsonArray(
+ section = BackupSection.CATEGORIES,
+ data = database.getFavouriteCategoriesDao().findAll().asFlow().map { CategoryBackup(it) },
+ serializer = serializer(),
+ )
+
+ BackupSection.FAVOURITES -> output.writeJsonArray(
+ section = BackupSection.FAVOURITES,
+ data = database.getFavouritesDao().dump().map { FavouriteBackup(it) },
+ serializer = serializer(),
+ )
+
+ BackupSection.SETTINGS -> output.writeString(
+ section = BackupSection.SETTINGS,
+ data = dumpSettings(),
+ )
+
+ BackupSection.SETTINGS_READER_GRID -> output.writeString(
+ section = BackupSection.SETTINGS_READER_GRID,
+ data = dumpReaderGridSettings(),
+ )
+
+ BackupSection.BOOKMARKS -> output.writeJsonArray(
+ section = BackupSection.BOOKMARKS,
+ data = database.getBookmarksDao().dump().map { BookmarkBackup(it.first, it.second) },
+ serializer = serializer(),
+ )
+
+ BackupSection.SOURCES -> output.writeJsonArray(
+ section = BackupSection.SOURCES,
+ data = database.getSourcesDao().dumpEnabled().map { SourceBackup(it) },
+ serializer = serializer(),
+ )
+ }
+ progress?.emit(commonProgress)
+ commonProgress++
+ }
+ progress?.emit(commonProgress)
+ }
+
+ suspend fun restoreBackup(
+ input: ZipInputStream,
+ sections: Set,
+ progress: FlowCollector