From 7220a0c6b06b915270d6ac1f7b52a3f662259797 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 6 Sep 2019 21:08:41 -0400 Subject: [PATCH 001/162] Database rework --- .../subFragments/backup/async/schema.json | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json new file mode 100644 index 0000000000..56edb0b9a5 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json @@ -0,0 +1,56 @@ +{ + "ignoreThis": "This is an example of schema for the backup, use it for reference. Strings should be serialized before being put into json, and each sub JSON should be serialized aswell", + "ignoreThis2": "the type of data is specified in KEY, remove them and the spaces for a proper key for actual JSON files", + "settings": { + "reader_text_color": "Settings.ReaderTextColor", + "reader_text_background_color": "Settings.ReaderTextBackgroundColor", + "shoDir": "Utilities.shoDir : Serialize this", + "paused": "Settings.downloadPaused", + "textSize": "Settings.ReaderTextSize", + "themeMode ": "Settings.themeMode", + "paraSpace": "Settings.paragraphSpacing", + "indent": "Settings.indentSize", + "tap_to_scroll ": " Utilities.isTapToScroll()" + }, + "novels": [ + { + "novelURL": "serialize", + "FORMATTER_ID": "", + "STATUS": "ignore", + "bookmarked": "", + "novelPage": { + "ignoreThis5": "TODO make method in base objects to convert themselves to json", + "title": "serialize", + "imageURL": "serialize", + "description": "serialize", + "genres": "serialize", + "authors": "serialize", + "status": "convert stati to an int and use a switch to set them", + "tags": [ + "Array of serialized strings" + ], + "artists": [ + "Array of serialized strings" + ], + "language": "serialize", + "maxChapterPage": "", + "novelChapters": "ignore this completely, it is not needed for most operations. This is just here to tell you to ignore this" + } + } + ], + "chapters": [ + { + "novelURL": "serialize", + "chapterURL": "serialize", + "SAVED_DATA": { + "": "This is some form of object, to decrypt on a later date" + }, + "Y": "", + "READ_CHAPTER": "", + "BOOKMARKED": "", + "IS_SAVED": "", + "SAVE_PATH": "serialize" + } + ], + "ignoreThis3": "No longer transferring download data" +} \ No newline at end of file From b3a3e6f3951209824dd1161b63a276da61e081e8 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 7 Sep 2019 11:32:04 -0400 Subject: [PATCH 002/162] Fixes #47 --- app/src/main/res/layout/recycler_novel_card.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/recycler_novel_card.xml b/app/src/main/res/layout/recycler_novel_card.xml index ded8169e01..006862b675 100644 --- a/app/src/main/res/layout/recycler_novel_card.xml +++ b/app/src/main/res/layout/recycler_novel_card.xml @@ -40,7 +40,9 @@ android:id="@+id/novel_item_left_to_read" android:layout_width="wrap_content" android:layout_height="40dp" - android:layout_marginEnd="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:textAlignment="center" android:visibility="gone" app:layout_constraintDimensionRatio="1:1" app:layout_constraintEnd_toEndOf="parent" From 8efed87d1806ac9a1f9a43cdcf0c139c0887c453 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 7 Sep 2019 14:43:58 -0400 Subject: [PATCH 003/162] Fixed stati convert issue --- .../shosetsu/backend/database/Database.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 2c5a75ef18..9167be4f3f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -166,20 +166,23 @@ public static Object deserialize(String string) throws IOException, ClassNotFoun newC.release = C.release; newPage.novelChapters.add(newC); } - switch (oldPage.status) { - case PUBLISHING: - newPage.status = Stati.PUBLISHING; - break; - case COMPLETED: - newPage.status = Stati.COMPLETED; - break; - case PAUSED: - newPage.status = Stati.PAUSED; - break; - case UNKNOWN: - newPage.status = Stati.UNKNOWN; - break; - } + if (oldPage.status != null) + switch (oldPage.status) { + case PUBLISHING: + newPage.status = Stati.PUBLISHING; + break; + case COMPLETED: + newPage.status = Stati.COMPLETED; + break; + case PAUSED: + newPage.status = Stati.PAUSED; + break; + case UNKNOWN: + newPage.status = Stati.UNKNOWN; + break; + } + else newPage.status = Stati.UNKNOWN; + newPage.tags = oldPage.tags; newPage.title = oldPage.title; return newPage; From 9527ade9a3514581905d23a18ff032b73bb7f1bc Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Sep 2019 15:15:22 -0400 Subject: [PATCH 004/162] Moved serializer into rework --- .../apps/shosetsu/backend/Serialize.java | 258 ++++++++++++++++++ .../apps/shosetsu/ExampleUnitTest.java | 35 +-- 2 files changed, 269 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java new file mode 100644 index 0000000000..2745e05725 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -0,0 +1,258 @@ +package com.github.doomsdayrs.apps.shosetsu.backend; + +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; + +/* + * This file is part of shosetsu-services. + * shosetsu-services is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * shosetsu-services is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with shosetsu-services. If not, see . + * ==================================================================== + * shosetsu-services + * 07 / 09 / 2019 + * + * @author github.com/doomsdayrs + */ +public class Serialize { + private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; + private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; + private static boolean debug = false; + + public static void toggleDebug() { + debug = !debug; + } + + /** + * Turns an object into a JSON counterpart, then serializes it along with data in it + * + * @param object NovelPage or NovelChapter + * @return Serialized JSON + */ + public static String serializeOBJECT(Object object) throws Exception { + if (object.getClass().equals(NovelChapter.class)) { + NovelChapter novelChapter = (NovelChapter) object; + return serialize(novelChapterToJSON(novelChapter).toString()); + } else if (object.getClass().equals(NovelPage.class)) { + NovelPage novelPage = (NovelPage) object; + JSONObject jsonObject = new JSONObject(); + + if (novelPage.title != null) + jsonObject.put("title", serialize(novelPage.title)); + else jsonObject.put("title", "null"); + + if (novelPage.imageURL != null) + jsonObject.put("imageURL", serialize(novelPage.imageURL)); + else jsonObject.put("imageURL", "null"); + + if (novelPage.description != null) + jsonObject.put("description", serialize(novelPage.description)); + else jsonObject.put("description", "null"); + + if (novelPage.genres != null) { + JSONArray jsonArray = new JSONArray(); + for (String genre : novelPage.genres) + jsonArray.put(serialize(genre)); + jsonObject.put("genres", jsonArray); + } else jsonObject.put("genres", new JSONArray()); + + if (novelPage.authors != null) { + JSONArray jsonArray = new JSONArray(); + for (String author : novelPage.authors) + jsonArray.put(serialize(author)); + jsonObject.put("authors", jsonArray); + } else jsonObject.put("authors", new JSONArray()); + + if (novelPage.status != null) { + jsonObject.put("status", novelPage.status.toString()); + } else jsonObject.put("status", "Unknown"); + + if (novelPage.tags != null) { + JSONArray jsonArray = new JSONArray(); + for (String tag : novelPage.tags) + jsonArray.put(serialize(tag)); + jsonObject.put("tags", jsonArray); + } else jsonObject.put("tags", new JSONArray()); + + if (novelPage.artists != null) { + JSONArray jsonArray = new JSONArray(); + for (String artist : novelPage.artists) + jsonArray.put(serialize(artist)); + jsonObject.put("artists", jsonArray); + } else jsonObject.put("artists", new JSONArray()); + + if (novelPage.language != null) { + jsonObject.put("language", serialize(novelPage.language)); + } else jsonObject.put("language", "null"); + + jsonObject.put("maxChapterPage", novelPage.maxChapterPage); + + if (novelPage.novelChapters != null) { + JSONArray jsonArray = new JSONArray(); + for (NovelChapter novelChapter : novelPage.novelChapters) + jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); + jsonObject.put("novelChapters", jsonArray); + } else jsonObject.put("novelChapters", new JSONArray()); + + if (debug) + System.out.println("JSON to be serialized: " + jsonObject.toString()); + + return serialize(jsonObject.toString()); + } else throw new Exception("Illegal class"); + } + + public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { + NovelPage novelPage = new NovelPage(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + if (debug) + System.out.println("Deserialize-d json: " + jsonObject); + for (String key : NOVELPAGEKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + switch (key) { + case "maxChapterPage": + novelPage.maxChapterPage = jsonObject.getInt(key); + break; + + case "status": + switch (jsonObject.getString(key)) { + case "Publishing": + novelPage.status = Stati.PUBLISHING; + break; + case "Completed": + novelPage.status = Stati.COMPLETED; + break; + case "Paused": + novelPage.status = Stati.PAUSED; + break; + case "Unknown": + novelPage.status = Stati.UNKNOWN; + break; + } + break; + + case "genres": + case "authors": + case "tags": + case "artists": + JSONArray array = jsonObject.getJSONArray(key); + String[] strings = new String[array.length()]; + for (int x = 0; x < array.length(); x++) { + String s = array.getString(x); + strings[x] = (String) deserialize(s); + } + switch (key) { + case "genres": + novelPage.genres = strings; + break; + case "authors": + novelPage.authors = strings; + break; + case "tags": + novelPage.tags = strings; + break; + case "artists": + novelPage.artists = strings; + break; + } + break; + case "novelChapters": + JSONArray jsonArray = jsonObject.getJSONArray(key); + ArrayList novelChapters = new ArrayList<>(); + for (int x = 0; x < jsonArray.length(); x++) { + novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); + } + novelPage.novelChapters = novelChapters; + break; + default: + String response = jsonObject.getString(key); + if (!response.equals("null")) { + if (debug) + System.out.println("Serial response of novelChapter key [" + key + "]: " + response); + response = (String) deserialize(response); + } + switch (key) { + case "title": + if (response.equals("null")) + novelPage.title = null; + else novelPage.title = response; + break; + case "imageURL": + if (response.equals("null")) + novelPage.imageURL = null; + else novelPage.imageURL = response; + break; + case "description": + if (response.equals("null")) + novelPage.description = null; + else novelPage.description = response; + break; + case "language": + if (response.equals("null")) + novelPage.language = null; + else novelPage.language = response; + break; + } + break; + } + } + return novelPage; + } + + public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { + NovelChapter novelChapter = new NovelChapter(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + for (String key : NOVELCHAPTERKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + String response = (String) deserialize(jsonObject.getString(key)); + switch (key) { + case "release": + if (response.equals("null")) + novelChapter.release = null; + else novelChapter.release = response; + break; + case "chapterNum": + if (response.equals("null")) + novelChapter.chapterNum = null; + else novelChapter.chapterNum = response; + break; + case "link": + if (response.equals("null")) + novelChapter.link = null; + else novelChapter.link = response; + break; + } + } + return novelChapter; + } + + private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("release", serialize(novelChapter.release)); + jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); + jsonObject.put("link", serialize(novelChapter.link)); + return jsonObject; + } + +} diff --git a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java index f497d184a8..0100c59f6f 100644 --- a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java +++ b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java @@ -1,8 +1,11 @@ package com.github.doomsdayrs.apps.shosetsu; -import org.joda.time.DateTime; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; + import org.junit.Test; +import java.io.IOException; + /** * Example local unit test, which will execute on the development machine (host). * @@ -10,30 +13,14 @@ */ public class ExampleUnitTest { - - public static void format(DateTime dateTime) { - long time = dateTime.getMillis(); - - time -= dateTime.getHourOfDay(); - time -= dateTime.getMinuteOfHour(); - time -= dateTime.getSecondOfMinute(); - time -= dateTime.getMillisOfSecond(); - - System.out.println("Formatted TIME " + time); - System.out.println("Formatted DATETIME " + new DateTime(time)); - - } - @Test - public void date() { - long time = System.currentTimeMillis(); - System.out.println("Raw TIME " + time); + public void format() { + try { + System.out.println((String) Database.deserialize("U3RyaW5n")); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } - DateTime dateTime = new DateTime(time); - System.out.println("Raw DateTime " + dateTime); - int divided = (int) (time / 86400); - System.out.println("Days since the beginning of TIME: " + divided); - format(dateTime); - } } \ No newline at end of file From 9acb0aa0671d4fcc98dadea67b9fce83fe6aa20b Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Sep 2019 15:22:20 -0400 Subject: [PATCH 005/162] Moved serializer into rework --- .../shosetsu/backend/database/Serialize.java | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java new file mode 100644 index 0000000000..967a713ee8 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java @@ -0,0 +1,258 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database; + +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; + +/* + * This file is part of shosetsu-services. + * shosetsu-services is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * shosetsu-services is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with shosetsu-services. If not, see . + * ==================================================================== + * shosetsu-services + * 07 / 09 / 2019 + * + * @author github.com/doomsdayrs + */ +public class Serialize { + private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; + private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; + private static boolean debug = false; + + public static void toggleDebug() { + debug = !debug; + } + + /** + * Turns an object into a JSON counterpart, then serializes it along with data in it + * + * @param object NovelPage or NovelChapter + * @return Serialized JSON + */ + public static String serializeOBJECT(Object object) throws Exception { + if (object.getClass().equals(NovelChapter.class)) { + NovelChapter novelChapter = (NovelChapter) object; + return serialize(novelChapterToJSON(novelChapter).toString()); + } else if (object.getClass().equals(NovelPage.class)) { + NovelPage novelPage = (NovelPage) object; + JSONObject jsonObject = new JSONObject(); + + if (novelPage.title != null) + jsonObject.put("title", serialize(novelPage.title)); + else jsonObject.put("title", "null"); + + if (novelPage.imageURL != null) + jsonObject.put("imageURL", serialize(novelPage.imageURL)); + else jsonObject.put("imageURL", "null"); + + if (novelPage.description != null) + jsonObject.put("description", serialize(novelPage.description)); + else jsonObject.put("description", "null"); + + if (novelPage.genres != null) { + JSONArray jsonArray = new JSONArray(); + for (String genre : novelPage.genres) + jsonArray.put(serialize(genre)); + jsonObject.put("genres", jsonArray); + } else jsonObject.put("genres", new JSONArray()); + + if (novelPage.authors != null) { + JSONArray jsonArray = new JSONArray(); + for (String author : novelPage.authors) + jsonArray.put(serialize(author)); + jsonObject.put("authors", jsonArray); + } else jsonObject.put("authors", new JSONArray()); + + if (novelPage.status != null) { + jsonObject.put("status", novelPage.status.toString()); + } else jsonObject.put("status", "Unknown"); + + if (novelPage.tags != null) { + JSONArray jsonArray = new JSONArray(); + for (String tag : novelPage.tags) + jsonArray.put(serialize(tag)); + jsonObject.put("tags", jsonArray); + } else jsonObject.put("tags", new JSONArray()); + + if (novelPage.artists != null) { + JSONArray jsonArray = new JSONArray(); + for (String artist : novelPage.artists) + jsonArray.put(serialize(artist)); + jsonObject.put("artists", jsonArray); + } else jsonObject.put("artists", new JSONArray()); + + if (novelPage.language != null) { + jsonObject.put("language", serialize(novelPage.language)); + } else jsonObject.put("language", "null"); + + jsonObject.put("maxChapterPage", novelPage.maxChapterPage); + + if (novelPage.novelChapters != null) { + JSONArray jsonArray = new JSONArray(); + for (NovelChapter novelChapter : novelPage.novelChapters) + jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); + jsonObject.put("novelChapters", jsonArray); + } else jsonObject.put("novelChapters", new JSONArray()); + + if (debug) + System.out.println("JSON to be serialized: " + jsonObject.toString()); + + return serialize(jsonObject.toString()); + } else throw new Exception("Illegal class"); + } + + public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { + NovelPage novelPage = new NovelPage(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + if (debug) + System.out.println("Deserialize-d json: " + jsonObject); + for (String key : NOVELPAGEKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + switch (key) { + case "maxChapterPage": + novelPage.maxChapterPage = jsonObject.getInt(key); + break; + + case "status": + switch (jsonObject.getString(key)) { + case "Publishing": + novelPage.status = Stati.PUBLISHING; + break; + case "Completed": + novelPage.status = Stati.COMPLETED; + break; + case "Paused": + novelPage.status = Stati.PAUSED; + break; + case "Unknown": + novelPage.status = Stati.UNKNOWN; + break; + } + break; + + case "genres": + case "authors": + case "tags": + case "artists": + JSONArray array = jsonObject.getJSONArray(key); + String[] strings = new String[array.length()]; + for (int x = 0; x < array.length(); x++) { + String s = array.getString(x); + strings[x] = (String) deserialize(s); + } + switch (key) { + case "genres": + novelPage.genres = strings; + break; + case "authors": + novelPage.authors = strings; + break; + case "tags": + novelPage.tags = strings; + break; + case "artists": + novelPage.artists = strings; + break; + } + break; + case "novelChapters": + JSONArray jsonArray = jsonObject.getJSONArray(key); + ArrayList novelChapters = new ArrayList<>(); + for (int x = 0; x < jsonArray.length(); x++) { + novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); + } + novelPage.novelChapters = novelChapters; + break; + default: + String response = jsonObject.getString(key); + if (!response.equals("null")) { + if (debug) + System.out.println("Serial response of novelChapter key [" + key + "]: " + response); + response = (String) deserialize(response); + } + switch (key) { + case "title": + if (response.equals("null")) + novelPage.title = null; + else novelPage.title = response; + break; + case "imageURL": + if (response.equals("null")) + novelPage.imageURL = null; + else novelPage.imageURL = response; + break; + case "description": + if (response.equals("null")) + novelPage.description = null; + else novelPage.description = response; + break; + case "language": + if (response.equals("null")) + novelPage.language = null; + else novelPage.language = response; + break; + } + break; + } + } + return novelPage; + } + + public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { + NovelChapter novelChapter = new NovelChapter(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + for (String key : NOVELCHAPTERKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + String response = (String) deserialize(jsonObject.getString(key)); + switch (key) { + case "release": + if (response.equals("null")) + novelChapter.release = null; + else novelChapter.release = response; + break; + case "chapterNum": + if (response.equals("null")) + novelChapter.chapterNum = null; + else novelChapter.chapterNum = response; + break; + case "link": + if (response.equals("null")) + novelChapter.link = null; + else novelChapter.link = response; + break; + } + } + return novelChapter; + } + + private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("release", serialize(novelChapter.release)); + jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); + jsonObject.put("link", serialize(novelChapter.link)); + return jsonObject; + } + +} From d3102d2c3a9cd443898376947e11dc5b4f897be3 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Sep 2019 16:27:12 -0400 Subject: [PATCH 006/162] Broken commit, backloggging to retrieve test data --- app/build.gradle | 2 +- .../apps/shosetsu/backend/Serialize.java | 258 ------------------ .../apps/shosetsu/backend/Utilities.java | 232 ++++++++++++++++ .../shosetsu/backend/database/DBHelper.java | 95 ++++++- .../shosetsu/backend/database/Database.java | 61 +++-- .../shosetsu/backend/database/Serialize.java | 258 ------------------ .../shosetsu/ui/novel/async/NovelLoader.java | 2 +- .../apps/shosetsu/ExampleUnitTest.java | 14 - 8 files changed, 366 insertions(+), 556 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java diff --git a/app/build.gradle b/app/build.gradle index 7e86748254..b20aa8ccca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -58,7 +58,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' - implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.1' + implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.2' implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.1' implementation 'com.github.Doomsdayrs:novelreader-services:1.1.4' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java deleted file mode 100644 index 2745e05725..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ /dev/null @@ -1,258 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend; - -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.util.ArrayList; - -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; - -/* - * This file is part of shosetsu-services. - * shosetsu-services is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * shosetsu-services is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with shosetsu-services. If not, see . - * ==================================================================== - * shosetsu-services - * 07 / 09 / 2019 - * - * @author github.com/doomsdayrs - */ -public class Serialize { - private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; - private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; - private static boolean debug = false; - - public static void toggleDebug() { - debug = !debug; - } - - /** - * Turns an object into a JSON counterpart, then serializes it along with data in it - * - * @param object NovelPage or NovelChapter - * @return Serialized JSON - */ - public static String serializeOBJECT(Object object) throws Exception { - if (object.getClass().equals(NovelChapter.class)) { - NovelChapter novelChapter = (NovelChapter) object; - return serialize(novelChapterToJSON(novelChapter).toString()); - } else if (object.getClass().equals(NovelPage.class)) { - NovelPage novelPage = (NovelPage) object; - JSONObject jsonObject = new JSONObject(); - - if (novelPage.title != null) - jsonObject.put("title", serialize(novelPage.title)); - else jsonObject.put("title", "null"); - - if (novelPage.imageURL != null) - jsonObject.put("imageURL", serialize(novelPage.imageURL)); - else jsonObject.put("imageURL", "null"); - - if (novelPage.description != null) - jsonObject.put("description", serialize(novelPage.description)); - else jsonObject.put("description", "null"); - - if (novelPage.genres != null) { - JSONArray jsonArray = new JSONArray(); - for (String genre : novelPage.genres) - jsonArray.put(serialize(genre)); - jsonObject.put("genres", jsonArray); - } else jsonObject.put("genres", new JSONArray()); - - if (novelPage.authors != null) { - JSONArray jsonArray = new JSONArray(); - for (String author : novelPage.authors) - jsonArray.put(serialize(author)); - jsonObject.put("authors", jsonArray); - } else jsonObject.put("authors", new JSONArray()); - - if (novelPage.status != null) { - jsonObject.put("status", novelPage.status.toString()); - } else jsonObject.put("status", "Unknown"); - - if (novelPage.tags != null) { - JSONArray jsonArray = new JSONArray(); - for (String tag : novelPage.tags) - jsonArray.put(serialize(tag)); - jsonObject.put("tags", jsonArray); - } else jsonObject.put("tags", new JSONArray()); - - if (novelPage.artists != null) { - JSONArray jsonArray = new JSONArray(); - for (String artist : novelPage.artists) - jsonArray.put(serialize(artist)); - jsonObject.put("artists", jsonArray); - } else jsonObject.put("artists", new JSONArray()); - - if (novelPage.language != null) { - jsonObject.put("language", serialize(novelPage.language)); - } else jsonObject.put("language", "null"); - - jsonObject.put("maxChapterPage", novelPage.maxChapterPage); - - if (novelPage.novelChapters != null) { - JSONArray jsonArray = new JSONArray(); - for (NovelChapter novelChapter : novelPage.novelChapters) - jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); - jsonObject.put("novelChapters", jsonArray); - } else jsonObject.put("novelChapters", new JSONArray()); - - if (debug) - System.out.println("JSON to be serialized: " + jsonObject.toString()); - - return serialize(jsonObject.toString()); - } else throw new Exception("Illegal class"); - } - - public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { - NovelPage novelPage = new NovelPage(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); - if (debug) - System.out.println("Deserialize-d json: " + jsonObject); - for (String key : NOVELPAGEKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - switch (key) { - case "maxChapterPage": - novelPage.maxChapterPage = jsonObject.getInt(key); - break; - - case "status": - switch (jsonObject.getString(key)) { - case "Publishing": - novelPage.status = Stati.PUBLISHING; - break; - case "Completed": - novelPage.status = Stati.COMPLETED; - break; - case "Paused": - novelPage.status = Stati.PAUSED; - break; - case "Unknown": - novelPage.status = Stati.UNKNOWN; - break; - } - break; - - case "genres": - case "authors": - case "tags": - case "artists": - JSONArray array = jsonObject.getJSONArray(key); - String[] strings = new String[array.length()]; - for (int x = 0; x < array.length(); x++) { - String s = array.getString(x); - strings[x] = (String) deserialize(s); - } - switch (key) { - case "genres": - novelPage.genres = strings; - break; - case "authors": - novelPage.authors = strings; - break; - case "tags": - novelPage.tags = strings; - break; - case "artists": - novelPage.artists = strings; - break; - } - break; - case "novelChapters": - JSONArray jsonArray = jsonObject.getJSONArray(key); - ArrayList novelChapters = new ArrayList<>(); - for (int x = 0; x < jsonArray.length(); x++) { - novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); - } - novelPage.novelChapters = novelChapters; - break; - default: - String response = jsonObject.getString(key); - if (!response.equals("null")) { - if (debug) - System.out.println("Serial response of novelChapter key [" + key + "]: " + response); - response = (String) deserialize(response); - } - switch (key) { - case "title": - if (response.equals("null")) - novelPage.title = null; - else novelPage.title = response; - break; - case "imageURL": - if (response.equals("null")) - novelPage.imageURL = null; - else novelPage.imageURL = response; - break; - case "description": - if (response.equals("null")) - novelPage.description = null; - else novelPage.description = response; - break; - case "language": - if (response.equals("null")) - novelPage.language = null; - else novelPage.language = response; - break; - } - break; - } - } - return novelPage; - } - - public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { - NovelChapter novelChapter = new NovelChapter(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); - for (String key : NOVELCHAPTERKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - String response = (String) deserialize(jsonObject.getString(key)); - switch (key) { - case "release": - if (response.equals("null")) - novelChapter.release = null; - else novelChapter.release = response; - break; - case "chapterNum": - if (response.equals("null")) - novelChapter.chapterNum = null; - else novelChapter.chapterNum = response; - break; - case "link": - if (response.equals("null")) - novelChapter.link = null; - else novelChapter.link = response; - break; - } - } - return novelChapter; - } - - private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("release", serialize(novelChapter.release)); - jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); - jsonObject.put("link", serialize(novelChapter.link)); - return jsonObject; - } - -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index bab6fe4fe6..f64fee1fe9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -12,6 +12,8 @@ import android.util.Log; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; @@ -21,9 +23,17 @@ import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import java.io.IOException; +import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; + /* * This file is part of Shosetsu. * @@ -283,4 +293,226 @@ public static boolean isTrackingEnabled() { public static void addTracker() { } + + private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; + private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; + private static boolean debug = false; + + public static void toggleDebug() { + debug = !debug; + } + + /** + * Turns an object into a JSON counterpart, then serializes it along with data in it + * + * @param object NovelPage or NovelChapter + * @return Serialized JSON + */ + public static String serializeOBJECT(Object object) throws Exception { + if (object.getClass().equals(NovelChapter.class)) { + NovelChapter novelChapter = (NovelChapter) object; + return serialize(novelChapterToJSON(novelChapter).toString()); + } else if (object.getClass().equals(NovelPage.class)) { + NovelPage novelPage = (NovelPage) object; + JSONObject jsonObject = new JSONObject(); + + if (novelPage.title != null) + jsonObject.put("title", serialize(novelPage.title)); + else jsonObject.put("title", "null"); + + if (novelPage.imageURL != null) + jsonObject.put("imageURL", serialize(novelPage.imageURL)); + else jsonObject.put("imageURL", "null"); + + if (novelPage.description != null) + jsonObject.put("description", serialize(novelPage.description)); + else jsonObject.put("description", "null"); + + if (novelPage.genres != null) { + JSONArray jsonArray = new JSONArray(); + for (String genre : novelPage.genres) + jsonArray.put(serialize(genre)); + jsonObject.put("genres", jsonArray); + } else jsonObject.put("genres", new JSONArray()); + + if (novelPage.authors != null) { + JSONArray jsonArray = new JSONArray(); + for (String author : novelPage.authors) + jsonArray.put(serialize(author)); + jsonObject.put("authors", jsonArray); + } else jsonObject.put("authors", new JSONArray()); + + if (novelPage.status != null) { + jsonObject.put("status", novelPage.status.toString()); + } else jsonObject.put("status", "Unknown"); + + if (novelPage.tags != null) { + JSONArray jsonArray = new JSONArray(); + for (String tag : novelPage.tags) + jsonArray.put(serialize(tag)); + jsonObject.put("tags", jsonArray); + } else jsonObject.put("tags", new JSONArray()); + + if (novelPage.artists != null) { + JSONArray jsonArray = new JSONArray(); + for (String artist : novelPage.artists) + jsonArray.put(serialize(artist)); + jsonObject.put("artists", jsonArray); + } else jsonObject.put("artists", new JSONArray()); + + if (novelPage.language != null) { + jsonObject.put("language", serialize(novelPage.language)); + } else jsonObject.put("language", "null"); + + jsonObject.put("maxChapterPage", novelPage.maxChapterPage); + + if (novelPage.novelChapters != null) { + JSONArray jsonArray = new JSONArray(); + for (NovelChapter novelChapter : novelPage.novelChapters) + jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); + jsonObject.put("novelChapters", jsonArray); + } else jsonObject.put("novelChapters", new JSONArray()); + + if (debug) + System.out.println("JSON to be serialized: " + jsonObject.toString()); + + return serialize(jsonObject.toString()); + } else throw new Exception("Illegal class"); + } + + public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { + NovelPage novelPage = new NovelPage(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + if (debug) + System.out.println("Deserialize-d json: " + jsonObject); + for (String key : NOVELPAGEKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + switch (key) { + case "maxChapterPage": + novelPage.maxChapterPage = jsonObject.getInt(key); + break; + + case "status": + switch (jsonObject.getString(key)) { + case "Publishing": + novelPage.status = Stati.PUBLISHING; + break; + case "Completed": + novelPage.status = Stati.COMPLETED; + break; + case "Paused": + novelPage.status = Stati.PAUSED; + break; + case "Unknown": + novelPage.status = Stati.UNKNOWN; + break; + } + break; + + case "genres": + case "authors": + case "tags": + case "artists": + JSONArray array = jsonObject.getJSONArray(key); + String[] strings = new String[array.length()]; + for (int x = 0; x < array.length(); x++) { + String s = array.getString(x); + strings[x] = (String) deserialize(s); + } + switch (key) { + case "genres": + novelPage.genres = strings; + break; + case "authors": + novelPage.authors = strings; + break; + case "tags": + novelPage.tags = strings; + break; + case "artists": + novelPage.artists = strings; + break; + } + break; + case "novelChapters": + JSONArray jsonArray = jsonObject.getJSONArray(key); + ArrayList novelChapters = new ArrayList<>(); + for (int x = 0; x < jsonArray.length(); x++) { + novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); + } + novelPage.novelChapters = novelChapters; + break; + default: + String response = jsonObject.getString(key); + if (!response.equals("null")) { + if (debug) + System.out.println("Serial response of novelChapter key [" + key + "]: " + response); + response = (String) deserialize(response); + } + switch (key) { + case "title": + if (response.equals("null")) + novelPage.title = null; + else novelPage.title = response; + break; + case "imageURL": + if (response.equals("null")) + novelPage.imageURL = null; + else novelPage.imageURL = response; + break; + case "description": + if (response.equals("null")) + novelPage.description = null; + else novelPage.description = response; + break; + case "language": + if (response.equals("null")) + novelPage.language = null; + else novelPage.language = response; + break; + } + break; + } + } + return novelPage; + } + + public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { + NovelChapter novelChapter = new NovelChapter(); + JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + for (String key : NOVELCHAPTERKEYS) { + if (!jsonObject.has(key)) + throw new Exception("JSON is invalid due to missing key[" + key + "]"); + + String response = (String) deserialize(jsonObject.getString(key)); + switch (key) { + case "release": + if (response.equals("null")) + novelChapter.release = null; + else novelChapter.release = response; + break; + case "chapterNum": + if (response.equals("null")) + novelChapter.chapterNum = null; + else novelChapter.chapterNum = response; + break; + case "link": + if (response.equals("null")) + novelChapter.link = null; + else novelChapter.link = response; + break; + } + } + return novelChapter; + } + + private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("release", serialize(novelChapter.release)); + jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); + jsonObject.put("link", serialize(novelChapter.link)); + return jsonObject; + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index ba7bcf5c42..f54ac83a5e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -5,9 +5,18 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; + /* * This file is part of Shosetsu. * @@ -93,7 +102,7 @@ public class DBHelper extends SQLiteOpenHelper { * @param context main context */ public DBHelper(Context context) { - super(context, DB_NAME, null, 7); + super(context, DB_NAME, null, 8); } @@ -110,6 +119,56 @@ public void onCreate(SQLiteDatabase db) { db.execSQL(UPDATES_CREATE); } + private static void updateNovelData(SQLiteDatabase sqLiteDatabase, @NotNull String novelURL, @NotNull NovelPage novelPage) throws Exception { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.NOVEL_PAGE + "='" + serializeOBJECT(novelPage) + "' where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + } + + private static void updateChapterData(SQLiteDatabase sqLiteDatabase, @NotNull String chapterURL, @NotNull NovelChapter novelChapter) throws Exception { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVED_DATA + "='" + serializeOBJECT(novelChapter) + "' where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + } + + private static ArrayList getPages(SQLiteDatabase sqLiteDatabase) { + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_PAGE + "," + Columns.NOVEL_URL + " from " + Tables.NOVELS, null); + if (cursor.getCount() <= 0) { + cursor.close(); + return null; + } else { + ArrayList novelPages = new ArrayList<>(); + try { + cursor.moveToNext(); + String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString())); + cursor.close(); + if (text != null) { + novelPages.add(new Holder(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), (NovelPage) deserialize(text))); + } + } catch (Exception e) { + e.printStackTrace(); + } + return novelPages; + } + } + + private static ArrayList getChapters(SQLiteDatabase sqLiteDatabase) { + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.SAVED_DATA + " from " + Tables.CHAPTERS, null); + if (cursor.getCount() <= 0) { + cursor.close(); + return null; + } else { + ArrayList novelChapters = new ArrayList<>(); + try { + cursor.moveToNext(); + String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); + cursor.close(); + if (text != null) { + novelChapters.add((NovelChapter) deserialize(text)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return novelChapters; + } + } + /** * Upgrades database * @@ -260,5 +319,39 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 7) { db.execSQL(UPDATES_CREATE); } + if (oldVersion < 8) { + // Updates chapters first, being most resource intensive + ArrayList holders = getPages(db); + if (holders != null) { + for (Holder holder : holders) { + try { + updateNovelData(db, holder.novelURL, holder.novelPage); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + ArrayList novelChapters = getChapters(db); + if (novelChapters != null) { + for (NovelChapter novelChapter : novelChapters) { + try { + updateChapterData(db, novelChapter.link, novelChapter); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + + private static class Holder { + final String novelURL; + final NovelPage novelPage; + + Holder(String novelURL, NovelPage novelPage) { + this.novelURL = novelURL; + this.novelPage = novelPage; + } } + } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 9167be4f3f..1450e24a56 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -30,6 +30,10 @@ import java.util.Calendar; import java.util.List; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelChapterJSON; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelPageJSON; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; + /* * This file is part of Shosetsu. * @@ -517,9 +521,9 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { "values ('" + novelURL + "','" + novelChapter.link + "','" + - serialize(novelChapter) + "'," + + serializeOBJECT(novelChapter) + "'," + 0 + "," + 0 + "," + 0 + "," + 0 + ")"); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -528,6 +532,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { * Adds chapter to database * * @param novelURL novelURL + * @param chapter serialized chapterData */ public static void addToChapters(String novelURL, String chapterURL, String chapter) { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + "(" + @@ -545,7 +550,6 @@ public static void addToChapters(String novelURL, String chapterURL, String chap 0 + "," + 0 + "," + 0 + "," + 0 + ")"); } - /** * Gets chapters of a novel * @@ -563,9 +567,9 @@ public static List getChapters(String novelURL) { try { String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); if (text != null) { - novelChapters.add((NovelChapter) deserialize(text)); + novelChapters.add(deserializeNovelChapterJSON(text)); } - } catch (IOException | ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -586,9 +590,9 @@ public static NovelChapter getChapter(String chapterURL) { String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); cursor.close(); if (text != null) { - novelChapters = ((NovelChapter) deserialize(text)); + novelChapters = deserializeNovelChapterJSON(text); } - } catch (IOException | ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } return novelChapters; @@ -609,10 +613,8 @@ public static String getChapterNovelURL(String chapterURL) { } } - public static class DatabaseLibrary { - /** * Bookmarks the novel * @@ -645,7 +647,6 @@ public static boolean isBookmarked(@NotNull String novelURL) { return a > 0; } - public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @NotNull String novelURL, int status) { try { sqLiteDatabase.execSQL("insert into " + Tables.NOVELS + "(" + @@ -653,14 +654,22 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No "0" + "," + "'" + novelURL + "'," + "'" + formatter + "','" + - serialize(novelPage) + "'," + + serializeOBJECT(novelPage) + "'," + status + ")" ); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } } + /** + * Method for restoring data + * + * @param formatter formatter ID + * @param novelPage serialized novelpage data + * @param novelURL novel url + * @param status status of novel + */ public static void addToLibrary(int formatter, @NotNull String novelPage, @NotNull String novelURL, int status) { sqLiteDatabase.execSQL("insert into " + Tables.NOVELS + "(" + Columns.BOOKMARKED + ",'" + Columns.NOVEL_URL + "'," + Columns.FORMATTER_ID + "," + Columns.NOVEL_PAGE + "," + Columns.STATUS + ") values(" + @@ -672,6 +681,12 @@ public static void addToLibrary(int formatter, @NotNull String novelPage, @NotNu ); } + /** + * TODO Create a cache cleaner + * + * @param novelURL url of novel to remove + * @return if successful + */ public static boolean removeFromLibrary(@NotNull String novelURL) { return sqLiteDatabase.delete(Tables.NOVELS.toString(), Columns.NOVEL_URL + "='" + novelURL + "'", null) > 0; } @@ -692,7 +707,6 @@ public static boolean inLibrary(@NotNull String novelURL) { return true; } - /** * Get's the entire library to be listed * @@ -711,14 +725,14 @@ public static ArrayList getLibrary() { } else { while (cursor.moveToNext()) { try { - NovelPage novelPage = (NovelPage) deserialize(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); + NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); novelCards.add(new NovelCard( novelPage.title, cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), novelPage.imageURL, cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())) )); - } catch (IOException | ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -739,7 +753,7 @@ public static NovelCard getNovel(String novelURL) { } else { cursor.moveToNext(); try { - NovelPage novelPage = (NovelPage) deserialize(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); + NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); NovelCard novelCard = new NovelCard( novelPage.title, cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), @@ -748,7 +762,7 @@ public static NovelCard getNovel(String novelURL) { ); cursor.close(); return novelCard; - } catch (IOException | ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -769,10 +783,10 @@ public static NovelPage getNovelPage(@NotNull String novelURL) { } else { cursor.moveToNext(); try { - NovelPage novelPage = (NovelPage) deserialize(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); + NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); cursor.close(); return novelPage; - } catch (IOException | ClassNotFoundException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -804,8 +818,8 @@ else if (y == 3) } } - public static void updateData(@NotNull String novelURL, @NotNull NovelPage novelPage) throws IOException { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.NOVEL_PAGE + "='" + serialize(novelPage) + "' where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + public static void updateData(@NotNull String novelURL, @NotNull NovelPage novelPage) throws Exception { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.NOVEL_PAGE + "='" + serializeOBJECT(novelPage) + "' where " + Columns.NOVEL_URL + "='" + novelURL + "'"); } public static void migrateNovel(@NotNull String oldURL, @NotNull String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { @@ -875,7 +889,8 @@ public static long getLatestDay() { } } - public static ArrayList getAll() { + /* + public static ArrayList getAll() { Log.d("DL", "Getting"); Cursor cursor = sqLiteDatabase.query(Tables.UPDATES.toString(), new String[]{Columns.NOVEL_URL.toString(), Columns.CHAPTER_URL.toString(), Columns.TIME.toString()}, null, null, null, null, null); @@ -896,7 +911,7 @@ public static ArrayList getAll() { return novelCards; } } - + */ /** * Gets count on day diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java deleted file mode 100644 index 967a713ee8..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Serialize.java +++ /dev/null @@ -1,258 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database; - -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.util.ArrayList; - -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; - -/* - * This file is part of shosetsu-services. - * shosetsu-services is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * shosetsu-services is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with shosetsu-services. If not, see . - * ==================================================================== - * shosetsu-services - * 07 / 09 / 2019 - * - * @author github.com/doomsdayrs - */ -public class Serialize { - private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; - private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; - private static boolean debug = false; - - public static void toggleDebug() { - debug = !debug; - } - - /** - * Turns an object into a JSON counterpart, then serializes it along with data in it - * - * @param object NovelPage or NovelChapter - * @return Serialized JSON - */ - public static String serializeOBJECT(Object object) throws Exception { - if (object.getClass().equals(NovelChapter.class)) { - NovelChapter novelChapter = (NovelChapter) object; - return serialize(novelChapterToJSON(novelChapter).toString()); - } else if (object.getClass().equals(NovelPage.class)) { - NovelPage novelPage = (NovelPage) object; - JSONObject jsonObject = new JSONObject(); - - if (novelPage.title != null) - jsonObject.put("title", serialize(novelPage.title)); - else jsonObject.put("title", "null"); - - if (novelPage.imageURL != null) - jsonObject.put("imageURL", serialize(novelPage.imageURL)); - else jsonObject.put("imageURL", "null"); - - if (novelPage.description != null) - jsonObject.put("description", serialize(novelPage.description)); - else jsonObject.put("description", "null"); - - if (novelPage.genres != null) { - JSONArray jsonArray = new JSONArray(); - for (String genre : novelPage.genres) - jsonArray.put(serialize(genre)); - jsonObject.put("genres", jsonArray); - } else jsonObject.put("genres", new JSONArray()); - - if (novelPage.authors != null) { - JSONArray jsonArray = new JSONArray(); - for (String author : novelPage.authors) - jsonArray.put(serialize(author)); - jsonObject.put("authors", jsonArray); - } else jsonObject.put("authors", new JSONArray()); - - if (novelPage.status != null) { - jsonObject.put("status", novelPage.status.toString()); - } else jsonObject.put("status", "Unknown"); - - if (novelPage.tags != null) { - JSONArray jsonArray = new JSONArray(); - for (String tag : novelPage.tags) - jsonArray.put(serialize(tag)); - jsonObject.put("tags", jsonArray); - } else jsonObject.put("tags", new JSONArray()); - - if (novelPage.artists != null) { - JSONArray jsonArray = new JSONArray(); - for (String artist : novelPage.artists) - jsonArray.put(serialize(artist)); - jsonObject.put("artists", jsonArray); - } else jsonObject.put("artists", new JSONArray()); - - if (novelPage.language != null) { - jsonObject.put("language", serialize(novelPage.language)); - } else jsonObject.put("language", "null"); - - jsonObject.put("maxChapterPage", novelPage.maxChapterPage); - - if (novelPage.novelChapters != null) { - JSONArray jsonArray = new JSONArray(); - for (NovelChapter novelChapter : novelPage.novelChapters) - jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); - jsonObject.put("novelChapters", jsonArray); - } else jsonObject.put("novelChapters", new JSONArray()); - - if (debug) - System.out.println("JSON to be serialized: " + jsonObject.toString()); - - return serialize(jsonObject.toString()); - } else throw new Exception("Illegal class"); - } - - public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { - NovelPage novelPage = new NovelPage(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); - if (debug) - System.out.println("Deserialize-d json: " + jsonObject); - for (String key : NOVELPAGEKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - switch (key) { - case "maxChapterPage": - novelPage.maxChapterPage = jsonObject.getInt(key); - break; - - case "status": - switch (jsonObject.getString(key)) { - case "Publishing": - novelPage.status = Stati.PUBLISHING; - break; - case "Completed": - novelPage.status = Stati.COMPLETED; - break; - case "Paused": - novelPage.status = Stati.PAUSED; - break; - case "Unknown": - novelPage.status = Stati.UNKNOWN; - break; - } - break; - - case "genres": - case "authors": - case "tags": - case "artists": - JSONArray array = jsonObject.getJSONArray(key); - String[] strings = new String[array.length()]; - for (int x = 0; x < array.length(); x++) { - String s = array.getString(x); - strings[x] = (String) deserialize(s); - } - switch (key) { - case "genres": - novelPage.genres = strings; - break; - case "authors": - novelPage.authors = strings; - break; - case "tags": - novelPage.tags = strings; - break; - case "artists": - novelPage.artists = strings; - break; - } - break; - case "novelChapters": - JSONArray jsonArray = jsonObject.getJSONArray(key); - ArrayList novelChapters = new ArrayList<>(); - for (int x = 0; x < jsonArray.length(); x++) { - novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); - } - novelPage.novelChapters = novelChapters; - break; - default: - String response = jsonObject.getString(key); - if (!response.equals("null")) { - if (debug) - System.out.println("Serial response of novelChapter key [" + key + "]: " + response); - response = (String) deserialize(response); - } - switch (key) { - case "title": - if (response.equals("null")) - novelPage.title = null; - else novelPage.title = response; - break; - case "imageURL": - if (response.equals("null")) - novelPage.imageURL = null; - else novelPage.imageURL = response; - break; - case "description": - if (response.equals("null")) - novelPage.description = null; - else novelPage.description = response; - break; - case "language": - if (response.equals("null")) - novelPage.language = null; - else novelPage.language = response; - break; - } - break; - } - } - return novelPage; - } - - public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { - NovelChapter novelChapter = new NovelChapter(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); - for (String key : NOVELCHAPTERKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - String response = (String) deserialize(jsonObject.getString(key)); - switch (key) { - case "release": - if (response.equals("null")) - novelChapter.release = null; - else novelChapter.release = response; - break; - case "chapterNum": - if (response.equals("null")) - novelChapter.chapterNum = null; - else novelChapter.chapterNum = response; - break; - case "link": - if (response.equals("null")) - novelChapter.link = null; - else novelChapter.link = response; - break; - } - } - return novelChapter; - } - - private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("release", serialize(novelChapter.release)); - jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); - jsonObject.put("link", serialize(novelChapter.link)); - return jsonObject; - } - -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index d6d8d23ce8..483b66e6f8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -173,7 +173,7 @@ protected void onPostExecute(Boolean aBoolean) { if (Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) { try { Database.DatabaseLibrary.updateData(StaticNovel.novelURL, StaticNovel.novelPage); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java index 0100c59f6f..1f9c360f59 100644 --- a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java +++ b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java @@ -1,11 +1,5 @@ package com.github.doomsdayrs.apps.shosetsu; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; - -import org.junit.Test; - -import java.io.IOException; - /** * Example local unit test, which will execute on the development machine (host). * @@ -13,14 +7,6 @@ */ public class ExampleUnitTest { - @Test - public void format() { - try { - System.out.println((String) Database.deserialize("U3RyaW5n")); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } - } } \ No newline at end of file From 1543a743ae53e270c95cf95a79528065a0a106d6 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Sep 2019 16:36:11 -0400 Subject: [PATCH 007/162] Back and forth work.. --- .../apps/shosetsu/backend/database/DBHelper.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index f54ac83a5e..a41d091243 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -4,6 +4,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; @@ -137,10 +138,10 @@ private static ArrayList getPages(SQLiteDatabase sqLiteDatabase) { try { cursor.moveToNext(); String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString())); - cursor.close(); if (text != null) { novelPages.add(new Holder(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), (NovelPage) deserialize(text))); } + cursor.close(); } catch (Exception e) { e.printStackTrace(); } @@ -320,11 +321,14 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(UPDATES_CREATE); } if (oldVersion < 8) { + Log.i("DBUpgrade", "Upgrading to version 8"); + // Updates chapters first, being most resource intensive ArrayList holders = getPages(db); if (holders != null) { for (Holder holder : holders) { try { + Log.i("Processing", holder.novelURL); updateNovelData(db, holder.novelURL, holder.novelPage); } catch (Exception e) { e.printStackTrace(); @@ -334,6 +338,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { ArrayList novelChapters = getChapters(db); if (novelChapters != null) { for (NovelChapter novelChapter : novelChapters) { + Log.i("Processing", novelChapter.link); try { updateChapterData(db, novelChapter.link, novelChapter); } catch (Exception e) { From 9e575c3ba1d49d9fd7eb564a6136b67f18a91228 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Sep 2019 16:47:28 -0400 Subject: [PATCH 008/162] This update marks a cutoff, v1.0.0, why? Because im crud at coding --- .../shosetsu/backend/database/DBHelper.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index a41d091243..2bd66cbb52 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -136,10 +136,11 @@ private static ArrayList getPages(SQLiteDatabase sqLiteDatabase) { } else { ArrayList novelPages = new ArrayList<>(); try { - cursor.moveToNext(); - String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString())); - if (text != null) { - novelPages.add(new Holder(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), (NovelPage) deserialize(text))); + while (cursor.moveToNext()) { + String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString())); + if (text != null) { + novelPages.add(new Holder(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), (NovelPage) deserialize(text))); + } } cursor.close(); } catch (Exception e) { @@ -157,12 +158,13 @@ private static ArrayList getChapters(SQLiteDatabase sqLiteDatabase } else { ArrayList novelChapters = new ArrayList<>(); try { - cursor.moveToNext(); - String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); - cursor.close(); - if (text != null) { - novelChapters.add((NovelChapter) deserialize(text)); + while (cursor.moveToNext()) { + String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); + if (text != null) { + novelChapters.add((NovelChapter) deserialize(text)); + } } + cursor.close(); } catch (Exception e) { e.printStackTrace(); } From c60eec9e7d03c7f65f195e0b31826c1a0f56588b Mon Sep 17 00:00:00 2001 From: Rahim Date: Mon, 9 Sep 2019 20:56:14 -0400 Subject: [PATCH 009/162] Fixed description issues --- .../res/layout-land/fragment_novel_main.xml | 420 ++++++++--------- .../main/res/layout/fragment_novel_main.xml | 428 +++++++++--------- gradlew.bat | 168 +++---- 3 files changed, 507 insertions(+), 509 deletions(-) diff --git a/app/src/main/res/layout-land/fragment_novel_main.xml b/app/src/main/res/layout-land/fragment_novel_main.xml index 319bb0d756..047ba82e2d 100644 --- a/app/src/main/res/layout-land/fragment_novel_main.xml +++ b/app/src/main/res/layout-land/fragment_novel_main.xml @@ -7,220 +7,222 @@ android:layout_height="match_parent"> - - - - - - - - - - - - - - - + android:layout_height="wrap_content"> + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" + android:text="@string/novel_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/fragment_novel_image" + app:layout_constraintTop_toBottomOf="@+id/fragment_novel_genres" /> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_novel_main.xml b/app/src/main/res/layout/fragment_novel_main.xml index dc3f8436ba..507ce161af 100644 --- a/app/src/main/res/layout/fragment_novel_main.xml +++ b/app/src/main/res/layout/fragment_novel_main.xml @@ -6,228 +6,224 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - - - - - - - - + + android:layout_height="wrap_content"> + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/fragment_novel_genres" /> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat index f9553162f1..e95643d6a2 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 4b488e3fe1155182cfd12c3ba52ebeef0572d993 Mon Sep 17 00:00:00 2001 From: Rahim Date: Mon, 9 Sep 2019 20:57:40 -0400 Subject: [PATCH 010/162] Updated graphql --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b20aa8ccca..e40acc3ab0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,7 +48,7 @@ repositories { dependencies { implementation 'com.google.android.material:material:1.1.0-alpha10' - implementation 'com.graphql-java:graphql-java:2019-08-20T01-08-54-018b57c' + implementation 'com.graphql-java:graphql-java:2019-09-07T08-08-53-173312e' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible From b66b815772dbaf8e8fa7597b519431c76a38059d Mon Sep 17 00:00:00 2001 From: Rahim Date: Wed, 11 Sep 2019 13:08:02 -0400 Subject: [PATCH 011/162] Maybe fixes #42 --- .../github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 9dabfe814f..261e7b8088 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -70,6 +70,7 @@ public class ChapterReader extends AppCompatActivity { public boolean ready = false; + public ScrollView scrollView; public TextView textView; public ProgressBar progressBar; From 74e82bd6ce70ae53fe31f0ff61be99b1d580747f Mon Sep 17 00:00:00 2001 From: Rahim Date: Mon, 23 Sep 2019 08:36:21 -0400 Subject: [PATCH 012/162] 99% way check for next chapter icon --- .../apps/shosetsu/ui/reader/ChapterReader.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 261e7b8088..a950683310 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -61,6 +61,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 9 / June / 2019 * @@ -527,10 +530,16 @@ public void addBottomListener() { * What to do when scroll hits bottom */ public void bottom() { + int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); if (ready) - if (scrollView.canScrollVertically(1)) { + if ((scrollView.getScrollY() / (float) total) < .99) { int y = scrollView.getScrollY(); if (y % 5 == 0) { + Log.d("YMAX", String.valueOf(total)); + Log.d("YC", String.valueOf(y)); + Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); + Log.d("TY", String.valueOf(textView.getScrollY())); + if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterURL) != Status.READ) Database.DatabaseChapter.updateY(chapterURL, y); } From 3ae3fe67649f7e1d5b4627c6ad361188ab13a039 Mon Sep 17 00:00:00 2001 From: Rahim Date: Mon, 23 Sep 2019 08:42:38 -0400 Subject: [PATCH 013/162] Removed backwards compatibility. Prep for hell --- app/build.gradle | 1 - .../shosetsu/backend/database/Database.java | 49 --------------- .../backend/database/objects/DBChapter.java | 59 ------------------ .../database/objects/DBDownloadItem.java | 54 ---------------- .../backend/database/objects/DBNovel.java | 58 ------------------ .../database/objects/SUPERSERIALZIED.java | 61 ------------------- .../database/objects/SettingsSerialized.java | 59 ------------------ .../backend/database/objects/base/Base.java | 39 ------------ .../database/objects/base/BaseChapter.java | 40 ------------ 9 files changed, 420 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java diff --git a/app/build.gradle b/app/build.gradle index e40acc3ab0..68f62715dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,7 +61,6 @@ dependencies { implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.2' implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.1' - implementation 'com.github.Doomsdayrs:novelreader-services:1.1.4' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'org.jetbrains:annotations:17.0.0' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 1450e24a56..c610d303f4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -150,55 +150,6 @@ public static Object deserialize(String string) throws IOException, ClassNotFoun ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); Object object = objectInputStream.readObject(); - Class c = object.getClass(); - if (c.equals(com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelPage.class)) { - System.out.println("WARNING, OLD PAGE DETECTED."); - NovelPage newPage = new NovelPage(); - com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelPage oldPage = (com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelPage) object; - newPage.artists = oldPage.artists; - newPage.authors = oldPage.artists; - newPage.description = oldPage.description; - newPage.genres = oldPage.genres; - newPage.imageURL = oldPage.imageURL; - newPage.language = oldPage.language; - newPage.maxChapterPage = oldPage.maxChapterPage; - newPage.novelChapters = new ArrayList<>(); - for (com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelChapter C : oldPage.novelChapters) { - NovelChapter newC = new NovelChapter(); - newC.chapterNum = C.chapterNum; - newC.link = C.link; - newC.release = C.release; - newPage.novelChapters.add(newC); - } - if (oldPage.status != null) - switch (oldPage.status) { - case PUBLISHING: - newPage.status = Stati.PUBLISHING; - break; - case COMPLETED: - newPage.status = Stati.COMPLETED; - break; - case PAUSED: - newPage.status = Stati.PAUSED; - break; - case UNKNOWN: - newPage.status = Stati.UNKNOWN; - break; - } - else newPage.status = Stati.UNKNOWN; - - newPage.tags = oldPage.tags; - newPage.title = oldPage.title; - return newPage; - } else if (c.equals(com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelChapter.class)) { - System.out.println("WARNING, OLD CHAPTER DETECTED."); - com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelChapter C = (com.github.Doomsdayrs.api.novelreader_core.services.core.objects.NovelChapter) object; - NovelChapter newC = new NovelChapter(); - newC.chapterNum = C.chapterNum; - newC.link = C.link; - newC.release = C.release; - return newC; - } return object; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java deleted file mode 100644 index 45774b0efc..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class DBChapter extends BaseChapter { - static final long serialVersionUID = 2002; - - public final String SAVED_DATA; - public final int Y; - public final int READ_CHAPTER; - public final boolean BOOKMARKED; - public final boolean IS_SAVED; - public final String SAVE_PATH; - - public DBChapter(String novel_url, String chapter_url, String saved_data, int y, int read_chapter, boolean bookmarked, boolean is_saved, String save_path) { - super(novel_url, chapter_url); - SAVED_DATA = saved_data; - Y = y; - READ_CHAPTER = read_chapter; - BOOKMARKED = bookmarked; - IS_SAVED = is_saved; - SAVE_PATH = save_path; - } - - @Override - public String toString() { - return "Chapter{" + - "SAVED_DATA='" + SAVED_DATA + '\'' + - ", Y='" + Y + '\'' + - ", READ_CHAPTER=" + READ_CHAPTER + - ", BOOKMARKED=" + BOOKMARKED + - ", IS_SAVED=" + IS_SAVED + - ", SAVE_PATH='" + SAVE_PATH + '\'' + - ", CHAPTER_URL='" + CHAPTER_URL + '\'' + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java deleted file mode 100644 index cb67b01815..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */public class DBDownloadItem extends BaseChapter { - static final long serialVersionUID = 2003; - - - public final int FORMATTER_ID; - public final String NOVEL_NAME; - public final String CHAPTER_NAME; - public final boolean PAUSED; - - public DBDownloadItem(String novel_url, String chapter_url, int formatter_id, String novel_name, String chapter_name, boolean paused) { - super(novel_url, chapter_url); - FORMATTER_ID = formatter_id; - NOVEL_NAME = novel_name; - CHAPTER_NAME = chapter_name; - PAUSED = paused; - } - - - @Override - public String toString() { - return "Download{" + - "FORMATTER_ID=" + FORMATTER_ID + - ", NOVEL_NAME='" + NOVEL_NAME + '\'' + - ", CHAPTER_NAME='" + CHAPTER_NAME + '\'' + - ", PAUSED=" + PAUSED + - ", CHAPTER_URL='" + CHAPTER_URL + '\'' + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java deleted file mode 100644 index 3b3259cb8e..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.Base; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class DBNovel extends Base { - static final long serialVersionUID = 2004; - - - public final boolean BOOKMARKED; - - /** - * Serialized NovelPage object in string form, must be deserialized for use - */ - public final String NOVEL_PAGE; - - public final int FORMATTER_ID; - public final int STATUS; - - public DBNovel(String novel_url, boolean bookmarked, String novel_page, int formatter_id, int status) { - super(novel_url); - BOOKMARKED = bookmarked; - NOVEL_PAGE = novel_page; - FORMATTER_ID = formatter_id; - STATUS = status; - } - - @Override - public String toString() { - return "Library{" + - "BOOKMARKED=" + BOOKMARKED + - ", NOVEL_PAGE='" + NOVEL_PAGE + '\'' + - ", FORMATTER_ID=" + FORMATTER_ID + - ", STATUS=" + STATUS + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java deleted file mode 100644 index 6ec3823ead..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class SUPERSERIALZIED implements Serializable { - static final long serialVersionUID = 2006; - - - public final ArrayList libraries = new ArrayList<>(); - public final ArrayList DBChapters = new ArrayList<>(); - public final ArrayList DBDownloadItems = new ArrayList<>(); - - @Deprecated - public final ArrayList updates = new ArrayList<>(); - public final SettingsSerialized settingsSerialized = new SettingsSerialized(); - - @Override - public String toString() { - return "SUPERSERIALZIED{" + - "libraries=" + libraries + - ", chapters=" + DBChapters + - ", downloads=" + DBDownloadItems + - ", updates=" + updates + - ", settings=" + settingsSerialized + - '}'; - } - - public String serialize() { - try { - return Database.serialize(this); - } catch (IOException e) { - e.printStackTrace(); - } - return "FUCK_UP"; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java deleted file mode 100644 index 8f10adc736..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.variables.Settings; - -import org.jetbrains.annotations.NotNull; - -import java.io.Serializable; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class SettingsSerialized implements Serializable { - static final long serialVersionUID = 2005; - - - public int reader_text_color = Settings.ReaderTextColor; - public int reader_text_background_color = Settings.ReaderTextBackgroundColor; - public String shoDir = Utilities.shoDir; - public boolean paused = Settings.downloadPaused; - public float textSize = Settings.ReaderTextSize; - public int themeMode = Settings.themeMode; - public int paraSpace = Settings.paragraphSpacing; - public int indent = Settings.indentSize; - public boolean tap_to_scroll = Utilities.isTapToScroll(); - - @NotNull - @Override - public String toString() { - return "SettingsSerialized{" + - "reader_text_color=" + reader_text_color + - ", reader_text_background_color=" + reader_text_background_color + - ", shoDir='" + shoDir + '\'' + - ", paused=" + paused + - ", textSize=" + textSize + - ", themeMode=" + themeMode + - ", paraSpace=" + paraSpace + - ", indent=" + indent + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java deleted file mode 100644 index 347c9c1aaa..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; - -import java.io.Serializable; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */public class Base implements Serializable { - static final long serialVersionUID = 2000; - public final String NOVEL_URL; - - public Base(String novel_url) { - NOVEL_URL = novel_url; - } - - @Override - public String toString() { - return "Base{" + - "NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java deleted file mode 100644 index 995ceaec8d..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */public class BaseChapter extends Base { - static final long serialVersionUID = 2001; - - public final String CHAPTER_URL; - - public BaseChapter(String novel_url, String chapter_url) { - super(novel_url); - CHAPTER_URL = chapter_url; - } - - @Override - public String toString() { - return "BaseChapter{" + - "CHAPTER_URL='" + CHAPTER_URL + '\'' + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} From 0b559d4719e898db073d25bd11d112161d3fc10b Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 12 Oct 2019 11:17:28 -0400 Subject: [PATCH 014/162] Working on rework. Finished Backup system, now to get restore --- app/build.gradle | 2 +- .../apps/shosetsu/backend/Serialize.java | 46 ++++++++ .../shosetsu/backend/database/Database.java | 4 +- .../backup/async/BackupProcess.java | 104 +++++++++++------- .../subFragments/backup/async/schema.json | 8 +- 5 files changed, 115 insertions(+), 49 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 207174e744..afe9902eae 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ android { minSdkVersion 22 targetSdkVersion 29 versionCode 19 - versionName "v1.2.0-alpha" + versionName "v1.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index 2745e05725..5757aa1e34 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -3,6 +3,8 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import org.json.JSONArray; import org.json.JSONException; @@ -11,6 +13,7 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; @@ -35,6 +38,7 @@ public class Serialize { private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; + private static boolean debug = false; public static void toggleDebug() { @@ -119,6 +123,13 @@ public static String serializeOBJECT(Object object) throws Exception { } else throw new Exception("Illegal class"); } + /** + * Deserializes a NovelPage from JSON + * + * @param serial SERIAL String + * @return NovelPage + * @throws Exception If something goes wrong + */ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { NovelPage novelPage = new NovelPage(); JSONObject jsonObject = new JSONObject((String) deserialize(serial)); @@ -218,6 +229,13 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception return novelPage; } + /** + * Deserializes a NovelChapter from JSON + * + * @param serial SERIAL String + * @return NovelChapter + * @throws Exception If something goes wrong + */ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { NovelChapter novelChapter = new NovelChapter(); JSONObject jsonObject = new JSONObject((String) deserialize(serial)); @@ -247,6 +265,14 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc return novelChapter; } + /** + * Converts a NovelChapter TO json + * + * @param novelChapter NovelChapter to convert + * @return JSON version of NovelChapter + * @throws IOException EXCEPTION + * @throws JSONException EXCEPTION + */ private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("release", serialize(novelChapter.release)); @@ -255,4 +281,24 @@ private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws I return jsonObject; } + /** + * Returns current settings in JSON format, Follows schema.json + * + * @return JSON of settings + * @throws JSONException EXCEPTION + * @throws IOException EXCEPTION IN SERIALIZING + */ + public static JSONObject getSettingsInJSON() throws JSONException, IOException { + JSONObject settings = new JSONObject(); + settings.put("reader_text_color", Settings.ReaderTextColor); + settings.put("reader_text_background_color", Settings.ReaderTextBackgroundColor); + settings.put("shoDir", Database.serialize(shoDir)); + settings.put("paused", Settings.downloadPaused); + settings.put("textSize", Settings.ReaderTextSize); + settings.put("themeMode", Settings.themeMode); + settings.put("paraSpace", Settings.paragraphSpacing); + settings.put("indent", Settings.indentSize); + settings.put("tap_to_scroll", Utilities.isTapToScroll()); + return settings; + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 25870068c8..c3e1af5690 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -125,7 +125,7 @@ public String toString() { * @return Serialised string * @throws IOException exception */ - public static String serialize(Object object) throws IOException { + public static String serialize(@NotNull Object object) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(object); @@ -141,7 +141,7 @@ public static String serialize(Object object) throws IOException { * @throws IOException exception * @throws ClassNotFoundException exception */ - public static Object deserialize(String string) throws IOException, ClassNotFoundException { + public static Object deserialize(@NotNull String string) throws IOException, ClassNotFoundException { byte[] bytes = Base64.decode(string, Base64.NO_WRAP); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index b5af2d6e5e..f61e81cbb2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -23,11 +23,12 @@ import android.os.AsyncTask; import android.util.Log; +import com.github.doomsdayrs.apps.shosetsu.backend.Serialize; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBChapter; -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBDownloadItem; -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBNovel; -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.SUPERSERIALZIED; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; @@ -66,66 +67,85 @@ protected void onPostExecute(Void aVoid) { @Override protected Void doInBackground(Void... voids) { try { - final SUPERSERIALZIED SUPER_SERIALIZED = new SUPERSERIALZIED(); + final JSONObject BACKUP = new JSONObject(); Log.i("Progress", "Backing up novels"); - // Library backup { + final JSONArray NOVELS = new JSONArray(); Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.NOVELS + " where " + Database.Columns.BOOKMARKED + "=1", null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { + + // Gets the novelURL String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); Log.i("NovelBack", nurl); - boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); - String npage = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString())); - int formatter_id = cursor.getInt(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())); - int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); - SUPER_SERIALIZED.libraries.add(new DBNovel(nurl, bookmarked, npage, formatter_id, status)); + // Gets if it is in library, if not then it skips + boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); + Log.i("NovelBack", "Valid?: " + bookmarked); + if (bookmarked) { + //SHOULD BE IN JSON ALREADY + JSONObject npage = new JSONObject(cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString()))); + npage.put("novelChapters", new JSONArray()); + + // ID of formatter + int formatter_id = cursor.getInt(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())); + + //IGNORED: int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); + + JSONObject novel = new JSONObject(); + novel.put("novelURL", Database.serialize(nurl)); + novel.put("bookmarked", true); + novel.put("FORMATTER_ID", formatter_id); + novel.put("novelPage", npage); + NOVELS.put(novel); + } } + BACKUP.put("novels", NOVELS); cursor.close(); } - // TODO figure out how to prevent non library chapters from being saved, lowering size of backup Log.i("Progress", "Backing up Chapters"); - // Chapter backup { + final JSONArray CHAPTERS = new JSONArray(); Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.CHAPTERS, null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); - // very dirty logger - //Log.i("ChapterBack", curl); - String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); - int y = cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString())); - int read_chapter = cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString())); - boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); - boolean is_saved = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.IS_SAVED.toString()))); - String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); - SUPER_SERIALIZED.DBChapters.add(new DBChapter(nurl, curl, saved_data, y, read_chapter, bookmarked, is_saved, path)); + boolean inLibrary = Database.DatabaseLibrary.isBookmarked(nurl); + if (inLibrary) { + String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); + // very dirty logger + //Log.i("ChapterBack", curl); + + String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); + int y = cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString())); + int read_chapter = cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString())); + boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); + boolean is_saved = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.IS_SAVED.toString()))); + String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); + + JSONObject chapter = new JSONObject(); + chapter.put("novelURL", Database.serialize(nurl)); + chapter.put("chapterURL", Database.serialize(curl)); + + //TODO Figure out where i use this + //chapter.put("SAVED_DATA",); + + chapter.put("Y", y); + chapter.put("READ_CHAPTER", read_chapter); + chapter.put("BOOKMARKED", bookmarked); + chapter.put("IS_SAVED", is_saved); + chapter.put("SAVE_PATH", Database.serialize(path)); + CHAPTERS.put(chapter); + } } + BACKUP.put("chapters", CHAPTERS); cursor.close(); } - Log.i("Progress", "Backing up Downloads"); - // Downloads backup - { - Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.DOWNLOADS, null); - if (!(cursor.getCount() <= 0)) - while (cursor.moveToNext()) { - String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); - String nname = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_NAME.toString())); - String cname = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_NAME.toString())); - int formatter_id = cursor.getInt(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())); - boolean paused = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.PAUSED.toString()))); - - SUPER_SERIALIZED.DBDownloadItems.add(new DBDownloadItem(nurl, curl, formatter_id, nname, cname, paused)); - } - cursor.close(); - } + BACKUP.put("settings", Serialize.getSettingsInJSON()); Log.i("Progress", "Writing"); File folder = new File(shoDir + "/backup/"); @@ -136,9 +156,9 @@ protected Void doInBackground(Void... voids) { FileOutputStream fileOutputStream = new FileOutputStream( (folder.getPath() + "/backup-" + (new Date().toString()) + ".shoback") ); - fileOutputStream.write(SUPER_SERIALIZED.serialize().getBytes()); + fileOutputStream.write(BACKUP.toString().getBytes()); fileOutputStream.close(); - } catch (IOException e) { + } catch (IOException | JSONException e) { e.printStackTrace(); } return null; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json index 56edb0b9a5..13f36b7b89 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json @@ -1,16 +1,17 @@ { "ignoreThis": "This is an example of schema for the backup, use it for reference. Strings should be serialized before being put into json, and each sub JSON should be serialized aswell", "ignoreThis2": "the type of data is specified in KEY, remove them and the spaces for a proper key for actual JSON files", + "settings": { "reader_text_color": "Settings.ReaderTextColor", "reader_text_background_color": "Settings.ReaderTextBackgroundColor", "shoDir": "Utilities.shoDir : Serialize this", "paused": "Settings.downloadPaused", "textSize": "Settings.ReaderTextSize", - "themeMode ": "Settings.themeMode", + "themeMode": "Settings.themeMode", "paraSpace": "Settings.paragraphSpacing", "indent": "Settings.indentSize", - "tap_to_scroll ": " Utilities.isTapToScroll()" + "tap_to_scroll": " Utilities.isTapToScroll()" }, "novels": [ { @@ -19,7 +20,6 @@ "STATUS": "ignore", "bookmarked": "", "novelPage": { - "ignoreThis5": "TODO make method in base objects to convert themselves to json", "title": "serialize", "imageURL": "serialize", "description": "serialize", @@ -34,7 +34,7 @@ ], "language": "serialize", "maxChapterPage": "", - "novelChapters": "ignore this completely, it is not needed for most operations. This is just here to tell you to ignore this" + "novelChapters": "Just set this ARRAY to an empty one." } } ], From ccc4948190a634421374ab798847e7e0b3284e1c Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 12 Oct 2019 11:29:57 -0400 Subject: [PATCH 015/162] Merging branches --- .../backend/database/objects/DBChapter.java | 57 ++++++++++++++++++ .../database/objects/DBDownloadItem.java | 51 ++++++++++++++++ .../backend/database/objects/DBNovel.java | 55 ++++++++++++++++++ .../database/objects/SUPERSERIALZIED.java | 58 +++++++++++++++++++ .../database/objects/SettingsSerialized.java | 56 ++++++++++++++++++ .../backend/database/objects/base/Base.java | 38 ++++++++++++ .../database/objects/base/BaseChapter.java | 38 ++++++++++++ .../backup/async/RestoreProcess.java | 16 +---- 8 files changed, 355 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java new file mode 100644 index 0000000000..5b8b265bb8 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java @@ -0,0 +1,57 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; + +import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */ +public class DBChapter extends BaseChapter { + public final String SAVED_DATA; + public final int Y; + public final int READ_CHAPTER; + public final boolean BOOKMARKED; + public final boolean IS_SAVED; + public final String SAVE_PATH; + + public DBChapter(String novel_url, String chapter_url, String saved_data, int y, int read_chapter, boolean bookmarked, boolean is_saved, String save_path) { + super(novel_url, chapter_url); + SAVED_DATA = saved_data; + Y = y; + READ_CHAPTER = read_chapter; + BOOKMARKED = bookmarked; + IS_SAVED = is_saved; + SAVE_PATH = save_path; + } + + @Override + public String toString() { + return "Chapter{" + + "SAVED_DATA='" + SAVED_DATA + '\'' + + ", Y='" + Y + '\'' + + ", READ_CHAPTER=" + READ_CHAPTER + + ", BOOKMARKED=" + BOOKMARKED + + ", IS_SAVED=" + IS_SAVED + + ", SAVE_PATH='" + SAVE_PATH + '\'' + + ", CHAPTER_URL='" + CHAPTER_URL + '\'' + + ", NOVEL_URL='" + NOVEL_URL + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java new file mode 100644 index 0000000000..1057e343a5 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java @@ -0,0 +1,51 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; + +import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */public class DBDownloadItem extends BaseChapter { + public final int FORMATTER_ID; + public final String NOVEL_NAME; + public final String CHAPTER_NAME; + public final boolean PAUSED; + + public DBDownloadItem(String novel_url, String chapter_url, int formatter_id, String novel_name, String chapter_name, boolean paused) { + super(novel_url, chapter_url); + FORMATTER_ID = formatter_id; + NOVEL_NAME = novel_name; + CHAPTER_NAME = chapter_name; + PAUSED = paused; + } + + + @Override + public String toString() { + return "Download{" + + "FORMATTER_ID=" + FORMATTER_ID + + ", NOVEL_NAME='" + NOVEL_NAME + '\'' + + ", CHAPTER_NAME='" + CHAPTER_NAME + '\'' + + ", PAUSED=" + PAUSED + + ", CHAPTER_URL='" + CHAPTER_URL + '\'' + + ", NOVEL_URL='" + NOVEL_URL + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java new file mode 100644 index 0000000000..1b2b225557 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java @@ -0,0 +1,55 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; + +import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.Base; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */ +public class DBNovel extends Base { + public final boolean BOOKMARKED; + + /** + * Serialized NovelPage object in string form, must be deserialized for use + */ + public final String NOVEL_PAGE; + + public final int FORMATTER_ID; + public final int STATUS; + + public DBNovel(String novel_url, boolean bookmarked, String novel_page, int formatter_id, int status) { + super(novel_url); + BOOKMARKED = bookmarked; + NOVEL_PAGE = novel_page; + FORMATTER_ID = formatter_id; + STATUS = status; + } + + @Override + public String toString() { + return "Library{" + + "BOOKMARKED=" + BOOKMARKED + + ", NOVEL_PAGE='" + NOVEL_PAGE + '\'' + + ", FORMATTER_ID=" + FORMATTER_ID + + ", STATUS=" + STATUS + + ", NOVEL_URL='" + NOVEL_URL + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java new file mode 100644 index 0000000000..52aa3f5d1b --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java @@ -0,0 +1,58 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; + +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */ +public class SUPERSERIALZIED implements Serializable { + public final ArrayList libraries = new ArrayList<>(); + public final ArrayList DBChapters = new ArrayList<>(); + public final ArrayList DBDownloadItems = new ArrayList<>(); + + @Deprecated + public final ArrayList updates = new ArrayList<>(); + public final SettingsSerialized settingsSerialized = new SettingsSerialized(); + + @Override + public String toString() { + return "SUPERSERIALZIED{" + + "libraries=" + libraries + + ", chapters=" + DBChapters + + ", downloads=" + DBDownloadItems + + ", updates=" + updates + + ", settings=" + settingsSerialized + + '}'; + } + + public String serialize() { + try { + return Database.serialize(this); + } catch (IOException e) { + e.printStackTrace(); + } + return "FUCK_UP"; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java new file mode 100644 index 0000000000..665c26ec4b --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java @@ -0,0 +1,56 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; + +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */ +public class SettingsSerialized implements Serializable { + public int reader_text_color = Settings.ReaderTextColor; + public int reader_text_background_color = Settings.ReaderTextBackgroundColor; + public String shoDir = Utilities.shoDir; + public boolean paused = Settings.downloadPaused; + public float textSize = Settings.ReaderTextSize; + public int themeMode = Settings.themeMode; + public int paraSpace = Settings.paragraphSpacing; + public int indent = Settings.indentSize; + public boolean tap_to_scroll = Utilities.isTapToScroll(); + + @NotNull + @Override + public String toString() { + return "SettingsSerialized{" + + "reader_text_color=" + reader_text_color + + ", reader_text_background_color=" + reader_text_background_color + + ", shoDir='" + shoDir + '\'' + + ", paused=" + paused + + ", textSize=" + textSize + + ", themeMode=" + themeMode + + ", paraSpace=" + paraSpace + + ", indent=" + indent + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java new file mode 100644 index 0000000000..693517811c --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java @@ -0,0 +1,38 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; + +import java.io.Serializable; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */public class Base implements Serializable { + public final String NOVEL_URL; + + public Base(String novel_url) { + NOVEL_URL = novel_url; + } + + @Override + public String toString() { + return "Base{" + + "NOVEL_URL='" + NOVEL_URL + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java new file mode 100644 index 0000000000..063b12fa39 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java @@ -0,0 +1,38 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; + +/* + * This file is part of Shosetsu. + * + * Shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Shosetsu. If not, see . + * ==================================================================== + * shosetsu + * 27 / 07 / 2019 + * + * @author github.com/doomsdayrs + */public class BaseChapter extends Base { + public final String CHAPTER_URL; + + public BaseChapter(String novel_url, String chapter_url) { + super(novel_url); + CHAPTER_URL = chapter_url; + } + + @Override + public String toString() { + return "BaseChapter{" + + "CHAPTER_URL='" + CHAPTER_URL + '\'' + + ", NOVEL_URL='" + NOVEL_URL + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index 172f029fa9..aa6628c711 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -29,21 +29,8 @@ import android.widget.Toast; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.SUPERSERIALZIED; -import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import com.github.doomsdayrs.apps.shosetsu.variables.DownloadItem; -import com.github.doomsdayrs.apps.shosetsu.variables.Settings; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; -import java.io.IOException; - -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; /** * shosetsu @@ -102,6 +89,7 @@ protected void onPostExecute(Boolean b) { @Override protected Boolean doInBackground(Void... voids) { File file = new File("" + file_path); + /* if (file.exists()) { try { BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); @@ -117,7 +105,6 @@ protected Boolean doInBackground(Void... voids) { } textView.post(() -> textView.setText(R.string.reading_file)); - SUPERSERIALZIED superserialzied = (SUPERSERIALZIED) deserialize(string.toString()); progressBar.post(() -> progressBar.setMax(superserialzied.DBChapters.size() + superserialzied.libraries.size() + superserialzied.DBDownloadItems.size() + 1)); Log.i("Progress", "Restoring downloads"); @@ -223,6 +210,7 @@ protected Boolean doInBackground(Void... voids) { e.printStackTrace(); } } + */ return false; } } From 4483c4aa42c787c151d4ffc3ab3dcad263ad87c3 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 12 Oct 2019 11:38:37 -0400 Subject: [PATCH 016/162] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa --- .../shosetsu/backend/database/DBHelper.java | 246 +----------------- .../shosetsu/backend/database/Database.java | 23 -- 2 files changed, 8 insertions(+), 261 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 2bd66cbb52..126a06515d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -1,23 +1,12 @@ package com.github.doomsdayrs.apps.shosetsu.backend.database; import android.content.Context; -import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; - -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; - /* * This file is part of Shosetsu. * @@ -103,10 +92,9 @@ public class DBHelper extends SQLiteOpenHelper { * @param context main context */ public DBHelper(Context context) { - super(context, DB_NAME, null, 8); + super(context, DB_NAME, null, 9); } - /** * Creates DB things * @@ -120,57 +108,6 @@ public void onCreate(SQLiteDatabase db) { db.execSQL(UPDATES_CREATE); } - private static void updateNovelData(SQLiteDatabase sqLiteDatabase, @NotNull String novelURL, @NotNull NovelPage novelPage) throws Exception { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.NOVEL_PAGE + "='" + serializeOBJECT(novelPage) + "' where " + Columns.NOVEL_URL + "='" + novelURL + "'"); - } - - private static void updateChapterData(SQLiteDatabase sqLiteDatabase, @NotNull String chapterURL, @NotNull NovelChapter novelChapter) throws Exception { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVED_DATA + "='" + serializeOBJECT(novelChapter) + "' where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); - } - - private static ArrayList getPages(SQLiteDatabase sqLiteDatabase) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_PAGE + "," + Columns.NOVEL_URL + " from " + Tables.NOVELS, null); - if (cursor.getCount() <= 0) { - cursor.close(); - return null; - } else { - ArrayList novelPages = new ArrayList<>(); - try { - while (cursor.moveToNext()) { - String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString())); - if (text != null) { - novelPages.add(new Holder(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), (NovelPage) deserialize(text))); - } - } - cursor.close(); - } catch (Exception e) { - e.printStackTrace(); - } - return novelPages; - } - } - - private static ArrayList getChapters(SQLiteDatabase sqLiteDatabase) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.SAVED_DATA + " from " + Tables.CHAPTERS, null); - if (cursor.getCount() <= 0) { - cursor.close(); - return null; - } else { - ArrayList novelChapters = new ArrayList<>(); - try { - while (cursor.moveToNext()) { - String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); - if (text != null) { - novelChapters.add((NovelChapter) deserialize(text)); - } - } - cursor.close(); - } catch (Exception e) { - e.printStackTrace(); - } - return novelChapters; - } - } /** * Upgrades database @@ -181,184 +118,17 @@ private static ArrayList getChapters(SQLiteDatabase sqLiteDatabase */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if (oldVersion < 4) { - db.execSQL("drop table if exists library"); - db.execSQL("drop table if exists bookmarks"); - db.execSQL("drop table if exists downloads"); - db.execSQL("drop table if exists chapters"); - db.execSQL("create TABLE if not exists library (" + - // URL of this novel - Database.Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Database.Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Database.Columns.FORMATTER_ID + " integer not null," + - Database.Columns.MAX_PAGE + " integer not null," + - Database.Columns.STATUS + " integer not null" + ")"); + if (oldVersion < 9) { + db.execSQL("DROP TABLE IF EXISTS " + Tables.CHAPTERS); + db.execSQL("DROP TABLE IF EXISTS " + Tables.NOVELS); + db.execSQL("DROP TABLE IF EXISTS " + Tables.DOWNLOADS); + db.execSQL("DROP TABLE IF EXISTS " + Tables.UPDATES); + + db.execSQL(NOVELS); db.execSQL(DOWNLOADS_CREATE); db.execSQL(CHAPTERS_CREATE); - } - if (oldVersion < 5) { - // in between - db.execSQL("create TABLE if not exists libraryNext (" + - // URL of this novel - Database.Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Database.Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Database.Columns.FORMATTER_ID + " integer not null," + - Database.Columns.MAX_PAGE + " integer not null," + - Database.Columns.STATUS + " integer not null" + ")"); - - // Move data to middle - Cursor cursor = db.rawQuery("select * from library", null); - - while (cursor.moveToNext()) { - db.execSQL("insert into libraryNext (" + - Database.Columns.NOVEL_URL + "," + - Database.Columns.NOVEL_PAGE + "," + - Database.Columns.FORMATTER_ID + "," + - Database.Columns.MAX_PAGE + "," + - Database.Columns.STATUS + ") values ('" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())) + "','" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString())) + "'," + - cursor.getString(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())) + "," + - 0 + "," + - 0 + ")"); - } - cursor.close(); - // Drop old table - db.execSQL("drop table if exists library"); - db.execSQL("create TABLE if not exists library (" + - // URL of this novel - Database.Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Database.Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Database.Columns.FORMATTER_ID + " integer not null," + - Database.Columns.MAX_PAGE + " integer not null," + - Database.Columns.STATUS + " integer not null" + ")"); - - // Move middle to new - cursor = db.rawQuery("select * from libraryNext", null); - while (cursor.moveToNext()) { - db.execSQL("insert into library (" + - Database.Columns.NOVEL_URL + "," + - Database.Columns.NOVEL_PAGE + "," + - Database.Columns.FORMATTER_ID + "," + - Database.Columns.MAX_PAGE + "," + - Database.Columns.STATUS + ") values ('" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())) + "','" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString())) + "'," + - cursor.getString(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())) + "," + - cursor.getString(cursor.getColumnIndex(Database.Columns.MAX_PAGE.toString())) + "," + - cursor.getString(cursor.getColumnIndex(Database.Columns.STATUS.toString())) + ")"); - } - db.execSQL("drop table if exists libraryNext"); - } - if (oldVersion < 6) { - db.execSQL("drop table if exists libraryNext"); - // in between - db.execSQL("create TABLE if not exists libraryNext (" + - //If in library - Database.Columns.BOOKMARKED + " text not null, " + - // URL of this novel - Database.Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Database.Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Database.Columns.FORMATTER_ID + " integer not null," + - Database.Columns.STATUS + " integer not null" + ")"); - - // Move data to middle - Cursor cursor = db.rawQuery("select * from library", null); - - while (cursor.moveToNext()) { - db.execSQL("insert into libraryNext (" + - Database.Columns.BOOKMARKED + "," + - Database.Columns.NOVEL_URL + "," + - Database.Columns.NOVEL_PAGE + "," + - Database.Columns.FORMATTER_ID + "," + - Database.Columns.STATUS + ") values (" + - 1 + ",'" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())) + "','" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString())) + "'," + - cursor.getString(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())) + "," + - cursor.getString(cursor.getColumnIndex(Database.Columns.STATUS.toString())) + ")"); - } - cursor.close(); - - // Drop old table - db.execSQL("drop table if exists library"); - db.execSQL("create TABLE if not exists " + Database.Tables.NOVELS + " (" + - // If in library - Database.Columns.BOOKMARKED + " integer not null, " + - // URL of this novel - Database.Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Database.Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Database.Columns.FORMATTER_ID + " integer not null," + - Database.Columns.STATUS + " integer not null" + ")"); - - // Move middle to new - cursor = db.rawQuery("select * from libraryNext", null); - while (cursor.moveToNext()) { - db.execSQL("insert into novels (" + - Database.Columns.BOOKMARKED + "," + - Database.Columns.NOVEL_URL + "," + - Database.Columns.NOVEL_PAGE + "," + - Database.Columns.FORMATTER_ID + "," + - Database.Columns.STATUS + ") values (" + - cursor.getString(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString())) + ",'" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())) + "','" + - cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString())) + "'," + - cursor.getString(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())) + "," + - cursor.getString(cursor.getColumnIndex(Database.Columns.STATUS.toString())) + ")"); - } - cursor.close(); - db.execSQL("drop table if exists libraryNext"); - } - if (oldVersion < 7) { db.execSQL(UPDATES_CREATE); } - if (oldVersion < 8) { - Log.i("DBUpgrade", "Upgrading to version 8"); - - // Updates chapters first, being most resource intensive - ArrayList holders = getPages(db); - if (holders != null) { - for (Holder holder : holders) { - try { - Log.i("Processing", holder.novelURL); - updateNovelData(db, holder.novelURL, holder.novelPage); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - ArrayList novelChapters = getChapters(db); - if (novelChapters != null) { - for (NovelChapter novelChapter : novelChapters) { - Log.i("Processing", novelChapter.link); - try { - updateChapterData(db, novelChapter.link, novelChapter); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - - private static class Holder { - final String novelURL; - final NovelPage novelPage; - - Holder(String novelURL, NovelPage novelPage) { - this.novelURL = novelURL; - this.novelPage = novelPage; - } } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 82f59d98e7..d26f5b9358 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -8,7 +8,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; import com.github.doomsdayrs.apps.shosetsu.backend.Download_Manager; import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.Update; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; @@ -479,28 +478,6 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { } } - /** - * Adds chapter to database - * - * @param novelURL novelURL - * @param chapter serialized chapterData - */ - public static void addToChapters(String novelURL, String chapterURL, String chapter) { - sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + "(" + - Columns.NOVEL_URL + "," + - Columns.CHAPTER_URL + "," + - Columns.SAVED_DATA + "," + - Columns.Y + "," + - Columns.READ_CHAPTER + "," + - Columns.BOOKMARKED + "," + - Columns.IS_SAVED + ") " + - "values ('" + - novelURL + "','" + - chapterURL + "','" + - chapter + "'," + - 0 + "," + 0 + "," + 0 + "," + 0 + ")"); - } - /** * Gets chapters of a novel * From 65282a939553bed7d8a351f220e4013b63d31e24 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 12 Oct 2019 14:21:14 -0400 Subject: [PATCH 017/162] Working on DB rewrite --- app/build.gradle | 5 +- .../shosetsu/backend/database/DBHelper.java | 14 ++++- .../shosetsu/backend/database/Database.java | 17 +++--- .../backend/database/objects/DBChapter.java | 57 ------------------ .../database/objects/DBDownloadItem.java | 51 ---------------- .../backend/database/objects/DBNovel.java | 55 ------------------ .../database/objects/SUPERSERIALZIED.java | 58 ------------------- .../database/objects/SettingsSerialized.java | 56 ------------------ .../backend/database/objects/Update.java | 2 + 9 files changed, 28 insertions(+), 287 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java diff --git a/app/build.gradle b/app/build.gradle index dc9d50ee0c..47978703c2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,12 +47,12 @@ repositories { } dependencies { - implementation 'com.google.android.material:material:1.1.0-alpha10' + implementation 'com.google.android.material:material:1.1.0-beta01' implementation 'com.graphql-java:graphql-java:2019-09-07T08-08-53-173312e' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible - implementation 'com.google.android.material:material:1.1.0-alpha10' + implementation 'com.google.android.material:material:1.1.0-beta01' testImplementation 'junit:junit:4.13-beta-3' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' @@ -67,6 +67,7 @@ dependencies { //TODO GITHUB sign in to save backup data to cloud implementation 'com.github.kohsuke:github-api:github-api-1.95' + implementation 'com.github.javiersantos:AppUpdater:2.7' implementation 'us.feras.mdv:markdownview:1.1.0' implementation 'joda-time:joda-time:2.10.3' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 126a06515d..ee956245f8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -32,13 +32,25 @@ public class DBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "database.db"; + private static final String NOVEL_IDENTIFICATION_CREATE = "create table if not exists " + Tables.NOVEL_IDENTIFICATION + "(" + + Columns.URL + " text not null primary key," + + Columns.ID + " integer not null autoincrement," + + Columns.FORMATTER_ID + " integer not null" + + ")"; + + private static final String CHAPTER_IDENTIFICATION_CREATE = "create table if not exists " + Tables.CHAPTER_IDENTIFICATION + "(" + + Columns.URL + " text not null primary key," + + Columns.ID + " integer not null autoincrement," + + Columns.FORMATTER_ID + " integer not null" + + ")"; + private static final String CHAPTERS_CREATE = "create table if not exists " + Tables.CHAPTERS + "(" + // Novel URL this chapter belongs to Columns.NOVEL_URL + " text not null," + // The chapter chapterURL Columns.CHAPTER_URL + " text not null unique," + - Columns.SAVED_DATA + " text," + + Columns.NOVEL_CHAPTER + " text," + // Saved Data // > Scroll position, either 0 for top, or X for the position diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index d26f5b9358..9798141863 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -69,6 +69,8 @@ public class Database { * Tables to work with */ public enum Tables { + NOVEL_IDENTIFICATION("novel_identification"), + CHAPTER_IDENTIFICATION("chapter_identification"), NOVELS("novels"), UPDATES("updates"), DOWNLOADS("downloads"), @@ -92,11 +94,12 @@ public String toString() { * Columns to work with */ public enum Columns { - MAX_PAGE("maxPage"), + URL("url"), + ID("id"), CHAPTER_URL("chapterURL"), NOVEL_URL("novelURL"), NOVEL_PAGE("novelPage"), - SAVED_DATA("savedData"), + NOVEL_CHAPTER("novel_chaper"), FORMATTER_ID("formatterID"), READ_CHAPTER("read"), Y("y"), @@ -463,7 +466,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + "(" + Columns.NOVEL_URL + "," + Columns.CHAPTER_URL + "," + - Columns.SAVED_DATA + "," + + Columns.NOVEL_CHAPTER + "," + Columns.Y + "," + Columns.READ_CHAPTER + "," + Columns.BOOKMARKED + "," + @@ -485,7 +488,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { * @return List of chapters saved of novel */ public static List getChapters(String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.SAVED_DATA + " from " + Tables.CHAPTERS + " where " + Columns.NOVEL_URL + " ='" + novelURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.NOVEL_URL + " ='" + novelURL + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -493,7 +496,7 @@ public static List getChapters(String novelURL) { ArrayList novelChapters = new ArrayList<>(); while (cursor.moveToNext()) { try { - String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); + String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_CHAPTER.toString())); if (text != null) { novelChapters.add(deserializeNovelChapterJSON(text)); } @@ -507,7 +510,7 @@ public static List getChapters(String novelURL) { } public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.SAVED_DATA + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " ='" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " ='" + chapterURL + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -515,7 +518,7 @@ public static NovelChapter getChapter(String chapterURL) { NovelChapter novelChapters = null; try { cursor.moveToNext(); - String text = cursor.getString(cursor.getColumnIndex(Columns.SAVED_DATA.toString())); + String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_CHAPTER.toString())); cursor.close(); if (text != null) { novelChapters = deserializeNovelChapterJSON(text); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java deleted file mode 100644 index 5b8b265bb8..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBChapter.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class DBChapter extends BaseChapter { - public final String SAVED_DATA; - public final int Y; - public final int READ_CHAPTER; - public final boolean BOOKMARKED; - public final boolean IS_SAVED; - public final String SAVE_PATH; - - public DBChapter(String novel_url, String chapter_url, String saved_data, int y, int read_chapter, boolean bookmarked, boolean is_saved, String save_path) { - super(novel_url, chapter_url); - SAVED_DATA = saved_data; - Y = y; - READ_CHAPTER = read_chapter; - BOOKMARKED = bookmarked; - IS_SAVED = is_saved; - SAVE_PATH = save_path; - } - - @Override - public String toString() { - return "Chapter{" + - "SAVED_DATA='" + SAVED_DATA + '\'' + - ", Y='" + Y + '\'' + - ", READ_CHAPTER=" + READ_CHAPTER + - ", BOOKMARKED=" + BOOKMARKED + - ", IS_SAVED=" + IS_SAVED + - ", SAVE_PATH='" + SAVE_PATH + '\'' + - ", CHAPTER_URL='" + CHAPTER_URL + '\'' + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java deleted file mode 100644 index 1057e343a5..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBDownloadItem.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */public class DBDownloadItem extends BaseChapter { - public final int FORMATTER_ID; - public final String NOVEL_NAME; - public final String CHAPTER_NAME; - public final boolean PAUSED; - - public DBDownloadItem(String novel_url, String chapter_url, int formatter_id, String novel_name, String chapter_name, boolean paused) { - super(novel_url, chapter_url); - FORMATTER_ID = formatter_id; - NOVEL_NAME = novel_name; - CHAPTER_NAME = chapter_name; - PAUSED = paused; - } - - - @Override - public String toString() { - return "Download{" + - "FORMATTER_ID=" + FORMATTER_ID + - ", NOVEL_NAME='" + NOVEL_NAME + '\'' + - ", CHAPTER_NAME='" + CHAPTER_NAME + '\'' + - ", PAUSED=" + PAUSED + - ", CHAPTER_URL='" + CHAPTER_URL + '\'' + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java deleted file mode 100644 index 1b2b225557..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/DBNovel.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.Base; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class DBNovel extends Base { - public final boolean BOOKMARKED; - - /** - * Serialized NovelPage object in string form, must be deserialized for use - */ - public final String NOVEL_PAGE; - - public final int FORMATTER_ID; - public final int STATUS; - - public DBNovel(String novel_url, boolean bookmarked, String novel_page, int formatter_id, int status) { - super(novel_url); - BOOKMARKED = bookmarked; - NOVEL_PAGE = novel_page; - FORMATTER_ID = formatter_id; - STATUS = status; - } - - @Override - public String toString() { - return "Library{" + - "BOOKMARKED=" + BOOKMARKED + - ", NOVEL_PAGE='" + NOVEL_PAGE + '\'' + - ", FORMATTER_ID=" + FORMATTER_ID + - ", STATUS=" + STATUS + - ", NOVEL_URL='" + NOVEL_URL + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java deleted file mode 100644 index 52aa3f5d1b..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SUPERSERIALZIED.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; - -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class SUPERSERIALZIED implements Serializable { - public final ArrayList libraries = new ArrayList<>(); - public final ArrayList DBChapters = new ArrayList<>(); - public final ArrayList DBDownloadItems = new ArrayList<>(); - - @Deprecated - public final ArrayList updates = new ArrayList<>(); - public final SettingsSerialized settingsSerialized = new SettingsSerialized(); - - @Override - public String toString() { - return "SUPERSERIALZIED{" + - "libraries=" + libraries + - ", chapters=" + DBChapters + - ", downloads=" + DBDownloadItems + - ", updates=" + updates + - ", settings=" + settingsSerialized + - '}'; - } - - public String serialize() { - try { - return Database.serialize(this); - } catch (IOException e) { - e.printStackTrace(); - } - return "FUCK_UP"; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java deleted file mode 100644 index 665c26ec4b..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/SettingsSerialized.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; - -import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.variables.Settings; - -import org.jetbrains.annotations.NotNull; - -import java.io.Serializable; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * shosetsu - * 27 / 07 / 2019 - * - * @author github.com/doomsdayrs - */ -public class SettingsSerialized implements Serializable { - public int reader_text_color = Settings.ReaderTextColor; - public int reader_text_background_color = Settings.ReaderTextBackgroundColor; - public String shoDir = Utilities.shoDir; - public boolean paused = Settings.downloadPaused; - public float textSize = Settings.ReaderTextSize; - public int themeMode = Settings.themeMode; - public int paraSpace = Settings.paragraphSpacing; - public int indent = Settings.indentSize; - public boolean tap_to_scroll = Utilities.isTapToScroll(); - - @NotNull - @Override - public String toString() { - return "SettingsSerialized{" + - "reader_text_color=" + reader_text_color + - ", reader_text_background_color=" + reader_text_background_color + - ", shoDir='" + shoDir + '\'' + - ", paused=" + paused + - ", textSize=" + textSize + - ", themeMode=" + themeMode + - ", paraSpace=" + paraSpace + - ", indent=" + indent + - '}'; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java index 77936a53d5..0f92283d54 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java @@ -1,5 +1,6 @@ package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; /* @@ -29,5 +30,6 @@ public class Update extends BaseChapter { public Update(String novel_url, String chapter_url, long time) { super(novel_url, chapter_url); this.time = time; + NovelChapter novelChapter; } } From 2d9a847920f5eefcbd32ee0175897de0f78316e3 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 12 Oct 2019 17:39:01 -0400 Subject: [PATCH 018/162] NonFunctioningCommit, Working on DB rework --- .../shosetsu/backend/database/DBHelper.java | 63 ++++--- .../shosetsu/backend/database/Database.java | 161 +++++++++++++++--- .../backend/database/objects/Update.java | 2 - .../catalogue/adapters/CatalogueAdapter.java | 2 +- .../catalogue/async/NovelBackgroundAdd.java | 8 +- .../shosetsu/ui/library/LibraryFragment.java | 6 +- .../shosetsu/ui/migration/async/Transfer.java | 2 +- .../apps/shosetsu/ui/novel/NovelFragment.java | 6 +- .../shosetsu/ui/novel/async/NovelLoader.java | 8 +- .../NovelFragmentMainAddToLibrary.java | 8 +- .../ui/novel/pages/NovelFragmentChapters.java | 2 +- .../ui/novel/pages/NovelFragmentMain.java | 4 +- .../backup/async/BackupProcess.java | 6 +- .../shosetsu/ui/updates/UpdatesFragment.java | 2 +- .../adapters/UpdatedChaptersAdapter.java | 4 +- .../viewHolder/UpdatedChapterHolder.java | 4 +- 16 files changed, 206 insertions(+), 82 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index ee956245f8..4059a80512 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -33,57 +33,67 @@ public class DBHelper extends SQLiteOpenHelper { private static final String NOVEL_IDENTIFICATION_CREATE = "create table if not exists " + Tables.NOVEL_IDENTIFICATION + "(" + - Columns.URL + " text not null primary key," + - Columns.ID + " integer not null autoincrement," + + Columns.ID + " integer primary key autoincrement," + + Columns.URL + " text unique not null," + Columns.FORMATTER_ID + " integer not null" + ")"; private static final String CHAPTER_IDENTIFICATION_CREATE = "create table if not exists " + Tables.CHAPTER_IDENTIFICATION + "(" + - Columns.URL + " text not null primary key," + - Columns.ID + " integer not null autoincrement," + - Columns.FORMATTER_ID + " integer not null" + + Columns.ID + " integer primary key autoincrement," + + + // Refers to NOVEL + Columns.PARENT_ID + " integer not null," + + Columns.URL + " text unique not null" + ")"; + private static final String CHAPTERS_CREATE = "create table if not exists " + Tables.CHAPTERS + "(" + - // Novel URL this chapter belongs to - Columns.NOVEL_URL + " text not null," + - // The chapter chapterURL - Columns.CHAPTER_URL + " text not null unique," + + // Refers to CHAPERID + Columns.PARENT_ID + " integer primary key," + - Columns.NOVEL_CHAPTER + " text," + + Columns.TITLE + " text," + + Columns.RELEASE_DATE + " text," + - // Saved Data // > Scroll position, either 0 for top, or X for the position Columns.Y + " integer not null," + // > Either 0 for none, or an incremented count (Status) Columns.READ_CHAPTER + " integer not null," + // > Either 0 for false or 1 for true. - Columns.BOOKMARKED + " integer not null," + + Columns.BOOKMARKED + " integer not null," + // If 1 then true and SAVE_PATH has data, false otherwise Columns.IS_SAVED + " integer not null," + - Columns.SAVE_PATH + " text)"; + Columns.SAVE_PATH + " text" + + ")"; //TODO Figure out a legitimate way to structure all this data // Library that the user has saved their novels to private static final String NOVELS = "create TABLE if not exists " + Tables.NOVELS + " (" + + // Refers to NOVELID + Columns.PARENT_ID + " integer not null," + // If in the library Columns.BOOKMARKED + " integer not null," + - // URL of this novel - Columns.NOVEL_URL + " text not null unique, " + - // Saved DATA of the novel - Columns.NOVEL_PAGE + " text not null," + - // Formatter this novel comes from - Columns.FORMATTER_ID + " integer not null," + - Columns.STATUS + " integer not null" + ")"; + Columns.READING_STATUS + " text," + + + // This bulk is the data values + Columns.TITLE + " text," + + Columns.IMAGE_URL + " text," + + Columns.DESCRIPTION + " text," + + Columns.GENRES + " text," + + Columns.AUTHORS + " text," + + Columns.STATUS + " integer not null," + + Columns.TAGS + " text," + + Columns.ARTISTS + " text," + + Columns.LANGUAGE + " text," + + Columns.MAX_CHAPTER_PAGE + " integer" + + ")"; // Watches download listing private static final String DOWNLOADS_CREATE = "create TABLE if not exists " + Tables.DOWNLOADS + "(" + - Columns.FORMATTER_ID + " integer not null," + - Columns.NOVEL_URL + " text not null," + - Columns.CHAPTER_URL + " text not null," + + // Refers to CHAPERID + Columns.PARENT_ID + " integer not null," + Columns.NOVEL_NAME + " text not null," + Columns.CHAPTER_NAME + " text not null," + @@ -94,8 +104,8 @@ public class DBHelper extends SQLiteOpenHelper { Columns.PAUSED + " integer not null)"; private static final String UPDATES_CREATE = "create table if not exists " + Tables.UPDATES + "(" + - Columns.NOVEL_URL + " text not null," + - Columns.CHAPTER_URL + " text not null unique," + + // Refers to CHAPERID + Columns.PARENT_ID + " integer not null," + Columns.TIME + " integer not null" + ")"; /** @@ -136,6 +146,9 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + Tables.DOWNLOADS); db.execSQL("DROP TABLE IF EXISTS " + Tables.UPDATES); + db.execSQL(NOVEL_IDENTIFICATION_CREATE); + db.execSQL(CHAPTER_IDENTIFICATION_CREATE); + db.execSQL(NOVELS); db.execSQL(DOWNLOADS_CREATE); db.execSQL(CHAPTERS_CREATE); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 9798141863..a9009c85b3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -95,11 +95,24 @@ public String toString() { */ public enum Columns { URL("url"), + PARENT_ID("parent_id"), ID("id"), - CHAPTER_URL("chapterURL"), - NOVEL_URL("novelURL"), - NOVEL_PAGE("novelPage"), - NOVEL_CHAPTER("novel_chaper"), + + + TITLE("title"), + IMAGE_URL("image_url"), + DESCRIPTION("description"), + GENRES("genres"), + AUTHORS("authors"), + STATUS("status"), + TAGS("tags"), + ARTISTS("artists"), + LANGUAGE("language"), + MAX_CHAPTER_PAGE("max_chapter_page"), + + RELEASE_DATE("release_date"), + + FORMATTER_ID("formatterID"), READ_CHAPTER("read"), Y("y"), @@ -109,7 +122,7 @@ public enum Columns { NOVEL_NAME("novelName"), CHAPTER_NAME("chapterName"), PAUSED("paused"), - STATUS("status"), + READING_STATUS("reading_status"), TIME("time"); final String COLUMN; @@ -155,6 +168,112 @@ public static Object deserialize(@NotNull String string) throws IOException, Cla return object; } + public static class DatabaseIdentification { + + /** + * @param url NovelURL + * @return NovelID + */ + public static int getNovelIDFromNovelURL(String url) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " = " + url + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + return 0; + } else { + cursor.moveToNext(); + int id = cursor.getInt(cursor.getColumnIndex(Columns.ID.toString())); + cursor.close(); + return id; + } + } + + /** + * @param url ChapterURL + * @return ChapterID + */ + public static int getChapterIDFromChapterURL(String url) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.URL + " = " + url + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + return 0; + } else { + cursor.moveToNext(); + int id = cursor.getInt(cursor.getColumnIndex(Columns.ID.toString())); + cursor.close(); + return id; + } + } + + + /** + * @param id ChapterID + * @return ChapterURL + */ + public static String getChapterURLFromChapterID(int id) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.URL + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + } else { + cursor.moveToNext(); + String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); + cursor.close(); + try { + return (String) Database.deserialize(serial); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * @param id ChapterID + * @return NovelID + */ + public static int getNovelIDFromChapterID(int id) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.PARENT_ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + return 0; + } else { + cursor.moveToNext(); + int parent = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); + cursor.close(); + return parent; + } + } + + /** + * @param id Chapter ID + * @return Chapter URL + */ + public static String getNovelURLFromChapterID(int id) { + return getNovelURLfromNovelID(getNovelIDFromChapterID(id)); + } + + /** + * @param id NovelID + * @return NovelURL + */ + public static String getNovelURLfromNovelID(int id) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.URL + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + } else { + cursor.moveToNext(); + String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); + cursor.close(); + try { + return (String) Database.deserialize(serial); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + return null; + } + } + + public static class DatabaseDownloads { /** * Gets downloads that are stored @@ -163,15 +282,13 @@ public static class DatabaseDownloads { */ public static List getDownloadList() { ArrayList downloadItems = new ArrayList<>(); - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + "," + Columns.NOVEL_URL + "," + Columns.CHAPTER_URL + "," + Columns.NOVEL_NAME + "," + Columns.CHAPTER_NAME + " from " + Tables.DOWNLOADS + ";", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT * from " + Tables.DOWNLOADS + ";", null); while (cursor.moveToNext()) { - String nURL = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())); - String cURL = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_URL.toString())); + int id = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); String nName = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_NAME.toString())); String cName = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_NAME.toString())); int formatter = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); - - downloadItems.add(new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, nURL, cURL)); + downloadItems.add(new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, DatabaseIdentification.getNovelURLFromChapterID(id), DatabaseIdentification.getChapterURLFromChapterID(id))); } cursor.close(); @@ -184,20 +301,18 @@ public static List getDownloadList() { * @return DownloadItem to download */ public static DownloadItem getFirstDownload() { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + "," + Columns.NOVEL_URL + "," + Columns.CHAPTER_URL + "," + Columns.NOVEL_NAME + "," + Columns.CHAPTER_NAME + " from " + Tables.DOWNLOADS + " LIMIT 1;", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT * from " + Tables.DOWNLOADS + " LIMIT 1;", null); if (cursor.getCount() <= 0) { cursor.close(); return null; } else { cursor.moveToNext(); - - String nURL = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())); - String cURL = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_URL.toString())); + int id = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); String nName = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_NAME.toString())); String cName = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_NAME.toString())); int formatter = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); cursor.close(); - return new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, nURL, cURL); + return new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, DatabaseIdentification.getNovelURLFromChapterID(id), DatabaseIdentification.getChapterURLFromChapterID(id)); } } @@ -208,7 +323,7 @@ public static DownloadItem getFirstDownload() { * @return if removed */ public static boolean removeDownload(DownloadItem downloadItem) { - return sqLiteDatabase.delete(Tables.DOWNLOADS.toString(), Columns.CHAPTER_URL + "='" + downloadItem.chapterURL + "'", null) > 0; + return sqLiteDatabase.delete(Tables.DOWNLOADS.toString(), Columns.PARENT_ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null) > 0; } /** @@ -219,15 +334,13 @@ public static boolean removeDownload(DownloadItem downloadItem) { public static void addToDownloads(DownloadItem downloadItem) { sqLiteDatabase.execSQL("insert into " + Tables.DOWNLOADS + " (" + Columns.FORMATTER_ID + "," + - Columns.NOVEL_URL + "," + - Columns.CHAPTER_URL + "," + + Columns.PARENT_ID + "," + Columns.NOVEL_NAME + "," + Columns.CHAPTER_NAME + "," + Columns.PAUSED + ") " + "values (" + - downloadItem.formatter.getID() + ",'" + - downloadItem.novelURL + "','" + - downloadItem.chapterURL + "','" + + downloadItem.formatter.getID() + "," + + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + ",'" + DownloadItem.cleanse(downloadItem.novelName) + "','" + DownloadItem.cleanse(downloadItem.chapterName) + "'," + 0 + ")"); } @@ -239,7 +352,7 @@ public static void addToDownloads(DownloadItem downloadItem) { * @return if is in list */ public static boolean inDownloads(DownloadItem downloadItem) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.CHAPTER_URL + " from " + Tables.DOWNLOADS + " where " + Columns.CHAPTER_URL + " = '" + downloadItem.chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.PARENT_ID + " from " + Tables.DOWNLOADS + " where " + Columns.PARENT_ID + " = " + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null); int a = cursor.getCount(); cursor.close(); return !(a <= 0); @@ -544,7 +657,7 @@ public static String getChapterNovelURL(String chapterURL) { } } - public static class DatabaseLibrary { + public static class DatabaseNovels { /** * Bookmarks the novel @@ -755,7 +868,7 @@ public static void updateData(@NotNull String novelURL, @NotNull NovelPage novel public static void migrateNovel(@NotNull String oldURL, @NotNull String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { unBookmark(oldURL); - if (!Database.DatabaseLibrary.inLibrary(newURL)) + if (!DatabaseNovels.inLibrary(newURL)) addToLibrary(formatterID, newNovel, newURL, status); bookMark(newURL); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java index 0f92283d54..77936a53d5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java @@ -1,6 +1,5 @@ package com.github.doomsdayrs.apps.shosetsu.backend.database.objects; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base.BaseChapter; /* @@ -30,6 +29,5 @@ public class Update extends BaseChapter { public Update(String novel_url, String chapter_url, long time) { super(novel_url, chapter_url); this.time = time; - NovelChapter novelChapter; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java index aab29e108d..590439337b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java @@ -77,7 +77,7 @@ public void onBindViewHolder(@NonNull NovelCardViewHolder novelCardsViewHolder, } else novelCardsViewHolder.library_card_image.setVisibility(View.GONE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (Database.DatabaseLibrary.isBookmarked(recycleCard.novelURL)) { + if (Database.DatabaseNovels.isBookmarked(recycleCard.novelURL)) { if (catalogueFragment.getContext() != null) novelCardsViewHolder.constraintLayout.setForeground(new ColorDrawable(ContextCompat.getColor(catalogueFragment.getContext(), R.color.shade))); } else novelCardsViewHolder.constraintLayout.setForeground(new ColorDrawable()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index 74a8e2a88a..9f35a48623 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -39,16 +39,16 @@ public NovelBackgroundAdd(NovelCardViewHolder novelCardsViewHolder) { @Override protected Void doInBackground(View... views) { try { - if (!Database.DatabaseLibrary.inLibrary(novelCardsViewHolder.url)) { - Database.DatabaseLibrary.addToLibrary(novelCardsViewHolder.formatter.getID(), novelCardsViewHolder.formatter.parseNovel(novelCardsViewHolder.url), novelCardsViewHolder.url, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); + if (!Database.DatabaseNovels.inLibrary(novelCardsViewHolder.url)) { + Database.DatabaseNovels.addToLibrary(novelCardsViewHolder.formatter.getID(), novelCardsViewHolder.formatter.parseNovel(novelCardsViewHolder.url), novelCardsViewHolder.url, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } - if (Database.DatabaseLibrary.isBookmarked(novelCardsViewHolder.url)) { + if (Database.DatabaseNovels.isBookmarked(novelCardsViewHolder.url)) { if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Already in the library", Toast.LENGTH_SHORT).show()); } else { - Database.DatabaseLibrary.bookMark(novelCardsViewHolder.url); + Database.DatabaseNovels.bookMark(novelCardsViewHolder.url); if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 4952e34f40..5e9d30b364 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -84,7 +84,7 @@ public LibraryFragment() { } private void readFromDB() { - libraryNovelCards = Database.DatabaseLibrary.getLibrary(); + libraryNovelCards = Database.DatabaseNovels.getLibrary(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { libraryNovelCards.sort((novelCard, t1) -> novelCard.title.compareTo(t1.title)); } else { @@ -145,7 +145,7 @@ public void onResume() { Log.d("Library", "Resumed"); if (LibraryFragment.changedData) { Log.d("Library", "Updating data"); - libraryNovelCards = Database.DatabaseLibrary.getLibrary(); + libraryNovelCards = Database.DatabaseNovels.getLibrary(); changedData = !changedData; } libraryNovelCardsAdapter.notifyDataSetChanged(); @@ -232,7 +232,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.remove_from_library: for (NovelCard novelCard : selectedNovels) { - Database.DatabaseLibrary.unBookmark(novelCard.novelURL); + Database.DatabaseNovels.unBookmark(novelCard.novelURL); libraryNovelCards.remove(novelCard); } selectedNovels = new ArrayList<>(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java index b57cfd0589..2e34790598 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java @@ -116,7 +116,7 @@ protected Void doInBackground(Void... voids) { } if (C) { migrationView.pageCount.post(() -> migrationView.pageCount.setText("")); - Database.DatabaseLibrary.migrateNovel(strings[0], strings[1], formatter.getID(), novelPage, Database.DatabaseLibrary.getStatus(strings[0]).getA()); + Database.DatabaseNovels.migrateNovel(strings[0], strings[1], formatter.getID(), novelPage, Database.DatabaseNovels.getStatus(strings[0]).getA()); } } catch (IOException e) { if (e.getMessage() != null) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 04e54b0d57..6baeae7779 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -103,7 +103,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c //boolean track = SettingsController.isTrackingEnabled(); if (savedInstanceState == null) { - if (isOnline() && !Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) { + if (isOnline() && !Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { setViewPager(); if (StaticNovel.novelLoader != null && !StaticNovel.novelLoader.isCancelled()) { @@ -114,8 +114,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c StaticNovel.novelLoader.execute(getActivity()); } else { - StaticNovel.novelPage = Database.DatabaseLibrary.getNovelPage(StaticNovel.novelURL); - StaticNovel.status = Database.DatabaseLibrary.getStatus(StaticNovel.novelURL); + StaticNovel.novelPage = Database.DatabaseNovels.getNovelPage(StaticNovel.novelURL); + StaticNovel.status = Database.DatabaseNovels.getStatus(StaticNovel.novelURL); if (StaticNovel.novelPage != null) Statics.mainActionBar.setTitle(StaticNovel.novelPage.title); setViewPager(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 483b66e6f8..650fa6e387 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -95,8 +95,8 @@ protected Boolean doInBackground(Activity... voids) { try { StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL); - if (C && !Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) { - Database.DatabaseLibrary.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); + if (C && !Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { + Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } for (NovelChapter novelChapter : StaticNovel.novelPage.novelChapters) if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) @@ -170,9 +170,9 @@ protected void onPostExecute(Boolean aBoolean) { } else { assert novelFragmentMain != null; novelFragmentMain.swipeRefreshLayout.setRefreshing(false); - if (Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { try { - Database.DatabaseLibrary.updateData(StaticNovel.novelURL, StaticNovel.novelPage); + Database.DatabaseNovels.updateData(StaticNovel.novelURL, StaticNovel.novelPage); } catch (Exception e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java index 801a033358..69077b3e05 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java @@ -39,13 +39,13 @@ public NovelFragmentMainAddToLibrary(NovelFragmentMain novelFragmentMain) { @Override public void onClick(View v) { if (!novelFragmentMain.inLibrary) { - if (!Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) - Database.DatabaseLibrary.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, StaticNovel.status.getA()); - Database.DatabaseLibrary.bookMark(StaticNovel.novelURL); + if (!Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) + Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, StaticNovel.status.getA()); + Database.DatabaseNovels.bookMark(StaticNovel.novelURL); novelFragmentMain.inLibrary = true; novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); } else { - Database.DatabaseLibrary.unBookmark(StaticNovel.novelURL); + Database.DatabaseNovels.unBookmark(StaticNovel.novelURL); novelFragmentMain.inLibrary = false; novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_outline_black_24dp); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 316cee6a69..aa02f7add8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -205,7 +205,7 @@ public void setNovels() { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); - if (Database.DatabaseLibrary.inLibrary(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { StaticNovel.novelChapters = Database.DatabaseChapter.getChapters(StaticNovel.novelURL); if (StaticNovel.novelChapters != null && StaticNovel.novelChapters.size() != 0) resumeRead.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index 609a44be9e..810a524d57 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -123,7 +123,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.toolbar_novel, menu); - if (Database.DatabaseLibrary.isBookmarked(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.isBookmarked(StaticNovel.novelURL)) { menu.findItem(R.id.source_migrate).setVisible(true); } else menu.findItem(R.id.source_migrate).setVisible(false); @@ -173,7 +173,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c floatingActionButton.hide(); - if (Database.DatabaseLibrary.isBookmarked(StaticNovel.novelURL)) + if (Database.DatabaseNovels.isBookmarked(StaticNovel.novelURL)) inLibrary(); if (inLibrary) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index f61e81cbb2..5d2373ce61 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -113,18 +113,18 @@ protected Void doInBackground(Void... voids) { while (cursor.moveToNext()) { String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - boolean inLibrary = Database.DatabaseLibrary.isBookmarked(nurl); + boolean inLibrary = Database.DatabaseNovels.isBookmarked(nurl); if (inLibrary) { String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); // very dirty logger //Log.i("ChapterBack", curl); - String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); + String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_CHAPTER.toString())); int y = cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString())); int read_chapter = cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString())); boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); boolean is_saved = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.IS_SAVED.toString()))); - String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVED_DATA.toString())); + String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVE_PATH.toString())); JSONObject chapter = new JSONObject(); chapter.put("novelURL", Database.serialize(nurl)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java index 4a78dd6c66..36ba883a1c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java @@ -66,7 +66,7 @@ public UpdatesFragment() { public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.updater_now: - Update_Manager.init(Database.DatabaseLibrary.getLibrary(), getContext()); + Update_Manager.init(Database.DatabaseNovels.getLibrary(), getContext()); return true; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index 339b1be031..de56a7e57d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -83,14 +83,14 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, String nURL = DatabaseChapter.getChapterNovelURL(updatedChapterHolder.novelChapter.link); if (nURL != null) - novelPage = Database.DatabaseLibrary.getNovelPage(nURL); + novelPage = Database.DatabaseNovels.getNovelPage(nURL); if (novelPage == null) { Log.e("DatabaseError", "No such novel in DB"); System.exit(-1); } - Formatter formatter = Database.DatabaseLibrary.getFormat(nURL); + Formatter formatter = Database.DatabaseNovels.getFormat(nURL); if (novelPage != null) switch (menuItem.getItemId()) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 6fa86883f1..5b7e063064 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -71,7 +71,7 @@ public void setNovelChapter(NovelChapter novelChapter) { Picasso.get() .load( Objects.requireNonNull( - Database.DatabaseLibrary.getNovel( + Database.DatabaseNovels.getNovel( Database.DatabaseChapter.getChapterNovelURL(novelChapter.link) ) ).imageURL) @@ -82,7 +82,7 @@ public void setNovelChapter(NovelChapter novelChapter) { @Override public void onClick(View view) { String nurl = Database.DatabaseChapter.getChapterNovelURL(novelChapter.link); - Formatter formatter = Database.DatabaseLibrary.getFormat(nurl); + Formatter formatter = Database.DatabaseNovels.getFormat(nurl); if (formatter != null) openChapter((Activity) itemView.getContext(), novelChapter, nurl, formatter.getID()); } From 92fe1ae918016131ec043418bd59e340d75103b8 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 13 Oct 2019 14:40:50 -0400 Subject: [PATCH 019/162] More effort put in --- .../apps/shosetsu/backend/Serialize.java | 44 ++-- .../apps/shosetsu/backend/Utilities.java | 42 ++-- .../shosetsu/backend/database/DBHelper.java | 5 +- .../shosetsu/backend/database/Database.java | 202 ++++++++++-------- .../shosetsu/ui/library/LibraryFragment.java | 2 +- .../shosetsu/ui/migration/MigrationView.java | 2 +- .../ui/novel/pages/NovelFragmentMain.java | 2 +- .../backup/async/BackupProcess.java | 8 +- 8 files changed, 169 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index 5757aa1e34..5fbcec2a21 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -14,8 +14,8 @@ import java.util.ArrayList; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserializeString; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serializeToString; /* * This file is part of shosetsu-services. @@ -54,34 +54,34 @@ public static void toggleDebug() { public static String serializeOBJECT(Object object) throws Exception { if (object.getClass().equals(NovelChapter.class)) { NovelChapter novelChapter = (NovelChapter) object; - return serialize(novelChapterToJSON(novelChapter).toString()); + return serializeToString(novelChapterToJSON(novelChapter).toString()); } else if (object.getClass().equals(NovelPage.class)) { NovelPage novelPage = (NovelPage) object; JSONObject jsonObject = new JSONObject(); if (novelPage.title != null) - jsonObject.put("title", serialize(novelPage.title)); + jsonObject.put("title", serializeToString(novelPage.title)); else jsonObject.put("title", "null"); if (novelPage.imageURL != null) - jsonObject.put("imageURL", serialize(novelPage.imageURL)); + jsonObject.put("imageURL", serializeToString(novelPage.imageURL)); else jsonObject.put("imageURL", "null"); if (novelPage.description != null) - jsonObject.put("description", serialize(novelPage.description)); + jsonObject.put("description", serializeToString(novelPage.description)); else jsonObject.put("description", "null"); if (novelPage.genres != null) { JSONArray jsonArray = new JSONArray(); for (String genre : novelPage.genres) - jsonArray.put(serialize(genre)); + jsonArray.put(serializeToString(genre)); jsonObject.put("genres", jsonArray); } else jsonObject.put("genres", new JSONArray()); if (novelPage.authors != null) { JSONArray jsonArray = new JSONArray(); for (String author : novelPage.authors) - jsonArray.put(serialize(author)); + jsonArray.put(serializeToString(author)); jsonObject.put("authors", jsonArray); } else jsonObject.put("authors", new JSONArray()); @@ -92,19 +92,19 @@ public static String serializeOBJECT(Object object) throws Exception { if (novelPage.tags != null) { JSONArray jsonArray = new JSONArray(); for (String tag : novelPage.tags) - jsonArray.put(serialize(tag)); + jsonArray.put(serializeToString(tag)); jsonObject.put("tags", jsonArray); } else jsonObject.put("tags", new JSONArray()); if (novelPage.artists != null) { JSONArray jsonArray = new JSONArray(); for (String artist : novelPage.artists) - jsonArray.put(serialize(artist)); + jsonArray.put(serializeToString(artist)); jsonObject.put("artists", jsonArray); } else jsonObject.put("artists", new JSONArray()); if (novelPage.language != null) { - jsonObject.put("language", serialize(novelPage.language)); + jsonObject.put("language", serializeToString(novelPage.language)); } else jsonObject.put("language", "null"); jsonObject.put("maxChapterPage", novelPage.maxChapterPage); @@ -112,14 +112,14 @@ public static String serializeOBJECT(Object object) throws Exception { if (novelPage.novelChapters != null) { JSONArray jsonArray = new JSONArray(); for (NovelChapter novelChapter : novelPage.novelChapters) - jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); + jsonArray.put(serializeToString(novelChapterToJSON(novelChapter).toString())); jsonObject.put("novelChapters", jsonArray); } else jsonObject.put("novelChapters", new JSONArray()); if (debug) System.out.println("JSON to be serialized: " + jsonObject.toString()); - return serialize(jsonObject.toString()); + return serializeToString(jsonObject.toString()); } else throw new Exception("Illegal class"); } @@ -132,7 +132,7 @@ public static String serializeOBJECT(Object object) throws Exception { */ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { NovelPage novelPage = new NovelPage(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); if (debug) System.out.println("Deserialize-d json: " + jsonObject); for (String key : NOVELPAGEKEYS) { @@ -169,7 +169,7 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception String[] strings = new String[array.length()]; for (int x = 0; x < array.length(); x++) { String s = array.getString(x); - strings[x] = (String) deserialize(s); + strings[x] = (String) deserializeString(s); } switch (key) { case "genres": @@ -199,7 +199,7 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception if (!response.equals("null")) { if (debug) System.out.println("Serial response of novelChapter key [" + key + "]: " + response); - response = (String) deserialize(response); + response = (String) deserializeString(response); } switch (key) { case "title": @@ -238,12 +238,12 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception */ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { NovelChapter novelChapter = new NovelChapter(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); for (String key : NOVELCHAPTERKEYS) { if (!jsonObject.has(key)) throw new Exception("JSON is invalid due to missing key[" + key + "]"); - String response = (String) deserialize(jsonObject.getString(key)); + String response = (String) deserializeString(jsonObject.getString(key)); switch (key) { case "release": if (response.equals("null")) @@ -275,9 +275,9 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc */ private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); - jsonObject.put("release", serialize(novelChapter.release)); - jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); - jsonObject.put("link", serialize(novelChapter.link)); + jsonObject.put("release", serializeToString(novelChapter.release)); + jsonObject.put("chapterNum", serializeToString(novelChapter.chapterNum)); + jsonObject.put("link", serializeToString(novelChapter.link)); return jsonObject; } @@ -292,7 +292,7 @@ public static JSONObject getSettingsInJSON() throws JSONException, IOException { JSONObject settings = new JSONObject(); settings.put("reader_text_color", Settings.ReaderTextColor); settings.put("reader_text_background_color", Settings.ReaderTextBackgroundColor); - settings.put("shoDir", Database.serialize(shoDir)); + settings.put("shoDir", Database.serializeToString(shoDir)); settings.put("paused", Settings.downloadPaused); settings.put("textSize", Settings.ReaderTextSize); settings.put("themeMode", Settings.themeMode); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index f64fee1fe9..ca9ce65eab 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -31,8 +31,8 @@ import java.util.ArrayList; import java.util.concurrent.TimeUnit; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserialize; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserializeString; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serializeToString; /* * This file is part of Shosetsu. @@ -311,34 +311,34 @@ public static void toggleDebug() { public static String serializeOBJECT(Object object) throws Exception { if (object.getClass().equals(NovelChapter.class)) { NovelChapter novelChapter = (NovelChapter) object; - return serialize(novelChapterToJSON(novelChapter).toString()); + return serializeToString(novelChapterToJSON(novelChapter).toString()); } else if (object.getClass().equals(NovelPage.class)) { NovelPage novelPage = (NovelPage) object; JSONObject jsonObject = new JSONObject(); if (novelPage.title != null) - jsonObject.put("title", serialize(novelPage.title)); + jsonObject.put("title", serializeToString(novelPage.title)); else jsonObject.put("title", "null"); if (novelPage.imageURL != null) - jsonObject.put("imageURL", serialize(novelPage.imageURL)); + jsonObject.put("imageURL", serializeToString(novelPage.imageURL)); else jsonObject.put("imageURL", "null"); if (novelPage.description != null) - jsonObject.put("description", serialize(novelPage.description)); + jsonObject.put("description", serializeToString(novelPage.description)); else jsonObject.put("description", "null"); if (novelPage.genres != null) { JSONArray jsonArray = new JSONArray(); for (String genre : novelPage.genres) - jsonArray.put(serialize(genre)); + jsonArray.put(serializeToString(genre)); jsonObject.put("genres", jsonArray); } else jsonObject.put("genres", new JSONArray()); if (novelPage.authors != null) { JSONArray jsonArray = new JSONArray(); for (String author : novelPage.authors) - jsonArray.put(serialize(author)); + jsonArray.put(serializeToString(author)); jsonObject.put("authors", jsonArray); } else jsonObject.put("authors", new JSONArray()); @@ -349,19 +349,19 @@ public static String serializeOBJECT(Object object) throws Exception { if (novelPage.tags != null) { JSONArray jsonArray = new JSONArray(); for (String tag : novelPage.tags) - jsonArray.put(serialize(tag)); + jsonArray.put(serializeToString(tag)); jsonObject.put("tags", jsonArray); } else jsonObject.put("tags", new JSONArray()); if (novelPage.artists != null) { JSONArray jsonArray = new JSONArray(); for (String artist : novelPage.artists) - jsonArray.put(serialize(artist)); + jsonArray.put(serializeToString(artist)); jsonObject.put("artists", jsonArray); } else jsonObject.put("artists", new JSONArray()); if (novelPage.language != null) { - jsonObject.put("language", serialize(novelPage.language)); + jsonObject.put("language", serializeToString(novelPage.language)); } else jsonObject.put("language", "null"); jsonObject.put("maxChapterPage", novelPage.maxChapterPage); @@ -369,20 +369,20 @@ public static String serializeOBJECT(Object object) throws Exception { if (novelPage.novelChapters != null) { JSONArray jsonArray = new JSONArray(); for (NovelChapter novelChapter : novelPage.novelChapters) - jsonArray.put(serialize(novelChapterToJSON(novelChapter).toString())); + jsonArray.put(serializeToString(novelChapterToJSON(novelChapter).toString())); jsonObject.put("novelChapters", jsonArray); } else jsonObject.put("novelChapters", new JSONArray()); if (debug) System.out.println("JSON to be serialized: " + jsonObject.toString()); - return serialize(jsonObject.toString()); + return serializeToString(jsonObject.toString()); } else throw new Exception("Illegal class"); } public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { NovelPage novelPage = new NovelPage(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); if (debug) System.out.println("Deserialize-d json: " + jsonObject); for (String key : NOVELPAGEKEYS) { @@ -419,7 +419,7 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception String[] strings = new String[array.length()]; for (int x = 0; x < array.length(); x++) { String s = array.getString(x); - strings[x] = (String) deserialize(s); + strings[x] = (String) deserializeString(s); } switch (key) { case "genres": @@ -449,7 +449,7 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception if (!response.equals("null")) { if (debug) System.out.println("Serial response of novelChapter key [" + key + "]: " + response); - response = (String) deserialize(response); + response = (String) deserializeString(response); } switch (key) { case "title": @@ -481,12 +481,12 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { NovelChapter novelChapter = new NovelChapter(); - JSONObject jsonObject = new JSONObject((String) deserialize(serial)); + JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); for (String key : NOVELCHAPTERKEYS) { if (!jsonObject.has(key)) throw new Exception("JSON is invalid due to missing key[" + key + "]"); - String response = (String) deserialize(jsonObject.getString(key)); + String response = (String) deserializeString(jsonObject.getString(key)); switch (key) { case "release": if (response.equals("null")) @@ -510,9 +510,9 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); - jsonObject.put("release", serialize(novelChapter.release)); - jsonObject.put("chapterNum", serialize(novelChapter.chapterNum)); - jsonObject.put("link", serialize(novelChapter.link)); + jsonObject.put("release", serializeToString(novelChapter.release)); + jsonObject.put("chapterNum", serializeToString(novelChapter.chapterNum)); + jsonObject.put("link", serializeToString(novelChapter.link)); return jsonObject; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 4059a80512..6ce7dbd263 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -49,7 +49,10 @@ public class DBHelper extends SQLiteOpenHelper { private static final String CHAPTERS_CREATE = "create table if not exists " + Tables.CHAPTERS + "(" + // Refers to CHAPERID - Columns.PARENT_ID + " integer primary key," + + Columns.ID + " integer primary key," + + + // Refers to NOVELID + Columns.PARENT_ID + " integer not null," + Columns.TITLE + " text," + Columns.RELEASE_DATE + " text," + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index a9009c85b3..5310cf481e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -29,7 +29,6 @@ import java.util.Calendar; import java.util.List; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelChapterJSON; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelPageJSON; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; @@ -144,7 +143,7 @@ public String toString() { * @return Serialised string * @throws IOException exception */ - public static String serialize(@NotNull Object object) throws IOException { + public static String serializeToString(@NotNull Object object) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(object); @@ -160,7 +159,7 @@ public static String serialize(@NotNull Object object) throws IOException { * @throws IOException exception * @throws ClassNotFoundException exception */ - public static Object deserialize(@NotNull String string) throws IOException, ClassNotFoundException { + public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { byte[] bytes = Base64.decode(string, Base64.NO_WRAP); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); @@ -170,6 +169,23 @@ public static Object deserialize(@NotNull String string) throws IOException, Cla public static class DatabaseIdentification { + public static void addChapter(int novelID, String chapterURL) { + try { + sqLiteDatabase.execSQL("insert into " + Tables.CHAPTER_IDENTIFICATION + "(" + + Columns.PARENT_ID + "," + + Columns.URL + + ")" + + "values" + + "('" + + novelID + "','" + + chapterURL + + ")"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** * @param url NovelURL * @return NovelID @@ -218,7 +234,7 @@ public static String getChapterURLFromChapterID(int id) { String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); try { - return (String) Database.deserialize(serial); + return (String) Database.deserializeString(serial); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } @@ -264,7 +280,7 @@ public static String getNovelURLfromNovelID(int id) { String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); try { - return (String) Database.deserialize(serial); + return (String) Database.deserializeString(serial); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } @@ -385,16 +401,11 @@ public static void purgeUneededCache() { * @return Count of chapters left to read */ public static int getCountOfChaptersUnread(String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.NOVEL_URL + "='" + novelURL + "'" + " and " + Columns.READ_CHAPTER + "!=" + Status.READ, null); - if (cursor.getCount() <= 0) { - cursor.close(); - return 0; - } else { - cursor.moveToNext(); - int count = cursor.getCount(); - cursor.close(); - return count; - } + int novelID = DatabaseIdentification.getNovelIDFromNovelURL(novelURL); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + "=" + novelID + "" + " and " + Columns.READ_CHAPTER + "!=" + Status.READ, null); + int count = cursor.getCount(); + cursor.close(); + return count; } @@ -406,8 +417,7 @@ public static int getCountOfChaptersUnread(String novelURL) { * @param y integer value scroll */ public static void updateY(String chapterURL, int y) { - Log.i("updateY", chapterURL + " := " + y); - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } @@ -416,7 +426,7 @@ public static void updateY(String chapterURL, int y) { * @return returns chapter status */ public static Status getStatus(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " = '" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return Status.UNREAD; @@ -440,7 +450,7 @@ else if (y == 1) * @param status status to be set */ public static void setChapterStatus(String chapterURL, Status status) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } /** @@ -451,7 +461,7 @@ public static void setChapterStatus(String chapterURL, Status status) { * @return if bookmarked? */ public static int getY(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " = '" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return 0; @@ -470,18 +480,18 @@ public static int getY(String chapterURL) { * @param b 1 is true, 0 is false */ public static void setBookMark(String chapterURL, int b) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.BOOKMARKED + "=" + b + " where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.BOOKMARKED + "=" + b + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } /** * is this chapter bookmarked? * - * @param url imageURL to the chapter + * @param chapterURL imageURL to the chapter * @return if bookmarked? */ - public static boolean isBookMarked(String url) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " = '" + url + "'", null); + public static boolean isBookMarked(String chapterURL) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -500,7 +510,7 @@ public static boolean isBookMarked(String url) { * @param chapterURL chapter to remove save path of */ public static void removePath(String chapterURL) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "=null," + Columns.IS_SAVED + "=0 where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "=null," + Columns.IS_SAVED + "=0 where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } /** @@ -510,7 +520,7 @@ public static void removePath(String chapterURL) { * @param chapterPath save path to set */ public static void addSavedPath(String chapterURL, String chapterPath) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "='" + chapterPath + "'," + Columns.IS_SAVED + "=1 where " + Columns.CHAPTER_URL + "='" + chapterURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "='" + chapterPath + "'," + Columns.IS_SAVED + "=1 where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } /** @@ -521,7 +531,7 @@ public static void addSavedPath(String chapterURL, String chapterPath) { */ public static boolean isSaved(String chapterURL) { // Log.d("CheckSave", chapterURL); - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + "='" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); // Log.d("CheckSave", chapterURL + " FALSE"); @@ -543,7 +553,7 @@ public static boolean isSaved(String chapterURL) { * @return String of passage */ public static String getSavedNovelPassage(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.SAVE_PATH + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + "='" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.SAVE_PATH + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -562,7 +572,7 @@ public static String getSavedNovelPassage(String chapterURL) { * @return if present */ public static boolean inChapters(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " ='" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); int a = cursor.getCount(); cursor.close(); return !(a <= 0); @@ -575,20 +585,51 @@ public static boolean inChapters(String chapterURL) { * @param novelChapter chapterURL */ public static void addToChapters(String novelURL, NovelChapter novelChapter) { + DatabaseIdentification.addChapter(DatabaseIdentification.getNovelIDFromNovelURL(novelURL), novelChapter.link); + String title = novelChapter.chapterNum; + String release = novelChapter.chapterNum; + // Formats the strings + { + if (title == null) { + title = ""; + } else { + try { + title = serializeToString(title); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (release == null) { + release = ""; + } else { + try { + release = serializeToString(release); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + try { - sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + "(" + - Columns.NOVEL_URL + "," + - Columns.CHAPTER_URL + "," + - Columns.NOVEL_CHAPTER + "," + + sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + + "(" + + Columns.ID + "," + + Columns.PARENT_ID + "," + + Columns.TITLE + "," + + Columns.RELEASE_DATE + "," + Columns.Y + "," + Columns.READ_CHAPTER + "," + Columns.BOOKMARKED + "," + - Columns.IS_SAVED + ") " + - "values ('" + - novelURL + "','" + - novelChapter.link + "','" + - serializeOBJECT(novelChapter) + "'," + - 0 + "," + 0 + "," + 0 + "," + 0 + ")"); + Columns.IS_SAVED + + ") " + + "values" + + "(" + + DatabaseIdentification.getChapterIDFromChapterURL(novelChapter.link) + "," + + DatabaseIdentification.getNovelIDFromNovelURL(novelURL) + "," + + title + "," + + release + "," + + 0 + "," + 0 + "," + 0 + "," + 0 + + ")"); } catch (Exception e) { e.printStackTrace(); } @@ -601,7 +642,8 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { * @return List of chapters saved of novel */ public static List getChapters(String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.NOVEL_URL + " ='" + novelURL + "'", null); + int novelID = DatabaseIdentification.getNovelIDFromNovelURL(novelURL); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -609,10 +651,20 @@ public static List getChapters(String novelURL) { ArrayList novelChapters = new ArrayList<>(); while (cursor.moveToNext()) { try { - String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_CHAPTER.toString())); - if (text != null) { - novelChapters.add(deserializeNovelChapterJSON(text)); + String url = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); + String text = cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString())); + if (!text.equals("")) { + text = (String) deserializeString(text); } + String release = cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString())); + if (!release.equals("")) { + release = (String) deserializeString(release); + } + NovelChapter novelChapter = new NovelChapter(); + novelChapter.chapterNum = text; + novelChapter.link = url; + novelChapter.release = release; + novelChapters.add(novelChapter); } catch (Exception e) { e.printStackTrace(); } @@ -623,36 +675,31 @@ public static List getChapters(String novelURL) { } public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " ='" + chapterURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return null; } else { - NovelChapter novelChapters = null; + NovelChapter novelChapter = null; try { - cursor.moveToNext(); - String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_CHAPTER.toString())); - cursor.close(); - if (text != null) { - novelChapters = deserializeNovelChapterJSON(text); + String url = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); + String text = cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString())); + if (!text.equals("")) { + text = (String) deserializeString(text); + } + String release = cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString())); + if (!release.equals("")) { + release = (String) deserializeString(release); } + + novelChapter = new NovelChapter(); + novelChapter.chapterNum = text; + novelChapter.link = url; + novelChapter.release = release; } catch (Exception e) { e.printStackTrace(); } - return novelChapters; - } - } - - public static String getChapterNovelURL(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.NOVEL_URL + " from " + Tables.CHAPTERS + " where " + Columns.CHAPTER_URL + " ='" + chapterURL + "'", null); - if (cursor.getCount() <= 0) { - cursor.close(); - return null; - } else { - cursor.moveToNext(); - String text = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())); - cursor.close(); - return text; + return novelChapter; } } } @@ -665,7 +712,7 @@ public static class DatabaseNovels { * @param novelURL novelURL of the novel */ public static void bookMark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL)); } /** @@ -675,11 +722,11 @@ public static void bookMark(@NotNull String novelURL) { * @return if removed successfully */ public static void unBookmark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL)); } public static boolean isBookmarked(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.NOVEL_URL + " ='" + novelURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL), null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -706,25 +753,6 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No } } - /** - * Method for restoring data - * - * @param formatter formatter ID - * @param novelPage serialized novelpage data - * @param novelURL novel url - * @param status status of novel - */ - public static void addToLibrary(int formatter, @NotNull String novelPage, @NotNull String novelURL, int status) { - sqLiteDatabase.execSQL("insert into " + Tables.NOVELS + "(" + - Columns.BOOKMARKED + ",'" + Columns.NOVEL_URL + "'," + Columns.FORMATTER_ID + "," + Columns.NOVEL_PAGE + "," + Columns.STATUS + ") values(" + - "0" + "," + - "'" + novelURL + "'," + - "'" + formatter + "','" + - novelPage + "'," + - status + ")" - ); - } - /** * TODO Create a cache cleaner * @@ -742,7 +770,7 @@ public static boolean removeFromLibrary(@NotNull String novelURL) { * @return yes or no */ public static boolean inLibrary(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + " from " + Tables.NOVELS + " where " + Columns.NOVEL_URL + " ='" + novelURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " ='" + novelURL + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return false; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 5e9d30b364..9ba04219c4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -242,7 +242,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.source_migrate: Intent intent = new Intent(getActivity(), MigrationView.class); try { - intent.putExtra("selected", Database.serialize(selectedNovels)); + intent.putExtra("selected", Database.serializeToString(selectedNovels)); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java index 287ee62259..4366160f24 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java @@ -103,7 +103,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); try { - novels = (ArrayList) Database.deserialize(intent.getStringExtra("selected")); + novels = (ArrayList) Database.deserializeString(intent.getStringExtra("selected")); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index 810a524d57..ad643be7af 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -100,7 +100,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { try { ArrayList novelCards = new ArrayList<>(); novelCards.add(new NovelCard(StaticNovel.novelPage.title, StaticNovel.novelURL, StaticNovel.novelPage.imageURL, StaticNovel.formatter.getID())); - intent.putExtra("selected", Database.serialize(novelCards)); + intent.putExtra("selected", Database.serializeToString(novelCards)); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index 5d2373ce61..ac5b22c0f3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -94,7 +94,7 @@ protected Void doInBackground(Void... voids) { //IGNORED: int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); JSONObject novel = new JSONObject(); - novel.put("novelURL", Database.serialize(nurl)); + novel.put("novelURL", Database.serializeToString(nurl)); novel.put("bookmarked", true); novel.put("FORMATTER_ID", formatter_id); novel.put("novelPage", npage); @@ -127,8 +127,8 @@ protected Void doInBackground(Void... voids) { String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVE_PATH.toString())); JSONObject chapter = new JSONObject(); - chapter.put("novelURL", Database.serialize(nurl)); - chapter.put("chapterURL", Database.serialize(curl)); + chapter.put("novelURL", Database.serializeToString(nurl)); + chapter.put("chapterURL", Database.serializeToString(curl)); //TODO Figure out where i use this //chapter.put("SAVED_DATA",); @@ -137,7 +137,7 @@ protected Void doInBackground(Void... voids) { chapter.put("READ_CHAPTER", read_chapter); chapter.put("BOOKMARKED", bookmarked); chapter.put("IS_SAVED", is_saved); - chapter.put("SAVE_PATH", Database.serialize(path)); + chapter.put("SAVE_PATH", Database.serializeToString(path)); CHAPTERS.put(chapter); } } From 86c9624051e705ecfd839eaa9d6e181a59e4ac19 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 13 Oct 2019 21:15:19 -0400 Subject: [PATCH 020/162] More effort put into rewriting. Next plan is to fix methods --- .../shosetsu/backend/database/Database.java | 170 +++++++++++------- 1 file changed, 102 insertions(+), 68 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 5310cf481e..c9ebb916bc 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -31,6 +31,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelPageJSON; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; /* * This file is part of Shosetsu. @@ -167,6 +168,46 @@ public static Object deserializeString(@NotNull String string) throws IOExceptio return object; } + /** + * Checks string before deserialization + * If null or empty, returns "". Else deserializes the string and returns + * + * @param string String to be checked + * @return Completed String + */ + public static String checkStringDeserialize(String string) { + if (string == null || string.isEmpty()) { + return ""; + } else { + try { + return (String) deserializeString(string); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + return ""; + } + + /** + * Checks string before serialization + * If null or empty, returns "". Else serializes the string and returns + * + * @param string String to be checked + * @return Completed String + */ + public static String checkStringSerialize(String string) { + if (string == null || string.isEmpty()) { + return ""; + } else { + try { + return serializeToString(string); + } catch (IOException e) { + e.printStackTrace(); + } + } + return ""; + } + public static class DatabaseIdentification { public static void addChapter(int novelID, String chapterURL) { @@ -287,9 +328,38 @@ public static String getNovelURLfromNovelID(int id) { } return null; } - } + /** + * Returns Formatter ID via Novel ID + * + * @param id Novel ID + * @return Formatter ID + */ + public static int getFormatterIDFromNovelID(int id) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); + if (cursor.getCount() <= 0) { + cursor.close(); + } else { + cursor.moveToNext(); + int ID = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); + cursor.close(); + return ID; + } + return -1; + } + + /** + * Returns Formatter ID via ChapterID, this simply compacts a longer line of methods into one. + * + * @param id Chapter ID + * @return Formatter ID + */ + public static int getFormatterIDFromChapterID(int id) { + return getFormatterIDFromNovelID(getNovelIDFromChapterID(id)); + } + } + public static class DatabaseDownloads { /** * Gets downloads that are stored @@ -401,7 +471,7 @@ public static void purgeUneededCache() { * @return Count of chapters left to read */ public static int getCountOfChaptersUnread(String novelURL) { - int novelID = DatabaseIdentification.getNovelIDFromNovelURL(novelURL); + int novelID = getNovelIDFromNovelURL(novelURL); Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + "=" + novelID + "" + " and " + Columns.READ_CHAPTER + "!=" + Status.READ, null); int count = cursor.getCount(); cursor.close(); @@ -585,30 +655,10 @@ public static boolean inChapters(String chapterURL) { * @param novelChapter chapterURL */ public static void addToChapters(String novelURL, NovelChapter novelChapter) { - DatabaseIdentification.addChapter(DatabaseIdentification.getNovelIDFromNovelURL(novelURL), novelChapter.link); - String title = novelChapter.chapterNum; - String release = novelChapter.chapterNum; - // Formats the strings - { - if (title == null) { - title = ""; - } else { - try { - title = serializeToString(title); - } catch (IOException e) { - e.printStackTrace(); - } - } - if (release == null) { - release = ""; - } else { - try { - release = serializeToString(release); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + DatabaseIdentification.addChapter(getNovelIDFromNovelURL(novelURL), novelChapter.link); + + String title = checkStringSerialize(novelChapter.chapterNum); + String release = checkStringSerialize(novelChapter.release); try { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + @@ -625,7 +675,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { "values" + "(" + DatabaseIdentification.getChapterIDFromChapterURL(novelChapter.link) + "," + - DatabaseIdentification.getNovelIDFromNovelURL(novelURL) + "," + + getNovelIDFromNovelURL(novelURL) + "," + title + "," + release + "," + 0 + "," + 0 + "," + 0 + "," + 0 + @@ -642,7 +692,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { * @return List of chapters saved of novel */ public static List getChapters(String novelURL) { - int novelID = DatabaseIdentification.getNovelIDFromNovelURL(novelURL); + int novelID = getNovelIDFromNovelURL(novelURL); Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); @@ -652,18 +702,11 @@ public static List getChapters(String novelURL) { while (cursor.moveToNext()) { try { String url = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); - String text = cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString())); - if (!text.equals("")) { - text = (String) deserializeString(text); - } - String release = cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString())); - if (!release.equals("")) { - release = (String) deserializeString(release); - } + NovelChapter novelChapter = new NovelChapter(); - novelChapter.chapterNum = text; + novelChapter.chapterNum = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); novelChapter.link = url; - novelChapter.release = release; + novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); novelChapters.add(novelChapter); } catch (Exception e) { e.printStackTrace(); @@ -682,20 +725,10 @@ public static NovelChapter getChapter(String chapterURL) { } else { NovelChapter novelChapter = null; try { - String url = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); - String text = cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString())); - if (!text.equals("")) { - text = (String) deserializeString(text); - } - String release = cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString())); - if (!release.equals("")) { - release = (String) deserializeString(release); - } - novelChapter = new NovelChapter(); - novelChapter.chapterNum = text; - novelChapter.link = url; - novelChapter.release = release; + novelChapter.chapterNum = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + novelChapter.link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); + novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); } catch (Exception e) { e.printStackTrace(); } @@ -712,7 +745,7 @@ public static class DatabaseNovels { * @param novelURL novelURL of the novel */ public static void bookMark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL)); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); } /** @@ -722,11 +755,11 @@ public static void bookMark(@NotNull String novelURL) { * @return if removed successfully */ public static void unBookmark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL)); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); } public static boolean isBookmarked(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.ID + "=" + DatabaseIdentification.getNovelIDFromNovelURL(novelURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL), null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -787,7 +820,7 @@ public static boolean inLibrary(@NotNull String novelURL) { public static ArrayList getLibrary() { Log.d("DL", "Getting"); Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), - new String[]{Columns.NOVEL_URL.toString(), Columns.FORMATTER_ID.toString(), Columns.NOVEL_PAGE.toString()}, + new String[]{Columns.PARENT_ID.toString(), Columns.TITLE.toString(), Columns.IMAGE_URL.toString()}, Columns.BOOKMARKED + "=1", null, null, null, null); ArrayList novelCards = new ArrayList<>(); @@ -797,12 +830,12 @@ public static ArrayList getLibrary() { } else { while (cursor.moveToNext()) { try { - NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); + int parent = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); novelCards.add(new NovelCard( - novelPage.title, - cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), - novelPage.imageURL, - cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())) + checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), + DatabaseIdentification.getNovelURLfromNovelID(parent), + checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString()))), + DatabaseIdentification.getFormatterIDFromNovelID(parent) )); } catch (Exception e) { e.printStackTrace(); @@ -815,9 +848,11 @@ public static ArrayList getLibrary() { public static NovelCard getNovel(String novelURL) { Log.d("DL", "Getting"); + int parent = getNovelIDFromNovelURL(novelURL); + Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), - new String[]{Columns.NOVEL_URL.toString(), Columns.FORMATTER_ID.toString(), Columns.NOVEL_PAGE.toString()}, - Columns.BOOKMARKED + "=1 and " + Columns.NOVEL_URL + "='" + novelURL + "'", null, null, null, null); + new String[]{Columns.PARENT_ID.toString(), Columns.TITLE.toString(), Columns.IMAGE_URL.toString()}, + Columns.BOOKMARKED + "=1 and " + Columns.PARENT_ID + "=" + parent, null, null, null, null); if (cursor.getCount() <= 0) { cursor.close(); @@ -825,12 +860,11 @@ public static NovelCard getNovel(String novelURL) { } else { cursor.moveToNext(); try { - NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); NovelCard novelCard = new NovelCard( - novelPage.title, - cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), - novelPage.imageURL, - cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())) + checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), + novelURL, + checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString()))), + DatabaseIdentification.getFormatterIDFromNovelID(parent) ); cursor.close(); return novelCard; @@ -870,7 +904,7 @@ public static void setStatus(@NotNull String novelURL, @NotNull Status status) { } public static Status getStatus(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.STATUS + " from " + Tables.NOVELS + " where " + Columns.NOVEL_URL + " = '" + novelURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READING_STATUS + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + " =" + getNovelIDFromNovelURL(novelURL), null); if (cursor.getCount() <= 0) { cursor.close(); return Status.UNREAD; From 160fcf64ca5f6fcad0399a04910e7ce8eae761b5 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 13 Oct 2019 23:10:13 -0400 Subject: [PATCH 021/162] More work done, added a few more utility methods --- .../apps/shosetsu/backend/Utilities.java | 53 +++++++++++ .../shosetsu/backend/database/DBHelper.java | 2 +- .../shosetsu/backend/database/Database.java | 95 ++++++++++++++++--- 3 files changed, 136 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index ca9ce65eab..980d78f280 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.concurrent.TimeUnit; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserializeString; @@ -66,6 +67,58 @@ public static int calculateNoOfColumns(Context context, float columnWidthDp) { / return (int) (screenWidthDp / columnWidthDp + 0.5); } + /** + * Converts String Stati back into Stati + * + * @param s String title + * @return Stati + */ + public static Stati convertStringToStati(String s) { + switch (s) { + case "Publishing": + return Stati.PUBLISHING; + case "Completed": + return Stati.COMPLETED; + case "Paused": + return Stati.PAUSED; + default: + case "Unknown": + return Stati.UNKNOWN; + } + } + + + /** + * Converts Array of Strings into a String + * + * @param a array of strings + * @return String Array + */ + public static String convertArrayToString(String[] a) { + for (int x = 0; x < a.length; x++) { + a[x] = a[x].replace(",", ">,<"); + } + return Arrays.toString(a); + } + + + /** + * Converts a String Array back into an Array of Strings + * + * @param s String array + * @return Array of Strings + */ + public static String[] convertStringToArray(String s) { + String[] a = s.substring(1, s.length() - 1).split(", "); + + for (int x = 0; x < a.length; x++) { + a[x] = a[x].replace(">,<", ","); + } + + return a; + } + + // Preference objects public static SharedPreferences download; public static SharedPreferences view; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 6ce7dbd263..928f49961b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -85,7 +85,7 @@ public class DBHelper extends SQLiteOpenHelper { Columns.DESCRIPTION + " text," + Columns.GENRES + " text," + Columns.AUTHORS + " text," + - Columns.STATUS + " integer not null," + + Columns.STATUS + " text not null," + Columns.TAGS + " text," + Columns.ARTISTS + " text," + Columns.LANGUAGE + " text," + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index c9ebb916bc..b6b47ac7cb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -29,8 +29,11 @@ import java.util.Calendar; import java.util.List; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeNovelPageJSON; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertArrayToString; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToArray; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToStati; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; /* @@ -149,7 +152,7 @@ public static String serializeToString(@NotNull Object object) throws IOExceptio ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(object); byte[] bytes = byteArrayOutputStream.toByteArray(); - return Base64.encodeToString(bytes, Base64.NO_WRAP); + return "serial-" + Base64.encodeToString(bytes, Base64.NO_WRAP); } /** @@ -161,6 +164,7 @@ public static String serializeToString(@NotNull Object object) throws IOExceptio * @throws ClassNotFoundException exception */ public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { + string = string.substring(7); byte[] bytes = Base64.decode(string, Base64.NO_WRAP); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); @@ -220,12 +224,28 @@ public static void addChapter(int novelID, String chapterURL) { "('" + novelID + "','" + chapterURL + - ")"); + "')"); } catch (Exception e) { e.printStackTrace(); } } + public static void addNovel(String novelURL, int formatter) { + try { + sqLiteDatabase.execSQL("insert into " + Tables.CHAPTER_IDENTIFICATION + "(" + + Columns.URL + "," + + Columns.FORMATTER_ID + + ")" + + "values" + + "('" + + novelURL + + "'," + + formatter + ")"); + } catch (Exception e) { + e.printStackTrace(); + } + } /** * @param url NovelURL @@ -771,15 +791,43 @@ public static boolean isBookmarked(@NotNull String novelURL) { return a > 0; } - public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @NotNull String novelURL, int status) { + public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @NotNull String novelURL, int readingStatus) { + addNovel(novelURL, formatter); + int id = getNovelIDFromNovelURL(novelURL); + String imageURL = novelPage.imageURL; + if (imageURL == null) + imageURL = ""; + try { sqLiteDatabase.execSQL("insert into " + Tables.NOVELS + "(" + - Columns.BOOKMARKED + ",'" + Columns.NOVEL_URL + "'," + Columns.FORMATTER_ID + "," + Columns.NOVEL_PAGE + "," + Columns.STATUS + ") values(" + - "0" + "," + - "'" + novelURL + "'," + - "'" + formatter + "','" + - serializeOBJECT(novelPage) + "'," + - status + ")" + Columns.PARENT_ID + "," + + Columns.BOOKMARKED + "," + + Columns.READING_STATUS + "," + + Columns.TITLE + "," + + Columns.IMAGE_URL + "," + + Columns.DESCRIPTION + "," + + Columns.GENRES + "," + + Columns.AUTHORS + "," + + Columns.STATUS + "," + + Columns.TAGS + "," + + Columns.ARTISTS + "," + + Columns.LANGUAGE + "," + + Columns.MAX_CHAPTER_PAGE + + ")" + "values" + "(" + + id + "," + + 0 + "," + + readingStatus + "," + + "'" + checkStringSerialize(novelPage.title) + "'," + + "'" + imageURL + "'," + + "'" + checkStringSerialize(novelPage.description) + "'," + + "'" + checkStringSerialize(convertArrayToString(novelPage.genres)) + "'," + + "'" + checkStringSerialize(convertArrayToString(novelPage.authors)) + "'," + + "'" + novelPage.status + "'," + + "'" + checkStringSerialize(convertArrayToString(novelPage.tags)) + "'," + + "'" + checkStringSerialize(convertArrayToString(novelPage.artists)) + "'," + + "'" + checkStringSerialize(novelPage.language) + "'," + + novelPage.maxChapterPage + "," + + ")" ); } catch (Exception e) { e.printStackTrace(); @@ -882,14 +930,35 @@ public static NovelCard getNovel(String novelURL) { * @return Saved novelPage */ public static NovelPage getNovelPage(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.NOVEL_PAGE + " from " + Tables.NOVELS + " where " + Columns.NOVEL_URL + "='" + novelURL + "'", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + + Columns.TITLE + "," + + Columns.IMAGE_URL + "," + + Columns.DESCRIPTION + "," + + Columns.GENRES + "," + + Columns.AUTHORS + "," + + Columns.STATUS + "," + + Columns.TAGS + "," + + Columns.ARTISTS + "," + + Columns.LANGUAGE + "," + + Columns.MAX_CHAPTER_PAGE + + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return null; } else { cursor.moveToNext(); try { - NovelPage novelPage = deserializeNovelPageJSON(cursor.getString(cursor.getColumnIndex(Columns.NOVEL_PAGE.toString()))); + NovelPage novelPage = new NovelPage(); + novelPage.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + novelPage.imageURL = cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())); + novelPage.description = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.DESCRIPTION.toString()))); + novelPage.genres = convertStringToArray(checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.GENRES.toString())))); + novelPage.authors = convertStringToArray(checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.AUTHORS.toString())))); + novelPage.status = convertStringToStati(cursor.getString(cursor.getColumnIndex(Columns.STATUS.toString()))); + novelPage.tags = convertStringToArray(checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TAGS.toString())))); + novelPage.artists = convertStringToArray(checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.ARTISTS.toString())))); + novelPage.language = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.LANGUAGE.toString()))); + novelPage.maxChapterPage = cursor.getInt(cursor.getColumnIndex(Columns.MAX_CHAPTER_PAGE.toString())); cursor.close(); return novelPage; } catch (Exception e) { @@ -900,7 +969,7 @@ public static NovelPage getNovelPage(@NotNull String novelURL) { } public static void setStatus(@NotNull String novelURL, @NotNull Status status) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.STATUS + "=" + status + " where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'"); } public static Status getStatus(@NotNull String novelURL) { From 934641c37e04c890d7747af52978ba98115de2af Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 13 Oct 2019 23:20:26 -0400 Subject: [PATCH 022/162] only... 12 more errors, then i need to do logic cleanup --- .../apps/shosetsu/backend/Serialize.java | 7 +- .../apps/shosetsu/backend/Utilities.java | 81 ++++++++++++- .../shosetsu/backend/database/Database.java | 107 ++++-------------- .../shosetsu/ui/library/LibraryFragment.java | 3 +- .../shosetsu/ui/migration/MigrationView.java | 5 +- .../ui/novel/pages/NovelFragmentMain.java | 3 +- .../backup/async/BackupProcess.java | 9 +- .../adapters/UpdatedChaptersAdapter.java | 2 +- .../viewHolder/UpdatedChapterHolder.java | 4 +- 9 files changed, 118 insertions(+), 103 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index 5fbcec2a21..a5388005a4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -3,7 +3,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import org.json.JSONArray; @@ -13,9 +12,9 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserializeString; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serializeToString; /* * This file is part of shosetsu-services. @@ -292,7 +291,7 @@ public static JSONObject getSettingsInJSON() throws JSONException, IOException { JSONObject settings = new JSONObject(); settings.put("reader_text_color", Settings.ReaderTextColor); settings.put("reader_text_background_color", Settings.ReaderTextBackgroundColor); - settings.put("shoDir", Database.serializeToString(shoDir)); + settings.put("shoDir", serializeToString(shoDir)); settings.put("paused", Settings.downloadPaused); settings.put("textSize", Settings.ReaderTextSize); settings.put("themeMode", Settings.themeMode); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 980d78f280..5cfb3d606a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -8,6 +8,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; +import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; @@ -27,13 +28,15 @@ import org.json.JSONException; import org.json.JSONObject; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.deserializeString; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.serializeToString; /* * This file is part of Shosetsu. @@ -67,6 +70,80 @@ public static int calculateNoOfColumns(Context context, float columnWidthDp) { / return (int) (screenWidthDp / columnWidthDp + 0.5); } + /** + * Serialize object to string + * + * @param object object serialize + * @return Serialised string + * @throws IOException exception + */ + public static String serializeToString(@NotNull Object object) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(object); + byte[] bytes = byteArrayOutputStream.toByteArray(); + return "serial-" + Base64.encodeToString(bytes, Base64.NO_WRAP); + } + + /** + * Deserialize a string to the object + * + * @param string serialized string + * @return Object from string + * @throws IOException exception + * @throws ClassNotFoundException exception + */ + public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { + string = string.substring(7); + byte[] bytes = Base64.decode(string, Base64.NO_WRAP); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + Object object = objectInputStream.readObject(); + return object; + } + + /** + * Checks string before deserialization + * If null or empty, returns "". Else deserializes the string and returns + * + * @param string String to be checked + * @return Completed String + */ + public static String checkStringDeserialize(String string) { + if (string == null || string.isEmpty()) { + return ""; + } else { + try { + return (String) deserializeString(string); + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + return ""; + } + + /** + * Checks string before serialization + * If null or empty, returns "". Else serializes the string and returns + * + * @param string String to be checked + * @return Completed String + */ + public static String checkStringSerialize(String string) { + if (string == null || string.isEmpty()) { + return ""; + } else { + try { + return serializeToString(string); + } catch (IOException e) { + e.printStackTrace(); + } + } + return ""; + } + + + /** * Converts String Stati back into Stati * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index b6b47ac7cb..0a09e5bc07 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -2,7 +2,6 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import android.util.Base64; import android.util.Log; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; @@ -19,19 +18,18 @@ import org.joda.time.DateTime; import org.joda.time.Days; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.checkStringDeserialize; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.checkStringSerialize; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertArrayToString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToArray; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToStati; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; @@ -140,77 +138,6 @@ public String toString() { } } - /** - * Serialize object to string - * - * @param object object serialize - * @return Serialised string - * @throws IOException exception - */ - public static String serializeToString(@NotNull Object object) throws IOException { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); - objectOutputStream.writeObject(object); - byte[] bytes = byteArrayOutputStream.toByteArray(); - return "serial-" + Base64.encodeToString(bytes, Base64.NO_WRAP); - } - - /** - * Deserialize a string to the object - * - * @param string serialized string - * @return Object from string - * @throws IOException exception - * @throws ClassNotFoundException exception - */ - public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { - string = string.substring(7); - byte[] bytes = Base64.decode(string, Base64.NO_WRAP); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); - ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); - Object object = objectInputStream.readObject(); - return object; - } - - /** - * Checks string before deserialization - * If null or empty, returns "". Else deserializes the string and returns - * - * @param string String to be checked - * @return Completed String - */ - public static String checkStringDeserialize(String string) { - if (string == null || string.isEmpty()) { - return ""; - } else { - try { - return (String) deserializeString(string); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } - } - return ""; - } - - /** - * Checks string before serialization - * If null or empty, returns "". Else serializes the string and returns - * - * @param string String to be checked - * @return Completed String - */ - public static String checkStringSerialize(String string) { - if (string == null || string.isEmpty()) { - return ""; - } else { - try { - return serializeToString(string); - } catch (IOException e) { - e.printStackTrace(); - } - } - return ""; - } public static class DatabaseIdentification { @@ -233,14 +160,14 @@ public static void addChapter(int novelID, String chapterURL) { public static void addNovel(String novelURL, int formatter) { try { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTER_IDENTIFICATION + "(" + - Columns.URL + "," + - Columns.FORMATTER_ID + - ")" + - "values" + - "('" + - novelURL + - "'," + - formatter + Columns.URL + "," + + Columns.FORMATTER_ID + + ")" + + "values" + + "('" + + novelURL + + "'," + + formatter + ")"); } catch (Exception e) { e.printStackTrace(); @@ -295,7 +222,7 @@ public static String getChapterURLFromChapterID(int id) { String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); try { - return (String) Database.deserializeString(serial); + return (String) deserializeString(serial); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } @@ -328,6 +255,14 @@ public static String getNovelURLFromChapterID(int id) { return getNovelURLfromNovelID(getNovelIDFromChapterID(id)); } + /** + * @param url Chapter url + * @return Novel URL + */ + public static String getNovelURLFromChapterURL(String url) { + return getNovelURLFromChapterID(getChapterIDFromChapterURL(url)); + } + /** * @param id NovelID * @return NovelURL @@ -341,7 +276,7 @@ public static String getNovelURLfromNovelID(int id) { String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); try { - return (String) Database.deserializeString(serial); + return (String) deserializeString(serial); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 9ba04219c4..022aa229ba 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -35,6 +35,7 @@ import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.calculateNoOfColumns; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; /* * This file is part of Shosetsu. @@ -242,7 +243,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.source_migrate: Intent intent = new Intent(getActivity(), MigrationView.class); try { - intent.putExtra("selected", Database.serializeToString(selectedNovels)); + intent.putExtra("selected", serializeToString(selectedNovels)); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java index 4366160f24..c316a3a129 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java @@ -38,7 +38,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.migration.adapters.MigratingMapAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.migration.adapters.MigratingNovelAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.migration.adapters.MigrationViewCatalogueAdapter; @@ -51,6 +50,8 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; + public class MigrationView extends AppCompatActivity { Transfer t; @@ -103,7 +104,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); try { - novels = (ArrayList) Database.deserializeString(intent.getStringExtra("selected")); + novels = (ArrayList) deserializeString(intent.getStringExtra("selected")); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index ad643be7af..5a7285b021 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -36,6 +36,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; /* * This file is part of Shosetsu. @@ -100,7 +101,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { try { ArrayList novelCards = new ArrayList<>(); novelCards.add(new NovelCard(StaticNovel.novelPage.title, StaticNovel.novelURL, StaticNovel.novelPage.imageURL, StaticNovel.formatter.getID())); - intent.putExtra("selected", Database.serializeToString(novelCards)); + intent.putExtra("selected", serializeToString(novelCards)); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index ac5b22c0f3..d86c89370e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -36,6 +36,7 @@ import java.util.Date; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.intToBoolean; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.sqLiteDatabase; @@ -94,7 +95,7 @@ protected Void doInBackground(Void... voids) { //IGNORED: int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); JSONObject novel = new JSONObject(); - novel.put("novelURL", Database.serializeToString(nurl)); + novel.put("novelURL", serializeToString(nurl)); novel.put("bookmarked", true); novel.put("FORMATTER_ID", formatter_id); novel.put("novelPage", npage); @@ -127,8 +128,8 @@ protected Void doInBackground(Void... voids) { String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVE_PATH.toString())); JSONObject chapter = new JSONObject(); - chapter.put("novelURL", Database.serializeToString(nurl)); - chapter.put("chapterURL", Database.serializeToString(curl)); + chapter.put("novelURL", serializeToString(nurl)); + chapter.put("chapterURL", serializeToString(curl)); //TODO Figure out where i use this //chapter.put("SAVED_DATA",); @@ -137,7 +138,7 @@ protected Void doInBackground(Void... voids) { chapter.put("READ_CHAPTER", read_chapter); chapter.put("BOOKMARKED", bookmarked); chapter.put("IS_SAVED", is_saved); - chapter.put("SAVE_PATH", Database.serializeToString(path)); + chapter.put("SAVE_PATH", serializeToString(path)); CHAPTERS.put(chapter); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index de56a7e57d..e3836b4050 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -80,7 +80,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, updatedChapterHolder.setNovelChapter(Objects.requireNonNull(DatabaseChapter.getChapter(updates.get(i).CHAPTER_URL))); updatedChapterHolder.popupMenu.setOnMenuItemClickListener(menuItem -> { NovelPage novelPage = new NovelPage(); - String nURL = DatabaseChapter.getChapterNovelURL(updatedChapterHolder.novelChapter.link); + String nURL = Database.DatabaseIdentification.getNovelURLFromChapterURL(updatedChapterHolder.novelChapter.link); if (nURL != null) novelPage = Database.DatabaseNovels.getNovelPage(nURL); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 5b7e063064..9a5f8bd10a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -72,7 +72,7 @@ public void setNovelChapter(NovelChapter novelChapter) { .load( Objects.requireNonNull( Database.DatabaseNovels.getNovel( - Database.DatabaseChapter.getChapterNovelURL(novelChapter.link) + Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link) ) ).imageURL) .into(image); @@ -81,7 +81,7 @@ public void setNovelChapter(NovelChapter novelChapter) { @Override public void onClick(View view) { - String nurl = Database.DatabaseChapter.getChapterNovelURL(novelChapter.link); + String nurl = Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link); Formatter formatter = Database.DatabaseNovels.getFormat(nurl); if (formatter != null) openChapter((Activity) itemView.getContext(), novelChapter, nurl, formatter.getID()); From 4f5c178f06c7f9badff9d21f497bc544d095e0d8 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 14 Oct 2019 11:51:09 -0400 Subject: [PATCH 023/162] Fully completed DB, and optimized some methods --- .../shosetsu/backend/database/DBHelper.java | 2 + .../shosetsu/backend/database/Database.java | 84 +++++++++++-------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 928f49961b..e1dfe4faf7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -108,6 +108,8 @@ public class DBHelper extends SQLiteOpenHelper { private static final String UPDATES_CREATE = "create table if not exists " + Tables.UPDATES + "(" + // Refers to CHAPERID + Columns.ID + " integer not null," + + // Refers to NovelID Columns.PARENT_ID + " integer not null," + Columns.TIME + " integer not null" + ")"; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 0a09e5bc07..6b0069e6c3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -4,7 +4,6 @@ import android.database.sqlite.SQLiteDatabase; import android.util.Log; -import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.Download_Manager; @@ -30,9 +29,11 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToArray; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToStati; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeOBJECT; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLFromChapterID; /* * This file is part of Shosetsu. @@ -606,11 +607,11 @@ public static boolean inChapters(String chapterURL) { /** * Adds chapter to database * - * @param novelURL novelURL + * @param novelID ID of novel * @param novelChapter chapterURL */ - public static void addToChapters(String novelURL, NovelChapter novelChapter) { - DatabaseIdentification.addChapter(getNovelIDFromNovelURL(novelURL), novelChapter.link); + public static void addToChapters(int novelID, NovelChapter novelChapter) { + DatabaseIdentification.addChapter(novelID, novelChapter.link); String title = checkStringSerialize(novelChapter.chapterNum); String release = checkStringSerialize(novelChapter.release); @@ -630,7 +631,7 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { "values" + "(" + DatabaseIdentification.getChapterIDFromChapterURL(novelChapter.link) + "," + - getNovelIDFromNovelURL(novelURL) + "," + + novelID + "," + title + "," + release + "," + 0 + "," + 0 + "," + 0 + "," + 0 + @@ -640,14 +641,18 @@ public static void addToChapters(String novelURL, NovelChapter novelChapter) { } } + public static List getChapters(String novelURL) { + int novelID = getNovelIDFromNovelURL(novelURL); + return getChapters(novelID); + } + /** * Gets chapters of a novel * - * @param novelURL novel to retrieve from + * @param novelID ID to retrieve from * @return List of chapters saved of novel */ - public static List getChapters(String novelURL) { - int novelID = getNovelIDFromNovelURL(novelURL); + public static List getChapters(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); @@ -761,7 +766,7 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No "'" + checkStringSerialize(convertArrayToString(novelPage.tags)) + "'," + "'" + checkStringSerialize(convertArrayToString(novelPage.artists)) + "'," + "'" + checkStringSerialize(novelPage.language) + "'," + - novelPage.maxChapterPage + "," + + novelPage.maxChapterPage + ")" ); } catch (Exception e) { @@ -776,7 +781,9 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No * @return if successful */ public static boolean removeFromLibrary(@NotNull String novelURL) { - return sqLiteDatabase.delete(Tables.NOVELS.toString(), Columns.NOVEL_URL + "='" + novelURL + "'", null) > 0; + boolean a = sqLiteDatabase.delete(Tables.NOVELS.toString(), Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL), null) > 0; + boolean b = sqLiteDatabase.delete(Tables.NOVEL_IDENTIFICATION.toString(), Columns.ID + "=" + getNovelIDFromNovelURL(novelURL), null) > 0; + return a && b; } /** @@ -928,8 +935,23 @@ else if (y == 3) } } - public static void updateData(@NotNull String novelURL, @NotNull NovelPage novelPage) throws Exception { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.NOVEL_PAGE + "='" + serializeOBJECT(novelPage) + "' where " + Columns.NOVEL_URL + "='" + novelURL + "'"); + public static void updateData(@NotNull String novelURL, @NotNull NovelPage novelPage) { + String imageURL = novelPage.imageURL; + if (imageURL == null) + imageURL = ""; + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + + Columns.TITLE + "='" + checkStringSerialize(novelPage.title) + "'," + + Columns.IMAGE_URL + "='" + imageURL + "'," + + Columns.DESCRIPTION + "='" + checkStringSerialize(novelPage.description) + "'," + + Columns.GENRES + "='" + checkStringSerialize(convertArrayToString(novelPage.genres)) + "'," + + Columns.AUTHORS + "='" + checkStringSerialize(convertArrayToString(novelPage.authors)) + "'," + + Columns.STATUS + "='" + novelPage.status + "'," + + Columns.TAGS + "='" + checkStringSerialize(convertArrayToString(novelPage.tags)) + "'," + + Columns.ARTISTS + "='" + checkStringSerialize(convertArrayToString(novelPage.artists)) + "'," + + Columns.LANGUAGE + "='" + checkStringSerialize(novelPage.language) + "'," + + Columns.MAX_CHAPTER_PAGE + "=" + novelPage.maxChapterPage + + "where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL)); + } public static void migrateNovel(@NotNull String oldURL, @NotNull String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { @@ -939,19 +961,6 @@ public static void migrateNovel(@NotNull String oldURL, @NotNull String newURL, bookMark(newURL); } - public static Formatter getFormat(String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + " from " + Tables.NOVELS + " where " + Columns.NOVEL_URL + "='" + novelURL + "'", null); - if (cursor.getCount() <= 0) { - cursor.close(); - return null; - } else { - cursor.moveToNext(); - Formatter formatter = DefaultScrapers.getByID(cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString()))); - cursor.close(); - return formatter; - } - } - } public static class DatabaseUpdates { @@ -1051,7 +1060,7 @@ public static ArrayList getTimeBetween(long date1, long date2) throws Ex throw new Exception("Dates implemented wrongly"); Log.i("UL", "Getting dates between [" + new DateTime(date1) + "] and [" + new DateTime(date2) + "]"); Cursor cursor = sqLiteDatabase.rawQuery( - "SELECT " + Columns.NOVEL_URL + "," + Columns.CHAPTER_URL + "," + Columns.TIME + " from " + Tables.UPDATES + + "SELECT " + Columns.PARENT_ID + "," + Columns.TIME + " from " + Tables.UPDATES + " where " + Columns.TIME + "<" + date2 + " and " + Columns.TIME + ">=" + date1, null); @@ -1061,9 +1070,10 @@ public static ArrayList getTimeBetween(long date1, long date2) throws Ex return new ArrayList<>(); } else { while (cursor.moveToNext()) { + int id = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); novelCards.add(new Update( - cursor.getString(cursor.getColumnIndex(Columns.NOVEL_URL.toString())), - cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_URL.toString())), + getNovelURLFromChapterID(id), + getChapterURLFromChapterID(id), cursor.getLong(cursor.getColumnIndex(Columns.TIME.toString())) )); } @@ -1072,19 +1082,19 @@ public static ArrayList getTimeBetween(long date1, long date2) throws Ex } } - public static void addToUpdates(@NotNull String novelURL, @NotNull String chapterURL, long time) { - sqLiteDatabase.execSQL("insert into " + Tables.UPDATES + "('" + Columns.NOVEL_URL + "','" + Columns.CHAPTER_URL + "'," + Columns.TIME + ") values(" + - "'" + novelURL + "'," + - "'" + chapterURL + "'," + - "" + time + ")"); + public static void addToUpdates(int novelID, @NotNull String chapterURL, long time) { + sqLiteDatabase.execSQL("insert into " + Tables.UPDATES + "(" + Columns.ID + "," + Columns.PARENT_ID + "," + Columns.TIME + ") values(" + + getChapterIDFromChapterURL(chapterURL) + "," + + novelID + "," + + +time + ")"); } - public static boolean removeNovelFromUpdates(@NotNull String novelURL) { - return sqLiteDatabase.delete(Tables.UPDATES.toString(), Columns.NOVEL_URL + "='" + novelURL + "'", null) > 0; + public static boolean removeNovelFromUpdates(int novelID) { + return sqLiteDatabase.delete(Tables.UPDATES.toString(), Columns.PARENT_ID + "=" + novelID, null) > 0; } public static boolean removeFromUpdates(@NotNull String chapterURL) { - return sqLiteDatabase.delete(Tables.UPDATES.toString(), Columns.CHAPTER_URL + "='" + chapterURL + "'", null) > 0; + return sqLiteDatabase.delete(Tables.UPDATES.toString(), Columns.ID + "=" + getChapterIDFromChapterURL(chapterURL), null) > 0; } } } From 325f8774fc6898b140a775c795b0c418b7e964ff Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 14 Oct 2019 11:59:23 -0400 Subject: [PATCH 024/162] Completed refactoring where needed. 5 errors left in backup, and many more in restore --- .../shosetsu/backend/database/Database.java | 21 ++++++++++++++++++- .../shosetsu/ui/migration/async/Transfer.java | 8 +++++-- .../ui/novel/adapters/ChaptersAdapter.java | 5 ++++- .../ui/novel/async/ChapterLoader.java | 5 ++++- .../shosetsu/ui/novel/async/NovelLoader.java | 6 +++++- .../adapters/UpdatedChaptersAdapter.java | 4 +++- .../ui/updates/async/ChapterUpdater.java | 7 +++++-- .../viewHolder/UpdatedChapterHolder.java | 4 +++- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 6b0069e6c3..35d47edf54 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -305,6 +305,25 @@ public static int getFormatterIDFromNovelID(int id) { return -1; } + /** + * Returns Formatter ID via Novel URL + * + * @param url Novel URL + * @return Formatter ID + */ + public static int getFormatterIDFromNovelURL(String url) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " = '" + url + "'", null); + if (cursor.getCount() <= 0) { + cursor.close(); + } else { + cursor.moveToNext(); + int ID = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); + cursor.close(); + return ID; + } + return -1; + } + /** * Returns Formatter ID via ChapterID, this simply compacts a longer line of methods into one. * @@ -607,7 +626,7 @@ public static boolean inChapters(String chapterURL) { /** * Adds chapter to database * - * @param novelID ID of novel + * @param novelID ID of novel * @param novelChapter chapterURL */ public static void addToChapters(int novelID, NovelChapter novelChapter) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java index 2e34790598..6e9711cf18 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java @@ -18,6 +18,8 @@ import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; + /* * This file is part of Shosetsu. * @@ -89,12 +91,13 @@ protected Void doInBackground(Void... voids) { migrationView.pageCount.post(() -> migrationView.pageCount.setText(p)); novelPage = formatter.parseNovel(strings[1], page); + int novelID = getNovelIDFromNovelURL(strings[1]); for (NovelChapter novelChapter : novelPage.novelChapters) if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - Database.DatabaseChapter.addToChapters(strings[1], novelChapter); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); } page++; @@ -107,11 +110,12 @@ protected Void doInBackground(Void... voids) { } } else { int mangaCount = 0; + int novelID = getNovelIDFromNovelURL(strings[1]); for (NovelChapter novelChapter : novelPage.novelChapters) if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - Database.DatabaseChapter.addToChapters(strings[1], novelChapter); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); } } if (C) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index c0f78d1e64..f4c3163ba2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -20,6 +20,8 @@ import com.github.doomsdayrs.apps.shosetsu.ui.novel.viewHolders.ChaptersViewHolder; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; + /* * This file is part of Shosetsu. * @@ -72,8 +74,9 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int chaptersViewHolder.library_card_title.setText(novelChapter.chapterNum); chaptersViewHolder.novelFragmentChapters = novelFragmentChapters; + //TODO The getNovelID in this method likely will cause slowdowns due to IO if (!Database.DatabaseChapter.inChapters(novelChapter.link)) - Database.DatabaseChapter.addToChapters(StaticNovel.novelURL, novelChapter); + Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(StaticNovel.novelURL), novelChapter); if (Database.DatabaseChapter.isBookMarked(novelChapter.link)) { chaptersViewHolder.library_card_title.setTextColor(chaptersViewHolder.itemView.getResources().getColor(R.color.bookmarked)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index b14a530445..2b48ccde79 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; + /* * This file is part of Shosetsu. * @@ -124,11 +126,12 @@ protected Boolean doInBackground(Activity... voids) { } private void add(int mangaCount, NovelChapter novelChapter) { + //TODO The getNovelID in this method likely will cause slowdowns due to IO if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); StaticNovel.novelChapters.add(novelChapter); - Database.DatabaseChapter.addToChapters(StaticNovel.novelURL, novelChapter); + Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(StaticNovel.novelURL), novelChapter); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 650fa6e387..2f752437e4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; + /* * This file is part of Shosetsu. * @@ -98,9 +100,11 @@ protected Boolean doInBackground(Activity... voids) { if (C && !Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } + //TODO The getNovelID in this method likely will cause slowdowns due to IO + int novelID = getNovelIDFromNovelURL(StaticNovel.novelURL); for (NovelChapter novelChapter : StaticNovel.novelPage.novelChapters) if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) - Database.DatabaseChapter.addToChapters(StaticNovel.novelURL, novelChapter); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); System.out.println(StaticNovel.novelChapters); if (StaticNovel.novelChapters == null) StaticNovel.novelChapters = new ArrayList<>(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index e3836b4050..bd5fd7593e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -16,6 +16,7 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.backend.database.objects.Update; import com.github.doomsdayrs.apps.shosetsu.ui.updates.viewHolder.UpdatedChapterHolder; +import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.DownloadItem; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; @@ -26,6 +27,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; /* * This file is part of Shosetsu. @@ -90,7 +92,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, System.exit(-1); } - Formatter formatter = Database.DatabaseNovels.getFormat(nURL); + Formatter formatter = DefaultScrapers.getByID(getFormatterIDFromNovelURL(nURL)); if (novelPage != null) switch (menuItem.getItemId()) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java index a4cc4d85a4..ce26253f70 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; + /* * This file is part of Shosetsu. * @@ -141,8 +143,9 @@ private void add(int mangaCount, NovelChapter novelChapter, NovelCard novelCard) if (continueProcesss && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - Database.DatabaseChapter.addToChapters(novelCard.novelURL, novelChapter); - Database.DatabaseUpdates.addToUpdates(novelCard.novelURL, novelChapter.link, System.currentTimeMillis()); + int novelID = getNovelIDFromNovelURL(novelCard.novelURL); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); + Database.DatabaseUpdates.addToUpdates(novelID, novelChapter.link, System.currentTimeMillis()); if (!updatedNovels.contains(novelCard)) updatedNovels.add(novelCard); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 9a5f8bd10a..1ceee393c5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -30,11 +30,13 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.squareup.picasso.Picasso; import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openChapter; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; /** * shosetsu @@ -82,7 +84,7 @@ public void setNovelChapter(NovelChapter novelChapter) { @Override public void onClick(View view) { String nurl = Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link); - Formatter formatter = Database.DatabaseNovels.getFormat(nurl); + Formatter formatter = DefaultScrapers.getByID(getFormatterIDFromNovelURL(nurl)); if (formatter != null) openChapter((Activity) itemView.getContext(), novelChapter, nurl, formatter.getID()); } From c956dc735eb3a391348a89d291d1d8e0234b8cee Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 14 Oct 2019 12:02:57 -0400 Subject: [PATCH 025/162] Temp patch, since ill need to redesign the backup/restore system --- .../backup/async/BackupProcess.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index d86c89370e..78352d0a32 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -78,16 +78,16 @@ protected Void doInBackground(Void... voids) { while (cursor.moveToNext()) { // Gets the novelURL - String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - Log.i("NovelBack", nurl); + //String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); + // Log.i("NovelBack", nurl); // Gets if it is in library, if not then it skips boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); Log.i("NovelBack", "Valid?: " + bookmarked); if (bookmarked) { //SHOULD BE IN JSON ALREADY - JSONObject npage = new JSONObject(cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString()))); - npage.put("novelChapters", new JSONArray()); + // JSONObject npage = new JSONObject(cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString()))); + // npage.put("novelChapters", new JSONArray()); // ID of formatter int formatter_id = cursor.getInt(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())); @@ -95,10 +95,10 @@ protected Void doInBackground(Void... voids) { //IGNORED: int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); JSONObject novel = new JSONObject(); - novel.put("novelURL", serializeToString(nurl)); + //novel.put("novelURL", serializeToString(nurl)); novel.put("bookmarked", true); novel.put("FORMATTER_ID", formatter_id); - novel.put("novelPage", npage); + //novel.put("novelPage", npage); NOVELS.put(novel); } } @@ -112,15 +112,17 @@ protected Void doInBackground(Void... voids) { Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.CHAPTERS, null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { - String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); + //String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - boolean inLibrary = Database.DatabaseNovels.isBookmarked(nurl); + //TODO Fix this shit + boolean inLibrary = false; + //Database.DatabaseNovels.isBookmarked(nurl); if (inLibrary) { - String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); + // String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); // very dirty logger //Log.i("ChapterBack", curl); - String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_CHAPTER.toString())); + // String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_CHAPTER.toString())); int y = cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString())); int read_chapter = cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString())); boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); @@ -128,8 +130,8 @@ protected Void doInBackground(Void... voids) { String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVE_PATH.toString())); JSONObject chapter = new JSONObject(); - chapter.put("novelURL", serializeToString(nurl)); - chapter.put("chapterURL", serializeToString(curl)); + //chapter.put("novelURL", serializeToString(nurl)); + // chapter.put("chapterURL", serializeToString(curl)); //TODO Figure out where i use this //chapter.put("SAVED_DATA",); From 031b4ec83ae5fd3f5fc92e5490f536e640b0c227 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 14 Oct 2019 13:12:56 -0400 Subject: [PATCH 026/162] Fixed ALOT, Need to work on testing ALL platforms --- app/src/main/AndroidManifest.xml | 6 +- .../shosetsu/backend/Download_Manager.java | 2 +- .../apps/shosetsu/backend/Utilities.java | 30 +++++---- .../shosetsu/backend/database/DBHelper.java | 2 + .../shosetsu/backend/database/Database.java | 63 +++++++++---------- .../library/adapter/LibraryNovelAdapter.java | 4 +- .../apps/shosetsu/ui/main/MainActivity.java | 18 ++++-- 7 files changed, 72 insertions(+), 53 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 571a5e801e..bf7a1253f9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,8 @@ + + + + - diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index c11968893a..f34c3f0fd1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -135,7 +135,7 @@ protected Void doInBackground(Void... voids) { File folder = new File(shoDir + "/download/" + downloadItem.formatter.getID() + "/" + downloadItem.novelName); Log.d("Des", folder.toString()); if (!folder.exists()) - if (!folder.mkdirs()) { + if (folder.mkdirs()) { throw new IOException("Failed to mkdirs"); } String formattedName = downloadItem.chapterName.replaceAll("/", ""); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 5cfb3d606a..d57158ca67 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -94,12 +94,16 @@ public static String serializeToString(@NotNull Object object) throws IOExceptio * @throws ClassNotFoundException exception */ public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { - string = string.substring(7); - byte[] bytes = Base64.decode(string, Base64.NO_WRAP); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); - ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); - Object object = objectInputStream.readObject(); - return object; + if (!string.equals("null")) { + string = string.substring(7); + //Log.d("Deserialize", string); + byte[] bytes = Base64.decode(string, Base64.NO_WRAP); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + Object object = objectInputStream.readObject(); + return object; + } + return null; } /** @@ -143,7 +147,6 @@ public static String checkStringSerialize(String string) { } - /** * Converts String Stati back into Stati * @@ -171,11 +174,14 @@ public static Stati convertStringToStati(String s) { * @param a array of strings * @return String Array */ - public static String convertArrayToString(String[] a) { - for (int x = 0; x < a.length; x++) { - a[x] = a[x].replace(",", ">,<"); + public static String convertArrayToString(@NotNull String[] a) { + if (a != null && a.length != 0) { + for (int x = 0; x < a.length; x++) { + a[x] = a[x].replace(",", ">,<"); + } + return Arrays.toString(a); } - return Arrays.toString(a); + return "[]"; } @@ -185,7 +191,7 @@ public static String convertArrayToString(String[] a) { * @param s String array * @return Array of Strings */ - public static String[] convertStringToArray(String s) { + public static String[] convertStringToArray(@NotNull String s) { String[] a = s.substring(1, s.length() - 1).split(", "); for (int x = 0; x < a.length; x++) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index e1dfe4faf7..1c1a6cec6e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -129,6 +129,8 @@ public DBHelper(Context context) { */ @Override public void onCreate(SQLiteDatabase db) { + db.execSQL(NOVEL_IDENTIFICATION_CREATE); + db.execSQL(CHAPTER_IDENTIFICATION_CREATE); db.execSQL(NOVELS); db.execSQL(DOWNLOADS_CREATE); db.execSQL(CHAPTERS_CREATE); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 35d47edf54..727bc045df 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -17,7 +17,6 @@ import org.joda.time.DateTime; import org.joda.time.Days; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -28,12 +27,13 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertArrayToString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToArray; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.convertStringToStati; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.hasChapter; /* * This file is part of Shosetsu. @@ -142,6 +142,13 @@ public String toString() { public static class DatabaseIdentification { + public static boolean hasChapter(String chapterURL) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.URL + " = '" + chapterURL + "'", null); + int a = cursor.getCount(); + cursor.close(); + return !(a <= 0); + } + public static void addChapter(int novelID, String chapterURL) { try { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTER_IDENTIFICATION + "(" + @@ -160,8 +167,8 @@ public static void addChapter(int novelID, String chapterURL) { public static void addNovel(String novelURL, int formatter) { try { - sqLiteDatabase.execSQL("insert into " + Tables.CHAPTER_IDENTIFICATION + "(" + - Columns.URL + "," + + sqLiteDatabase.execSQL("insert into " + Tables.NOVEL_IDENTIFICATION + "('" + + Columns.URL + "'," + Columns.FORMATTER_ID + ")" + "values" + @@ -180,7 +187,7 @@ public static void addNovel(String novelURL, int formatter) { * @return NovelID */ public static int getNovelIDFromNovelURL(String url) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " = " + url + "", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " ='" + url + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return 0; @@ -197,7 +204,7 @@ public static int getNovelIDFromNovelURL(String url) { * @return ChapterID */ public static int getChapterIDFromChapterURL(String url) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.URL + " = " + url + "", null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.URL + " = '" + url + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return 0; @@ -220,13 +227,9 @@ public static String getChapterURLFromChapterID(int id) { cursor.close(); } else { cursor.moveToNext(); - String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); + String url = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); - try { - return (String) deserializeString(serial); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } + return url; } return null; } @@ -274,13 +277,9 @@ public static String getNovelURLfromNovelID(int id) { cursor.close(); } else { cursor.moveToNext(); - String serial = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); + String url = cursor.getString(cursor.getColumnIndex(Columns.URL.toString())); cursor.close(); - try { - return (String) deserializeString(serial); - } catch (IOException | ClassNotFoundException e) { - e.printStackTrace(); - } + return url; } return null; } @@ -371,7 +370,7 @@ public static DownloadItem getFirstDownload() { int id = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); String nName = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_NAME.toString())); String cName = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_NAME.toString())); - int formatter = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); + int formatter = getFormatterIDFromChapterID(id); cursor.close(); return new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, DatabaseIdentification.getNovelURLFromChapterID(id), DatabaseIdentification.getChapterURLFromChapterID(id)); } @@ -394,13 +393,11 @@ public static boolean removeDownload(DownloadItem downloadItem) { */ public static void addToDownloads(DownloadItem downloadItem) { sqLiteDatabase.execSQL("insert into " + Tables.DOWNLOADS + " (" + - Columns.FORMATTER_ID + "," + Columns.PARENT_ID + "," + Columns.NOVEL_NAME + "," + Columns.CHAPTER_NAME + "," + Columns.PAUSED + ") " + "values (" + - downloadItem.formatter.getID() + "," + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + ",'" + DownloadItem.cleanse(downloadItem.novelName) + "','" + DownloadItem.cleanse(downloadItem.chapterName) + "'," + 0 + ")"); @@ -423,7 +420,7 @@ public static boolean inDownloads(DownloadItem downloadItem) { * @return count of download items */ public static int getDownloadCount() { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.FORMATTER_ID + " from " + Tables.DOWNLOADS, null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.PARENT_ID + " from " + Tables.DOWNLOADS, null); int a = cursor.getCount(); cursor.close(); return a; @@ -630,7 +627,8 @@ public static boolean inChapters(String chapterURL) { * @param novelChapter chapterURL */ public static void addToChapters(int novelID, NovelChapter novelChapter) { - DatabaseIdentification.addChapter(novelID, novelChapter.link); + if (!hasChapter(novelChapter.link)) + DatabaseIdentification.addChapter(novelID, novelChapter.link); String title = checkStringSerialize(novelChapter.chapterNum); String release = checkStringSerialize(novelChapter.release); @@ -650,9 +648,9 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { "values" + "(" + DatabaseIdentification.getChapterIDFromChapterURL(novelChapter.link) + "," + - novelID + "," + - title + "," + - release + "," + + novelID + ",'" + + title + "','" + + release + "'," + 0 + "," + 0 + "," + 0 + "," + 0 + ")"); } catch (Exception e) { @@ -724,7 +722,7 @@ public static class DatabaseNovels { * @param novelURL novelURL of the novel */ public static void bookMark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL)); } /** @@ -738,7 +736,7 @@ public static void unBookmark(@NotNull String novelURL) { } public static boolean isBookmarked(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL), null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -843,7 +841,7 @@ public static ArrayList getLibrary() { novelCards.add(new NovelCard( checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), DatabaseIdentification.getNovelURLfromNovelID(parent), - checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString()))), + cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())), DatabaseIdentification.getFormatterIDFromNovelID(parent) )); } catch (Exception e) { @@ -891,6 +889,7 @@ public static NovelCard getNovel(String novelURL) { * @return Saved novelPage */ public static NovelPage getNovelPage(@NotNull String novelURL) { + int ID = getNovelIDFromNovelURL(novelURL); Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.TITLE + "," + Columns.IMAGE_URL + "," + @@ -902,7 +901,7 @@ public static NovelPage getNovelPage(@NotNull String novelURL) { Columns.ARTISTS + "," + Columns.LANGUAGE + "," + Columns.MAX_CHAPTER_PAGE + - " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'", null); + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + ID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -940,7 +939,7 @@ public static Status getStatus(@NotNull String novelURL) { return Status.UNREAD; } else { cursor.moveToNext(); - int y = cursor.getInt(cursor.getColumnIndex(Columns.STATUS.toString())); + int y = cursor.getInt(cursor.getColumnIndex(Columns.READING_STATUS.toString())); cursor.close(); if (y == 0) return Status.UNREAD; @@ -969,7 +968,7 @@ public static void updateData(@NotNull String novelURL, @NotNull NovelPage novel Columns.ARTISTS + "='" + checkStringSerialize(convertArrayToString(novelPage.artists)) + "'," + Columns.LANGUAGE + "='" + checkStringSerialize(novelPage.language) + "'," + Columns.MAX_CHAPTER_PAGE + "=" + novelPage.maxChapterPage + - "where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL)); + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL)); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java index 61c54cd867..ef1dae7935 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java @@ -62,8 +62,8 @@ public void onBindViewHolder(@NonNull LibraryViewHolder libraryViewHolder, int i //Sets values { Picasso.get() - .load(novelCard.imageURL) - .into(libraryViewHolder.library_card_image); + .load(novelCard.imageURL) + .into(libraryViewHolder.library_card_image); libraryViewHolder.libraryFragment = libraryFragment; libraryViewHolder.novelCard = novelCard; libraryViewHolder.formatter = DefaultScrapers.getByID(novelCard.formatterID); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index b8efba5aec..e6b69cd073 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -2,14 +2,15 @@ import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.os.Build; import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; @@ -74,8 +75,18 @@ public class MainActivity extends AppCompatActivity { */ @Override protected void onCreate(Bundle savedInstanceState) { - // super.onCreate(savedInstanceState); + + int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (permission != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, new String[] + { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }, 1); + } + + Utilities.view = getSharedPreferences("view", 0); Utilities.download = getSharedPreferences("download", 0); Utilities.advanced = getSharedPreferences("advanced", 0); @@ -139,9 +150,6 @@ public void onFailed(AppUpdaterError error) { Log.d("Updater", "Completed construction"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); - } // Settings setup Settings.connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); From 6115c73f2881444cd6943a58d617ec7ee0b3bf55 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Tue, 15 Oct 2019 20:12:59 -0400 Subject: [PATCH 027/162] Fixed downloader issues --- .../shosetsu/ExampleInstrumentedTest.java | 15 ++++++------ .../shosetsu/backend/Download_Manager.java | 7 +++--- .../apps/shosetsu/backend/Utilities.java | 23 +++++++++++++++++-- .../shosetsu/backend/database/Database.java | 1 - .../apps/shosetsu/ui/main/MainActivity.java | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/app/src/androidTest/java/com/github/doomsdayrs/apps/shosetsu/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/github/doomsdayrs/apps/shosetsu/ExampleInstrumentedTest.java index 78f4d66c46..8129191315 100644 --- a/app/src/androidTest/java/com/github/doomsdayrs/apps/shosetsu/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/com/github/doomsdayrs/apps/shosetsu/ExampleInstrumentedTest.java @@ -1,13 +1,11 @@ package com.github.doomsdayrs.apps.shosetsu; -import android.content.Context; -import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -import static org.junit.Assert.*; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.cleanString; /** * Instrumented test, which will execute on an Android device. @@ -16,11 +14,12 @@ */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - assertEquals("com.github.doomsdayrs.apps.shosetsu", appContext.getPackageName()); + @Test + public void test() { + String a = "Abc123+++::::/ / `\""; + System.out.println(a); + a = cleanString(a); + System.out.println(a); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index f34c3f0fd1..f33cae9436 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -19,6 +19,7 @@ import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.cleanString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; /* @@ -132,13 +133,13 @@ protected Void doInBackground(Void... voids) { try { { Log.d("Dir", shoDir + "download/"); - File folder = new File(shoDir + "/download/" + downloadItem.formatter.getID() + "/" + downloadItem.novelName); + File folder = new File(shoDir + "/download/" + downloadItem.formatter.getID() + "/" + cleanString(downloadItem.novelName)); Log.d("Des", folder.toString()); if (!folder.exists()) - if (folder.mkdirs()) { + if (!folder.mkdirs()) { throw new IOException("Failed to mkdirs"); } - String formattedName = downloadItem.chapterName.replaceAll("/", ""); + String formattedName = cleanString(downloadItem.chapterName); String passage = downloadItem.formatter.getNovelPassage(downloadItem.chapterURL); FileOutputStream fileOutputStream = new FileOutputStream( diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index d57158ca67..f72cf00907 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -12,6 +12,8 @@ import android.util.DisplayMetrics; import android.util.Log; +import androidx.appcompat.app.AppCompatActivity; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; @@ -61,6 +63,19 @@ */ public class Utilities { + + /** + * Cleans a string + * + * @param input String to clean + * @return string without specials + */ + public static String cleanString(String input) { + return input.replaceAll("[^A-Za-z0-9]", "_"); + } + + + public static final int SELECTED_STROKE_WIDTH = 8; public static String shoDir = "/Shosetsu/"; @@ -211,11 +226,15 @@ public static String[] convertStringToArray(@NotNull String s) { /** * Initializes the settings + * + * @param */ - public static void initPreferences() { + public static void initPreferences(AppCompatActivity mainActivity) { Settings.ReaderTextColor = view.getInt("ReaderTextColor", Color.BLACK); Settings.ReaderTextBackgroundColor = view.getInt("ReaderBackgroundColor", Color.WHITE); - shoDir = download.getString("dir", "/storage/emulated/0/Shosetsu/"); + String dir = mainActivity.getExternalFilesDir(null).getAbsolutePath(); + dir = dir.substring(0, dir.indexOf("/Android")); + shoDir = download.getString("dir", dir + "/Shosetsu/"); Settings.downloadPaused = download.getBoolean("paused", false); Settings.ReaderTextSize = view.getInt("ReaderTextSize", 14); Settings.themeMode = advanced.getInt("themeMode", 0); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 727bc045df..e02b36bf3f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -139,7 +139,6 @@ public String toString() { } } - public static class DatabaseIdentification { public static boolean hasChapter(String chapterURL) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index e6b69cd073..6f1df30f4b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -92,7 +92,7 @@ protected void onCreate(Bundle savedInstanceState) { Utilities.advanced = getSharedPreferences("advanced", 0); Utilities.tracking = getSharedPreferences("tracking", 0); Utilities.backup = getSharedPreferences("backup", 0); - initPreferences(); + initPreferences(this); switch (Settings.themeMode) { case 0: From 1987033492c27c2d59eb5c254ab03fa1cdf07364 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Wed, 16 Oct 2019 00:33:00 -0400 Subject: [PATCH 028/162] HolyShit lots of work done here. ChapterReader had the most code efficiency increase --- app/build.gradle | 11 +- .../apps/shosetsu/backend/Utilities.java | 26 +- .../shosetsu/backend/database/DBHelper.java | 2 + .../shosetsu/backend/database/Database.java | 28 +- .../shosetsu/ui/reader/ChapterReader.java | 358 +++++++++--------- ..._chapter_reader.xml => chapter_reader.xml} | 11 +- .../main/res/menu/toolbar_chapter_view.xml | 17 + app/src/main/res/values/strings.xml | 3 + 8 files changed, 277 insertions(+), 179 deletions(-) rename app/src/main/res/layout/{fragment_novel_chapter_reader.xml => chapter_reader.xml} (91%) diff --git a/app/build.gradle b/app/build.gradle index 47978703c2..e8a3d80520 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,10 +66,17 @@ dependencies { implementation 'org.jetbrains:annotations:17.0.0' //TODO GITHUB sign in to save backup data to cloud - implementation 'com.github.kohsuke:github-api:github-api-1.95' + //implementation 'com.github.kohsuke:github-api:github-api-1.95' implementation 'com.github.javiersantos:AppUpdater:2.7' + implementation 'us.feras.mdv:markdownview:1.1.0' + implementation 'com.mittsu:markedview:1.0.7' + + implementation 'joda-time:joda-time:2.10.3' - implementation "org.mozilla.components:feature-readerview:1.0.0" + + // TODO Implement readerview provided by Mozilla + //implementation "org.mozilla.components:feature-readerview:1.0.0" + //implementation 'org.mozilla.components:support-base:1.0.0' } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index f72cf00907..af707fcfb3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -11,6 +11,7 @@ import android.util.Base64; import android.util.DisplayMetrics; import android.util.Log; +import android.view.MenuItem; import androidx.appcompat.app.AppCompatActivity; @@ -63,6 +64,29 @@ */ public class Utilities { + /** + * Demarks a list of items, setting only one to be checked. + * + * @param menuItems Items to sort through + * @param positionSpared Item to set checked + * @param demarkAction Any action to proceed with + */ + public static void demarkMenuItems(@NotNull MenuItem[] menuItems, int positionSpared, DemarkAction demarkAction) { + for (int x = 0; x < menuItems.length; x++) + if (x != positionSpared) + menuItems[x].setChecked(false); + else menuItems[x].setChecked(true); + + if (demarkAction != null) + demarkAction.action(positionSpared); + } + + /** + * Abstraction for Actions to take after demarking items. To simplify bulky code + */ + public interface DemarkAction { + void action(int spared); + } /** * Cleans a string @@ -74,8 +98,6 @@ public static String cleanString(String input) { return input.replaceAll("[^A-Za-z0-9]", "_"); } - - public static final int SELECTED_STROKE_WIDTH = 8; public static String shoDir = "/Shosetsu/"; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 1c1a6cec6e..c5e16a0970 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -77,7 +77,9 @@ public class DBHelper extends SQLiteOpenHelper { Columns.PARENT_ID + " integer not null," + // If in the library Columns.BOOKMARKED + " integer not null," + + Columns.READING_STATUS + " text," + + Columns.READER_TYPE + " integer," + // This bulk is the data values Columns.TITLE + " text," + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index e02b36bf3f..070ad93888 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -99,7 +99,7 @@ public enum Columns { URL("url"), PARENT_ID("parent_id"), ID("id"), - + READER_TYPE("reader_type"), TITLE("title"), IMAGE_URL("image_url"), @@ -747,6 +747,30 @@ public static boolean isBookmarked(@NotNull String novelURL) { return a > 0; } + public static void setReaderType(@NotNull String novelURL, int reader) { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); + } + + /** + * Gets reader type for novel + * + * @param novelURL Novel URL + * @return -2 is no such novel, -1 is default, 0 is the same as -1, and 1+ is a specific reading type + */ + public static int getReaderType(@NotNull String novelURL) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READER_TYPE + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL), null); + if (cursor.getCount() <= 0) { + cursor.close(); + return -2; + } + cursor.moveToNext(); + System.out.println(Arrays.toString(cursor.getColumnNames())); + int a = cursor.getInt(cursor.getColumnIndex(Columns.READER_TYPE.toString())); + cursor.close(); + return a; + } + + public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @NotNull String novelURL, int readingStatus) { addNovel(novelURL, formatter); int id = getNovelIDFromNovelURL(novelURL); @@ -759,6 +783,7 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No Columns.PARENT_ID + "," + Columns.BOOKMARKED + "," + Columns.READING_STATUS + "," + + Columns.READER_TYPE + "," + Columns.TITLE + "," + Columns.IMAGE_URL + "," + Columns.DESCRIPTION + "," + @@ -773,6 +798,7 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No id + "," + 0 + "," + readingStatus + "," + + -1 + "," + "'" + checkStringSerialize(novelPage.title) + "'," + "'" + imageURL + "'," + "'" + checkStringSerialize(novelPage.description) + "'," + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index a950683310..ed10a26740 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -21,6 +21,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; @@ -33,8 +34,11 @@ import java.util.Objects; +import us.feras.mdv.MarkdownView; + import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeIndentSize; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeParagraphSpacing; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isReaderNightMode; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; @@ -43,7 +47,10 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.swapReaderColor; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.getNextChapter; +import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.novelURL; /* * This file is part of Shosetsu. @@ -73,9 +80,13 @@ public class ChapterReader extends AppCompatActivity { public boolean ready = false; + public TextView textView; + public MarkdownView markdownView; + int readerType; public ScrollView scrollView; - public TextView textView; + + public ProgressBar progressBar; public Chip nextChapter; @@ -89,22 +100,18 @@ public class ChapterReader extends AppCompatActivity { private boolean bookmarked; private MenuItem tap_to_scroll; + // Order of values. Small,Medium,Large + private MenuItem[] textSizes = new MenuItem[3]; - private MenuItem textSmall; - private MenuItem textMedium; - private MenuItem textLarge; + // Order of values. Non,Small,Medium,Large + private MenuItem[] paragraphSpaces = new MenuItem[4]; - private MenuItem pspaceNon; - private MenuItem pspaceSmall; - private MenuItem pspaceMedium; - private MenuItem pspaceLarge; + // Order of values. Non,Small,Medium,Large + private MenuItem[] indentSpaces = new MenuItem[4]; - private MenuItem ispaceNon; - private MenuItem ispaceSmall; - private MenuItem ispaceMedium; - private MenuItem ispaceLarge; - + private MenuItem defaultReader; + private MenuItem markdownReader; //Tap to scroll private View scroll_up; @@ -116,6 +123,7 @@ public class ChapterReader extends AppCompatActivity { public TextView errorMessage; public Button errorButton; + /** * Save data of view before destroyed * @@ -161,72 +169,66 @@ public boolean onCreateOptionsMenu(Menu menu) { } // Text size { - textSmall = menu.findItem(R.id.chapter_view_textSize_small); - textMedium = menu.findItem(R.id.chapter_view_textSize_medium); - textLarge = menu.findItem(R.id.chapter_view_textSize_large); + textSizes[0] = menu.findItem(R.id.chapter_view_textSize_small); + textSizes[1] = menu.findItem(R.id.chapter_view_textSize_medium); + textSizes[2] = menu.findItem(R.id.chapter_view_textSize_large); switch ((int) Settings.ReaderTextSize) { default: setTextSize(14); case 14: - textSmall.setChecked(true); + textSizes[0].setChecked(true); break; case 17: - textMedium.setChecked(true); + textSizes[1].setChecked(true); break; case 20: - textLarge.setChecked(true); + textSizes[2].setChecked(true); break; } } // Paragraph Space { - pspaceNon = menu.findItem(R.id.chapter_view_paragraphSpace_none); - pspaceSmall = menu.findItem(R.id.chapter_view_paragraphSpace_small); - pspaceMedium = menu.findItem(R.id.chapter_view_paragraphSpace_medium); - pspaceLarge = menu.findItem(R.id.chapter_view_paragraphSpace_large); + paragraphSpaces[0] = menu.findItem(R.id.chapter_view_paragraphSpace_none); + paragraphSpaces[1] = menu.findItem(R.id.chapter_view_paragraphSpace_small); + paragraphSpaces[2] = menu.findItem(R.id.chapter_view_paragraphSpace_medium); + paragraphSpaces[3] = menu.findItem(R.id.chapter_view_paragraphSpace_large); - switch (Settings.paragraphSpacing) { - case 0: - pspaceNon.setChecked(true); - break; - case 1: - pspaceSmall.setChecked(true); - break; - case 2: - pspaceMedium.setChecked(true); - break; - case 3: - pspaceLarge.setChecked(true); - break; - } + paragraphSpaces[Settings.paragraphSpacing].setChecked(true); } // Indent Space { - ispaceNon = menu.findItem(R.id.chapter_view_indent_none); - ispaceSmall = menu.findItem(R.id.chapter_view_indent_small); - ispaceMedium = menu.findItem(R.id.chapter_view_indent_medium); - ispaceLarge = menu.findItem(R.id.chapter_view_indent_large); + indentSpaces[0] = menu.findItem(R.id.chapter_view_indent_none); + indentSpaces[1] = menu.findItem(R.id.chapter_view_indent_small); + indentSpaces[2] = menu.findItem(R.id.chapter_view_indent_medium); + indentSpaces[3] = menu.findItem(R.id.chapter_view_indent_large); - switch (Settings.indentSize) { - case 0: - ispaceNon.setChecked(true); - break; + indentSpaces[Settings.indentSize].setChecked(true); + } + + // Reader + { + defaultReader = menu.findItem(R.id.reader_0); + markdownReader = menu.findItem(R.id.reader_1); + readerType = getReaderType(novelURL); + + switch (readerType) { case 1: - ispaceSmall.setChecked(true); - break; - case 2: - ispaceMedium.setChecked(true); + defaultReader.setChecked(false); + markdownReader.setChecked(true); break; - case 3: - ispaceLarge.setChecked(true); + case 0: + case -1: + defaultReader.setChecked(true); + markdownReader.setChecked(false); break; + case -2: + default: + throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); } } - - return true; } @@ -240,6 +242,8 @@ public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(@NotNull MenuItem item) { Log.d("item", item.toString()); switch (item.getItemId()) { + default: + return false; case R.id.chapter_view_nightMode: if (!item.isChecked()) { swapReaderColor(); @@ -254,8 +258,6 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { tap_to_scroll.setChecked(toggleTapToScroll()); return true; case R.id.chapter_view_bookmark: - - bookmarked = toggleBookmarkChapter(chapterURL); if (bookmarked) bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); @@ -263,103 +265,61 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { return true; case R.id.chapter_view_textSize_small: - setTextSize(14); - setUpReader(); - - item.setChecked(true); - textMedium.setChecked(false); - textLarge.setChecked(false); + demarkMenuItems(indentSpaces, 0, new TextSizeChange()); return true; case R.id.chapter_view_textSize_medium: - setTextSize(17); - setUpReader(); - - item.setChecked(true); - textSmall.setChecked(false); - textLarge.setChecked(false); + demarkMenuItems(textSizes, 1, new TextSizeChange()); return true; case R.id.chapter_view_textSize_large: - setTextSize(20); - setUpReader(); - item.setChecked(true); - textSmall.setChecked(false); - textMedium.setChecked(false); + demarkMenuItems(textSizes, 2, new TextSizeChange()); return true; case R.id.chapter_view_paragraphSpace_none: - changeParagraphSpacing(0); - setUpReader(); - pspaceNon.setChecked(true); - pspaceSmall.setChecked(false); - pspaceMedium.setChecked(false); - pspaceLarge.setChecked(false); + demarkMenuItems(paragraphSpaces, 0, new ParaSpacingChange()); return true; case R.id.chapter_view_paragraphSpace_small: - changeParagraphSpacing(1); - setUpReader(); - pspaceNon.setChecked(false); - pspaceSmall.setChecked(true); - pspaceMedium.setChecked(false); - pspaceLarge.setChecked(false); + demarkMenuItems(paragraphSpaces, 1, new ParaSpacingChange()); return true; case R.id.chapter_view_paragraphSpace_medium: - changeParagraphSpacing(2); - setUpReader(); - pspaceNon.setChecked(false); - pspaceSmall.setChecked(false); - pspaceMedium.setChecked(true); - pspaceLarge.setChecked(false); + demarkMenuItems(paragraphSpaces, 2, new ParaSpacingChange()); return true; case R.id.chapter_view_paragraphSpace_large: - changeParagraphSpacing(3); - setUpReader(); - pspaceNon.setChecked(false); - pspaceSmall.setChecked(false); - pspaceMedium.setChecked(false); - pspaceLarge.setChecked(true); + demarkMenuItems(paragraphSpaces, 3, new ParaSpacingChange()); return true; - case R.id.chapter_view_indent_none: - changeIndentSize(0); - setUpReader(); - ispaceNon.setChecked(true); - ispaceSmall.setChecked(false); - ispaceMedium.setChecked(false); - ispaceLarge.setChecked(false); + demarkMenuItems(indentSpaces, 0, new IndentChange()); return true; case R.id.chapter_view_indent_small: - changeIndentSize(1); - setUpReader(); - ispaceNon.setChecked(false); - ispaceSmall.setChecked(true); - ispaceMedium.setChecked(false); - ispaceLarge.setChecked(false); + demarkMenuItems(indentSpaces, 1, new IndentChange()); return true; case R.id.chapter_view_indent_medium: - changeIndentSize(2); - setUpReader(); - ispaceNon.setChecked(false); - ispaceSmall.setChecked(false); - ispaceMedium.setChecked(true); - ispaceLarge.setChecked(false); + demarkMenuItems(indentSpaces, 2, new IndentChange()); return true; case R.id.chapter_view_indent_large: - changeIndentSize(3); - setUpReader(); - ispaceNon.setChecked(false); - ispaceSmall.setChecked(false); - ispaceMedium.setChecked(false); - ispaceLarge.setChecked(true); + demarkMenuItems(indentSpaces, 3, new IndentChange()); return true; + case R.id.browser: openInBrowser(this, chapterURL); return true; case R.id.webview: openInWebview(this, chapterURL); return true; + case R.id.reader_0: + readerType = 0; + defaultReader.setChecked(true); + markdownReader.setChecked(false); + setReaderType(novelURL, 0); + return true; + case R.id.reader_1: + readerType = 1; + defaultReader.setChecked(false); + markdownReader.setChecked(true); + setReaderType(novelURL, 1); + return true; + } - return false; } /** @@ -382,7 +342,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setTheme(R.style.ThemeOverlay_MaterialComponents_Dark); } - setContentView(R.layout.fragment_novel_chapter_reader); + setContentView(R.layout.chapter_reader); if (savedInstanceState != null) { unformattedText = savedInstanceState.getString("unformattedText"); @@ -408,8 +368,21 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - textView = findViewById(R.id.fragment_novel_chapter_view_text); - textView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); + switch (readerType) { + case 1: + markdownView = findViewById(R.id.fragment_novel_chapter_view_markdown); + markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); + break; + case 0: + case -1: + textView = findViewById(R.id.fragment_novel_chapter_view_text); + textView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); + break; + case -2: + default: + throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); + } + // Scroll up listener scroll_up = findViewById(R.id.scroll_up); @@ -440,6 +413,83 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { loadChapter(); } + /** + * Changes the theme of the reader + * TODO change the scroll position bars color + */ + public void setUpReader() { + scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + switch (readerType) { + case -1: + case 0: + textView.setTextColor(Settings.ReaderTextColor); + textView.setTextSize(Settings.ReaderTextSize); + break; + default: + break; + } + + + if (unformattedText != null) { + StringBuilder replaceSpacing = new StringBuilder("\n"); + for (int x = 0; x < Settings.paragraphSpacing; x++) + replaceSpacing.append("\n"); + + for (int x = 0; x < Settings.indentSize; x++) + replaceSpacing.append("\t"); + + text = unformattedText.replaceAll("\n", replaceSpacing.toString()); + + switch (readerType) { + case -1: + case 0: + textView.setText(text); + break; + case 1: + markdownView.loadMarkdown(text); + } + } + } + + /** + * What to do when scroll hits bottom + */ + public void bottom() { + int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); + if (ready) + if ((scrollView.getScrollY() / (float) total) < .99) { + int y = scrollView.getScrollY(); + if (y % 5 == 0) { + // Log.d("YMAX", String.valueOf(total)); + // Log.d("YC", String.valueOf(y)); + // Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); + + // Log.d("TY", String.valueOf(textView.getScrollY())); + + if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterURL) != Status.READ) + Database.DatabaseChapter.updateY(chapterURL, y); + } + } else { + Log.i("Scroll", "Marking chapter as READ"); + if (chapterURL != null) { + Database.DatabaseChapter.setChapterStatus(chapterURL, Status.READ); + Database.DatabaseChapter.updateY(chapterURL, 0); + nextChapter.setVisibility(View.VISIBLE); + } + //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) + } + } + + private class TextSizeChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + int[] a = {14, 17, 20}; + setTextSize(a[spared]); + setUpReader(); + } + } + /** * Loads the chapter to be read */ @@ -491,27 +541,11 @@ private void scrollDown() { } } - - /** - * Changes the theme of the reader - * TODO change the scroll position bars color - */ - public void setUpReader() { - scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); - textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); - textView.setTextColor(Settings.ReaderTextColor); - textView.setTextSize(Settings.ReaderTextSize); - - if (unformattedText != null) { - StringBuilder replaceSpacing = new StringBuilder("\n"); - for (int x = 0; x < Settings.paragraphSpacing; x++) - replaceSpacing.append("\n"); - - for (int x = 0; x < Settings.indentSize; x++) - replaceSpacing.append("\t"); - - text = unformattedText.replaceAll("\n", replaceSpacing.toString()); - textView.setText(text); + private class ParaSpacingChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + changeParagraphSpacing(spared); + setUpReader(); } } @@ -526,32 +560,12 @@ public void addBottomListener() { } } - /** - * What to do when scroll hits bottom - */ - public void bottom() { - int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); - if (ready) - if ((scrollView.getScrollY() / (float) total) < .99) { - int y = scrollView.getScrollY(); - if (y % 5 == 0) { - Log.d("YMAX", String.valueOf(total)); - Log.d("YC", String.valueOf(y)); - Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); - Log.d("TY", String.valueOf(textView.getScrollY())); - - if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterURL) != Status.READ) - Database.DatabaseChapter.updateY(chapterURL, y); - } - } else { - Log.i("Scroll", "Marking chapter as READ"); - if (chapterURL != null) { - Database.DatabaseChapter.setChapterStatus(chapterURL, Status.READ); - Database.DatabaseChapter.updateY(chapterURL, 0); - nextChapter.setVisibility(View.VISIBLE); - } - //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) - } + private class IndentChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + changeIndentSize(spared); + setUpReader(); + } } diff --git a/app/src/main/res/layout/fragment_novel_chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml similarity index 91% rename from app/src/main/res/layout/fragment_novel_chapter_reader.xml rename to app/src/main/res/layout/chapter_reader.xml index 4d3f45d701..4f903f5ad1 100644 --- a/app/src/main/res/layout/fragment_novel_chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -47,12 +47,19 @@ tools:ignore="ScrollViewSize" /> + @@ -62,7 +69,7 @@ android:layout_width="match_parent" android:layout_height="250dp" android:focusable="false" - android:visibility="invisible" + android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/app/src/main/res/menu/toolbar_chapter_view.xml b/app/src/main/res/menu/toolbar_chapter_view.xml index 2f047ea957..9ccfeaac5d 100644 --- a/app/src/main/res/menu/toolbar_chapter_view.xml +++ b/app/src/main/res/menu/toolbar_chapter_view.xml @@ -79,16 +79,33 @@ android:title="@string/large" /> + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f94275746f..a8a5c74304 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,6 +108,9 @@ Open in WebView Browser + Reader + Default + MarkDown reader From aa9f623f23471d00668f08b1d672c8f925f13e30 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 20 Oct 2019 14:12:11 -0400 Subject: [PATCH 029/162] Tiny increments --- app/build.gradle | 4 +- .../apps/shosetsu/backend/Serialize.java | 6 +- .../apps/shosetsu/backend/Utilities.java | 8 +- .../shosetsu/backend/database/Database.java | 6 +- .../ui/novel/adapters/ChaptersAdapter.java | 2 +- .../ui/novel/pages/NovelFragmentChapters.java | 4 +- .../novel/viewHolders/ChaptersViewHolder.java | 4 +- .../shosetsu/ui/reader/ChapterReader.java | 70 ++++----- .../adapters/UpdatedChaptersAdapter.java | 4 +- .../viewHolder/UpdatedChapterHolder.java | 2 +- .../apps/shosetsu/variables/NovelPlanet.java | 136 ------------------ app/src/main/res/layout/chapter_reader.xml | 37 ++--- 12 files changed, 77 insertions(+), 206 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/NovelPlanet.java diff --git a/app/build.gradle b/app/build.gradle index e8a3d80520..4aac93a5d8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -58,8 +58,8 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' - implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.2' - implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.1' + implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.3' + implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.2' implementation 'com.squareup.picasso:picasso:2.71828' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index a5388005a4..6df26cd2bd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -251,8 +251,8 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc break; case "chapterNum": if (response.equals("null")) - novelChapter.chapterNum = null; - else novelChapter.chapterNum = response; + novelChapter.title = null; + else novelChapter.title = response; break; case "link": if (response.equals("null")) @@ -275,7 +275,7 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("release", serializeToString(novelChapter.release)); - jsonObject.put("chapterNum", serializeToString(novelChapter.chapterNum)); + jsonObject.put("chapterNum", serializeToString(novelChapter.title)); jsonObject.put("link", serializeToString(novelChapter.link)); return jsonObject; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index af707fcfb3..7be31a5fb1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -424,7 +424,7 @@ public static void setTextSize(int size) { public static void openChapter(Activity activity, NovelChapter novelChapter, String nurl, int formatterID) { Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.READING); Intent intent = new Intent(activity, ChapterReader.class); - intent.putExtra("title", novelChapter.chapterNum); + intent.putExtra("title", novelChapter.title); intent.putExtra("chapterURL", novelChapter.link); intent.putExtra("novelURL", nurl); intent.putExtra("formatter", formatterID); @@ -672,8 +672,8 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc break; case "chapterNum": if (response.equals("null")) - novelChapter.chapterNum = null; - else novelChapter.chapterNum = response; + novelChapter.title = null; + else novelChapter.title = response; break; case "link": if (response.equals("null")) @@ -688,7 +688,7 @@ public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exc private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("release", serializeToString(novelChapter.release)); - jsonObject.put("chapterNum", serializeToString(novelChapter.chapterNum)); + jsonObject.put("chapterNum", serializeToString(novelChapter.title)); jsonObject.put("link", serializeToString(novelChapter.link)); return jsonObject; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 070ad93888..fb450652ab 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -629,7 +629,7 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { if (!hasChapter(novelChapter.link)) DatabaseIdentification.addChapter(novelID, novelChapter.link); - String title = checkStringSerialize(novelChapter.chapterNum); + String title = checkStringSerialize(novelChapter.title); String release = checkStringSerialize(novelChapter.release); try { @@ -680,7 +680,7 @@ public static List getChapters(int novelID) { String url = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); NovelChapter novelChapter = new NovelChapter(); - novelChapter.chapterNum = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + novelChapter.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); novelChapter.link = url; novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); novelChapters.add(novelChapter); @@ -702,7 +702,7 @@ public static NovelChapter getChapter(String chapterURL) { NovelChapter novelChapter = null; try { novelChapter = new NovelChapter(); - novelChapter.chapterNum = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + novelChapter.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); novelChapter.link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); } catch (Exception e) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index f4c3163ba2..868e9f76a2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -71,7 +71,7 @@ public ChaptersViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int i) { NovelChapter novelChapter = StaticNovel.novelChapters.get(i); chaptersViewHolder.novelChapter = novelChapter; - chaptersViewHolder.library_card_title.setText(novelChapter.chapterNum); + chaptersViewHolder.library_card_title.setText(novelChapter.title); chaptersViewHolder.novelFragmentChapters = novelFragmentChapters; //TODO The getNovelID in this method likely will cause slowdowns due to IO diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index aa02f7add8..edb9349807 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -250,7 +250,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.chapter_download_selected: for (NovelChapter novelChapter : selectedChapters) if (!Database.DatabaseChapter.isSaved(novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.chapterNum, StaticNovel.novelURL, novelChapter.link); + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link); Download_Manager.addToDownload(downloadItem); } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); @@ -259,7 +259,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.chapter_delete_selected: for (NovelChapter novelChapter : selectedChapters) if (Database.DatabaseChapter.isSaved(novelChapter.link)) - Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.chapterNum, StaticNovel.novelURL, novelChapter.link)); + Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link)); NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index 17f1cbe9f3..eab03e7c1a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -100,10 +100,10 @@ public ChaptersViewHolder(@NonNull View itemView) { return true; case R.id.popup_chapter_menu_download: if (!Database.DatabaseChapter.isSaved(novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.chapterNum, StaticNovel.novelURL, novelChapter.link); + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.chapterNum, StaticNovel.novelURL, novelChapter.link))) { + if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link))) { downloadTag.setVisibility(View.INVISIBLE); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index ed10a26740..c823d3dcc8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -109,9 +109,9 @@ public class ChapterReader extends AppCompatActivity { // Order of values. Non,Small,Medium,Large private MenuItem[] indentSpaces = new MenuItem[4]; + // Order of values. Default, Markdown + private MenuItem[] readers = new MenuItem[2]; - private MenuItem defaultReader; - private MenuItem markdownReader; //Tap to scroll private View scroll_up; @@ -210,19 +210,18 @@ public boolean onCreateOptionsMenu(Menu menu) { // Reader { - defaultReader = menu.findItem(R.id.reader_0); - markdownReader = menu.findItem(R.id.reader_1); + + readers[0] = menu.findItem(R.id.reader_0); + readers[1] = menu.findItem(R.id.reader_1); readerType = getReaderType(novelURL); switch (readerType) { case 1: - defaultReader.setChecked(false); - markdownReader.setChecked(true); + demarkMenuItems(readers, 1, null); break; case 0: case -1: - defaultReader.setChecked(true); - markdownReader.setChecked(false); + demarkMenuItems(readers, 0, null); break; case -2: default: @@ -307,16 +306,10 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { openInWebview(this, chapterURL); return true; case R.id.reader_0: - readerType = 0; - defaultReader.setChecked(true); - markdownReader.setChecked(false); - setReaderType(novelURL, 0); + demarkMenuItems(readers, 0, new ReaderChange()); return true; case R.id.reader_1: - readerType = 1; - defaultReader.setChecked(false); - markdownReader.setChecked(true); - setReaderType(novelURL, 1); + demarkMenuItems(readers, 1, new ReaderChange()); return true; } @@ -398,7 +391,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { if (novelChapter != null) { if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { - title = novelChapter.chapterNum; + title = novelChapter.title; chapterURL = novelChapter.link; loadChapter(); } else @@ -481,14 +474,6 @@ public void bottom() { } } - private class TextSizeChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - int[] a = {14, 17, 20}; - setTextSize(a[spared]); - setUpReader(); - } - } /** * Loads the chapter to be read @@ -511,7 +496,6 @@ public void loadChapter() { Database.DatabaseChapter.setChapterStatus(chapterURL, Status.READING); } - /** * Scrolls the text upwards */ @@ -541,14 +525,6 @@ private void scrollDown() { } } - private class ParaSpacingChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - changeParagraphSpacing(spared); - setUpReader(); - } - } - /** * Sets up the hitting bottom listener */ @@ -560,6 +536,24 @@ public void addBottomListener() { } } + + private class TextSizeChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + int[] a = {14, 17, 20}; + setTextSize(a[spared]); + setUpReader(); + } + } + + private class ParaSpacingChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + changeParagraphSpacing(spared); + setUpReader(); + } + } + private class IndentChange implements Utilities.DemarkAction { @Override public void action(int spared) { @@ -568,5 +562,13 @@ public void action(int spared) { } } + private class ReaderChange implements Utilities.DemarkAction { + @Override + public void action(int spared) { + readerType = spared; + setReaderType(novelURL, spared); + setUpReader(); + } + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index bd5fd7593e..bff2e0671c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -107,10 +107,10 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, return true; case R.id.popup_chapter_menu_download: if (!Database.DatabaseChapter.isSaved(updatedChapterHolder.novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.chapterNum, nURL, updatedChapterHolder.novelChapter.link); + DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.chapterNum, nURL, updatedChapterHolder.novelChapter.link))) { + if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link))) { updatedChapterHolder.downloadTag.setVisibility(View.INVISIBLE); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 1ceee393c5..536879af54 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -69,7 +69,7 @@ public UpdatedChapterHolder(@NonNull View itemView) { public void setNovelChapter(NovelChapter novelChapter) { this.novelChapter = novelChapter; - title.setText(novelChapter.chapterNum); + title.setText(novelChapter.title); Picasso.get() .load( Objects.requireNonNull( diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/NovelPlanet.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/NovelPlanet.java deleted file mode 100644 index a4c6dcc8b5..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/NovelPlanet.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.variables; - -import com.github.Doomsdayrs.api.shosetsu.services.core.dep.ScrapeFormat; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelGenre; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; - -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import okhttp3.OkHttpClient; -import okhttp3.Request; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * novelreader-extensions - * 11 / June / 2019 - * - * @author github.com/doomsdayrs - */ -//TODO Cloudflare intercept -@Deprecated -public class NovelPlanet extends ScrapeFormat { - private final String baseURL = "https://novelplanet.com"; - - public NovelPlanet(int id) { - super(id); - hasCloudFlare(true); - } - - public NovelPlanet(int id, Request.Builder builder) { - super(id, builder); - hasCloudFlare(true); - } - - public NovelPlanet(int id, OkHttpClient client) { - super(id, client); - hasCloudFlare(true); - } - - public NovelPlanet(int id, Request.Builder builder, OkHttpClient client) { - super(id, builder, client); - hasCloudFlare(true); - } - - @Override - public String getName() { - return "NovelPlanet"; - } - - @Override - public String getImageURL() { - return "https://novelplanet.com/Content/images/logoHeader.png"; - } - - - @Override - public String getNovelPassage(String s) throws IOException { - return null; - } - - @Override - public NovelPage parseNovel(String s) throws IOException { - return null; - } - - @Override - public NovelPage parseNovel(String s, int i) throws IOException { - return null; - } - - @Override - public String getLatestURL(int i) { - if (i == 0) - i = 1; - return "https://novelplanet.com/NovelList?order=latestupdate&page=" + i; - } - - @Override - public List parseLatest(String s) throws IOException { - - List novels = new ArrayList<>(); - s = verify(baseURL, s); - - Document document = docFromURL(s); - System.out.println(document.toString()); - Elements elements = document.select("article"); - for (Element element : elements) { - Novel novel = new Novel(); - - { - Element preview = element.selectFirst("div.post-preview"); - Element a = preview.selectFirst("a"); - novel.link = baseURL + a.attr("href"); - novel.imageURL = baseURL + a.selectFirst("img").attr("src"); - } - { - Element content = element.selectFirst("div.post-content"); - novel.title = baseURL + content.selectFirst("a.title").attr("href"); - } - } - - return novels; - } - - @Override - public List search(String s) throws IOException { - - - return new ArrayList<>(); - } - - @Override - public NovelGenre[] getGenres() { - return new NovelGenre[0]; - } -} diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 4f903f5ad1..440af63f4f 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -36,24 +36,29 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> - + + + + + + + - + Date: Wed, 23 Oct 2019 09:37:07 -0400 Subject: [PATCH 030/162] Added order, will modify rest of code for it, Next step is to remove the need of chapterURL for chapterIDs --- .../shosetsu/backend/database/DBHelper.java | 2 + .../shosetsu/backend/database/Database.java | 45 ++++++++++--------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index c5e16a0970..3d3d8873dc 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -56,6 +56,7 @@ public class DBHelper extends SQLiteOpenHelper { Columns.TITLE + " text," + Columns.RELEASE_DATE + " text," + + Columns.ORDER + " integer not null," + // > Scroll position, either 0 for top, or X for the position Columns.Y + " integer not null," + @@ -150,6 +151,7 @@ public void onCreate(SQLiteDatabase db) { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 9) { + //TODO Convert tables db.execSQL("DROP TABLE IF EXISTS " + Tables.CHAPTERS); db.execSQL("DROP TABLE IF EXISTS " + Tables.NOVELS); db.execSQL("DROP TABLE IF EXISTS " + Tables.DOWNLOADS); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index fb450652ab..9acad1538e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -113,7 +113,7 @@ public enum Columns { MAX_CHAPTER_PAGE("max_chapter_page"), RELEASE_DATE("release_date"), - + ORDER("order"), FORMATTER_ID("formatterID"), READ_CHAPTER("read"), @@ -449,6 +449,9 @@ public static int getCountOfChaptersUnread(String novelURL) { return count; } + public static void updateOrder(String chapterURL, int order) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.ORDER + "='" + order + "' where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + } /** * Updates the Y coordinate @@ -461,6 +464,24 @@ public static void updateY(String chapterURL, int y) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } + /** + * Precondition is the chapter is already in the database + * + * @param chapterURL chapterURL to the chapter + * @return order of chapter + */ + public static int getY(String chapterURL) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + if (cursor.getCount() <= 0) { + cursor.close(); + return 0; + } else { + cursor.moveToNext(); + int y = cursor.getInt(cursor.getColumnIndex(Columns.Y.toString())); + cursor.close(); + return y; + } + } /** * @param chapterURL chapter to check @@ -494,25 +515,7 @@ public static void setChapterStatus(String chapterURL, Status status) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } - /** - * returns Y coordinate - * Precondition is the chapter is already in the database - * - * @param chapterURL imageURL to the chapter - * @return if bookmarked? - */ - public static int getY(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); - if (cursor.getCount() <= 0) { - cursor.close(); - return 0; - } else { - cursor.moveToNext(); - int y = cursor.getInt(cursor.getColumnIndex(Columns.Y.toString())); - cursor.close(); - return y; - } - } + /** * Sets bookmark true or false (1 for true, 0 is false) @@ -639,6 +642,7 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { Columns.PARENT_ID + "," + Columns.TITLE + "," + Columns.RELEASE_DATE + "," + + Columns.ORDER + "," + Columns.Y + "," + Columns.READ_CHAPTER + "," + Columns.BOOKMARKED + "," + @@ -650,6 +654,7 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { novelID + ",'" + title + "','" + release + "'," + + novelChapter.order + "," + 0 + "," + 0 + "," + 0 + "," + 0 + ")"); } catch (Exception e) { From b5d87589845d6a870571b5d99bc6434689d8287f Mon Sep 17 00:00:00 2001 From: Rahim Date: Wed, 23 Oct 2019 12:41:11 -0400 Subject: [PATCH 031/162] Finished some DB rewriting, now to finish other parts of the program --- .../apps/shosetsu/backend/database/Database.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 9acad1538e..53e57a2fd7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.checkStringDeserialize; @@ -113,7 +116,7 @@ public enum Columns { MAX_CHAPTER_PAGE("max_chapter_page"), RELEASE_DATE("release_date"), - ORDER("order"), + ORDER("order_of"), FORMATTER_ID("formatterID"), READ_CHAPTER("read"), @@ -515,8 +518,6 @@ public static void setChapterStatus(String chapterURL, Status status) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); } - - /** * Sets bookmark true or false (1 for true, 0 is false) * @@ -694,6 +695,13 @@ public static List getChapters(int novelID) { } } cursor.close(); + Collections.sort(novelChapters, (novelChapter, t1) -> { + if (novelChapter.order < t1.order) + return -1; + else if (novelChapter.order > t1.order) + return 1; + else return 0; + }); return novelChapters; } } From 715e8b4ec8ffcbf857b25acaa41c4f5eed2ae287 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 27 Oct 2019 16:31:35 -0400 Subject: [PATCH 032/162] Working on backup/restore process --- .../apps/shosetsu/backend/Utilities.java | 221 ------------------ .../shosetsu/backend/database/Database.java | 23 +- .../backup/async/BackupProcess.java | 80 ++++--- .../backup/async/RestoreProcess.java | 126 +++------- .../subFragments/backup/async/schema.json | 48 ++-- 5 files changed, 118 insertions(+), 380 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 7be31a5fb1..62bc83939f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -16,7 +16,6 @@ import androidx.appcompat.app.AppCompatActivity; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; @@ -27,16 +26,12 @@ import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import org.jetbrains.annotations.NotNull; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.TimeUnit; @@ -470,226 +465,10 @@ public static boolean isTrackingEnabled() { public static void addTracker() { } - - private static final String[] NOVELPAGEKEYS = {"title", "imageURL", "description", "genres", "authors", "status", "tags", "artists", "language", "maxChapterPage", "novelChapters"}; - private static final String[] NOVELCHAPTERKEYS = {"release", "chapterNum", "link"}; private static boolean debug = false; public static void toggleDebug() { debug = !debug; } - /** - * Turns an object into a JSON counterpart, then serializes it along with data in it - * - * @param object NovelPage or NovelChapter - * @return Serialized JSON - */ - public static String serializeOBJECT(Object object) throws Exception { - if (object.getClass().equals(NovelChapter.class)) { - NovelChapter novelChapter = (NovelChapter) object; - return serializeToString(novelChapterToJSON(novelChapter).toString()); - } else if (object.getClass().equals(NovelPage.class)) { - NovelPage novelPage = (NovelPage) object; - JSONObject jsonObject = new JSONObject(); - - if (novelPage.title != null) - jsonObject.put("title", serializeToString(novelPage.title)); - else jsonObject.put("title", "null"); - - if (novelPage.imageURL != null) - jsonObject.put("imageURL", serializeToString(novelPage.imageURL)); - else jsonObject.put("imageURL", "null"); - - if (novelPage.description != null) - jsonObject.put("description", serializeToString(novelPage.description)); - else jsonObject.put("description", "null"); - - if (novelPage.genres != null) { - JSONArray jsonArray = new JSONArray(); - for (String genre : novelPage.genres) - jsonArray.put(serializeToString(genre)); - jsonObject.put("genres", jsonArray); - } else jsonObject.put("genres", new JSONArray()); - - if (novelPage.authors != null) { - JSONArray jsonArray = new JSONArray(); - for (String author : novelPage.authors) - jsonArray.put(serializeToString(author)); - jsonObject.put("authors", jsonArray); - } else jsonObject.put("authors", new JSONArray()); - - if (novelPage.status != null) { - jsonObject.put("status", novelPage.status.toString()); - } else jsonObject.put("status", "Unknown"); - - if (novelPage.tags != null) { - JSONArray jsonArray = new JSONArray(); - for (String tag : novelPage.tags) - jsonArray.put(serializeToString(tag)); - jsonObject.put("tags", jsonArray); - } else jsonObject.put("tags", new JSONArray()); - - if (novelPage.artists != null) { - JSONArray jsonArray = new JSONArray(); - for (String artist : novelPage.artists) - jsonArray.put(serializeToString(artist)); - jsonObject.put("artists", jsonArray); - } else jsonObject.put("artists", new JSONArray()); - - if (novelPage.language != null) { - jsonObject.put("language", serializeToString(novelPage.language)); - } else jsonObject.put("language", "null"); - - jsonObject.put("maxChapterPage", novelPage.maxChapterPage); - - if (novelPage.novelChapters != null) { - JSONArray jsonArray = new JSONArray(); - for (NovelChapter novelChapter : novelPage.novelChapters) - jsonArray.put(serializeToString(novelChapterToJSON(novelChapter).toString())); - jsonObject.put("novelChapters", jsonArray); - } else jsonObject.put("novelChapters", new JSONArray()); - - if (debug) - System.out.println("JSON to be serialized: " + jsonObject.toString()); - - return serializeToString(jsonObject.toString()); - } else throw new Exception("Illegal class"); - } - - public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { - NovelPage novelPage = new NovelPage(); - JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); - if (debug) - System.out.println("Deserialize-d json: " + jsonObject); - for (String key : NOVELPAGEKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - switch (key) { - case "maxChapterPage": - novelPage.maxChapterPage = jsonObject.getInt(key); - break; - - case "status": - switch (jsonObject.getString(key)) { - case "Publishing": - novelPage.status = Stati.PUBLISHING; - break; - case "Completed": - novelPage.status = Stati.COMPLETED; - break; - case "Paused": - novelPage.status = Stati.PAUSED; - break; - case "Unknown": - novelPage.status = Stati.UNKNOWN; - break; - } - break; - - case "genres": - case "authors": - case "tags": - case "artists": - JSONArray array = jsonObject.getJSONArray(key); - String[] strings = new String[array.length()]; - for (int x = 0; x < array.length(); x++) { - String s = array.getString(x); - strings[x] = (String) deserializeString(s); - } - switch (key) { - case "genres": - novelPage.genres = strings; - break; - case "authors": - novelPage.authors = strings; - break; - case "tags": - novelPage.tags = strings; - break; - case "artists": - novelPage.artists = strings; - break; - } - break; - case "novelChapters": - JSONArray jsonArray = jsonObject.getJSONArray(key); - ArrayList novelChapters = new ArrayList<>(); - for (int x = 0; x < jsonArray.length(); x++) { - novelChapters.add(deserializeNovelChapterJSON(jsonArray.getString(x))); - } - novelPage.novelChapters = novelChapters; - break; - default: - String response = jsonObject.getString(key); - if (!response.equals("null")) { - if (debug) - System.out.println("Serial response of novelChapter key [" + key + "]: " + response); - response = (String) deserializeString(response); - } - switch (key) { - case "title": - if (response.equals("null")) - novelPage.title = null; - else novelPage.title = response; - break; - case "imageURL": - if (response.equals("null")) - novelPage.imageURL = null; - else novelPage.imageURL = response; - break; - case "description": - if (response.equals("null")) - novelPage.description = null; - else novelPage.description = response; - break; - case "language": - if (response.equals("null")) - novelPage.language = null; - else novelPage.language = response; - break; - } - break; - } - } - return novelPage; - } - - public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { - NovelChapter novelChapter = new NovelChapter(); - JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); - for (String key : NOVELCHAPTERKEYS) { - if (!jsonObject.has(key)) - throw new Exception("JSON is invalid due to missing key[" + key + "]"); - - String response = (String) deserializeString(jsonObject.getString(key)); - switch (key) { - case "release": - if (response.equals("null")) - novelChapter.release = null; - else novelChapter.release = response; - break; - case "chapterNum": - if (response.equals("null")) - novelChapter.title = null; - else novelChapter.title = response; - break; - case "link": - if (response.equals("null")) - novelChapter.link = null; - else novelChapter.link = response; - break; - } - } - return novelChapter; - } - - private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("release", serializeToString(novelChapter.release)); - jsonObject.put("chapterNum", serializeToString(novelChapter.title)); - jsonObject.put("link", serializeToString(novelChapter.link)); - return jsonObject; - } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 53e57a2fd7..3bc1706217 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -20,9 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; -import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.checkStringDeserialize; @@ -675,7 +673,7 @@ public static List getChapters(String novelURL) { * @return List of chapters saved of novel */ public static List getChapters(int novelID) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -689,6 +687,7 @@ public static List getChapters(int novelID) { novelChapter.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); novelChapter.link = url; novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); + novelChapter.order = cursor.getDouble(cursor.getColumnIndex(Columns.ORDER.toString())); novelChapters.add(novelChapter); } catch (Exception e) { e.printStackTrace(); @@ -706,8 +705,14 @@ else if (novelChapter.order > t1.order) } } + /** + * Gets a chapter by it's URL + * + * @param chapterURL + * @return + */ public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -718,6 +723,7 @@ public static NovelChapter getChapter(String chapterURL) { novelChapter.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); novelChapter.link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); + novelChapter.order = cursor.getDouble(cursor.getColumnIndex(Columns.ORDER.toString())); } catch (Exception e) { e.printStackTrace(); } @@ -747,8 +753,13 @@ public static void unBookmark(@NotNull String novelURL) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); } - public static boolean isBookmarked(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL), null); + + public static boolean isBookmarked(String novelURL) { + return isBookmarked(getNovelIDFromNovelURL(novelURL)); + } + + public static boolean isBookmarked(int novelID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID , null); if (cursor.getCount() <= 0) { cursor.close(); return false; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index 78352d0a32..417bda8179 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -36,8 +36,10 @@ import java.util.Date; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.intToBoolean; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLfromNovelID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.sqLiteDatabase; /** @@ -77,28 +79,37 @@ protected Void doInBackground(Void... voids) { if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { - // Gets the novelURL - //String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - // Log.i("NovelBack", nurl); // Gets if it is in library, if not then it skips boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); Log.i("NovelBack", "Valid?: " + bookmarked); if (bookmarked) { - //SHOULD BE IN JSON ALREADY - // JSONObject npage = new JSONObject(cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_PAGE.toString()))); - // npage.put("novelChapters", new JSONArray()); + String nurl = getNovelURLfromNovelID(cursor.getInt(cursor.getColumnIndex(Database.Columns.PARENT_ID.toString()))); - // ID of formatter - int formatter_id = cursor.getInt(cursor.getColumnIndex(Database.Columns.FORMATTER_ID.toString())); + JSONObject novel = new JSONObject(); + novel.put("novelURL", nurl); + novel.put("FORMATTER_ID", getFormatterIDFromNovelURL(nurl)); - //IGNORED: int status = cursor.getInt(cursor.getColumnIndex(Database.Columns.STATUS.toString())); + novel.put("title", cursor.getString(cursor.getColumnIndex(Database.Columns.TITLE.toString()))); + + novel.put("imageURL", cursor.getString(cursor.getColumnIndex(Database.Columns.IMAGE_URL.toString()))); + + novel.put("description", cursor.getString(cursor.getColumnIndex(Database.Columns.DESCRIPTION.toString()))); + + novel.put("genres", cursor.getString(cursor.getColumnIndex(Database.Columns.GENRES.toString()))); + + novel.put("authors", cursor.getString(cursor.getColumnIndex(Database.Columns.AUTHORS.toString()))); + + novel.put("status", cursor.getString(cursor.getColumnIndex(Database.Columns.STATUS.toString()))); + + novel.put("tags", cursor.getString(cursor.getColumnIndex(Database.Columns.TAGS.toString()))); + + novel.put("artists", cursor.getString(cursor.getColumnIndex(Database.Columns.ARTISTS.toString()))); + + novel.put("language", cursor.getString(cursor.getColumnIndex(Database.Columns.LANGUAGE.toString()))); + + novel.put("maxChapterPage", cursor.getInt(cursor.getColumnIndex(Database.Columns.MAX_CHAPTER_PAGE.toString()))); - JSONObject novel = new JSONObject(); - //novel.put("novelURL", serializeToString(nurl)); - novel.put("bookmarked", true); - novel.put("FORMATTER_ID", formatter_id); - //novel.put("novelPage", npage); NOVELS.put(novel); } } @@ -112,35 +123,22 @@ protected Void doInBackground(Void... voids) { Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.CHAPTERS, null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { - //String nurl = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_URL.toString())); - - //TODO Fix this shit - boolean inLibrary = false; - //Database.DatabaseNovels.isBookmarked(nurl); - if (inLibrary) { - // String curl = cursor.getString(cursor.getColumnIndex(Database.Columns.CHAPTER_URL.toString())); - // very dirty logger - //Log.i("ChapterBack", curl); - - // String saved_data = cursor.getString(cursor.getColumnIndex(Database.Columns.NOVEL_CHAPTER.toString())); - int y = cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString())); - int read_chapter = cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString())); - boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); - boolean is_saved = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.IS_SAVED.toString()))); - String path = cursor.getString(cursor.getColumnIndex(Database.Columns.SAVE_PATH.toString())); + int novelID = cursor.getInt(cursor.getColumnIndex(Database.Columns.PARENT_ID.toString())); + boolean b = Database.DatabaseNovels.isBookmarked(novelID); + if (b) { + int id = cursor.getInt(cursor.getColumnIndex(Database.Columns.ID.toString())); JSONObject chapter = new JSONObject(); - //chapter.put("novelURL", serializeToString(nurl)); - // chapter.put("chapterURL", serializeToString(curl)); + chapter.put("novelURL", getNovelURLfromNovelID(novelID)); + chapter.put("chapterURL", getChapterURLFromChapterID(id)); - //TODO Figure out where i use this - //chapter.put("SAVED_DATA",); + chapter.put("title", cursor.getString(cursor.getColumnIndex(Database.Columns.TITLE.toString()))); + chapter.put("release_date", cursor.getString(cursor.getColumnIndex(Database.Columns.RELEASE_DATE.toString()))); + chapter.put("order", cursor.getInt(cursor.getColumnIndex(Database.Columns.ORDER.toString()))); - chapter.put("Y", y); - chapter.put("READ_CHAPTER", read_chapter); - chapter.put("BOOKMARKED", bookmarked); - chapter.put("IS_SAVED", is_saved); - chapter.put("SAVE_PATH", serializeToString(path)); + chapter.put("Y", cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString()))); + chapter.put("READ_CHAPTER", cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString()))); + chapter.put("BOOKMARKED", cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); CHAPTERS.put(chapter); } } @@ -159,7 +157,7 @@ protected Void doInBackground(Void... voids) { FileOutputStream fileOutputStream = new FileOutputStream( (folder.getPath() + "/backup-" + (new Date().toString()) + ".shoback") ); - fileOutputStream.write(BACKUP.toString().getBytes()); + fileOutputStream.write(("JSON+-=" + BACKUP.toString()).getBytes()); fileOutputStream.close(); } catch (IOException | JSONException e) { e.printStackTrace(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index aa6628c711..015568bb16 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -30,7 +30,17 @@ import com.github.doomsdayrs.apps.shosetsu.R; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.inChapters; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.inLibrary; /** * shosetsu @@ -89,12 +99,13 @@ protected void onPostExecute(Boolean b) { @Override protected Boolean doInBackground(Void... voids) { File file = new File("" + file_path); - /* + if (file.exists()) { try { BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); textView.post(() -> textView.setText(R.string.reading_file)); + StringBuilder string = new StringBuilder(); { String line; @@ -103,114 +114,53 @@ protected Boolean doInBackground(Void... voids) { } bufferedReader.close(); } + final JSONObject BACKUP = new JSONObject(string.substring(6)); + JSONArray novels = BACKUP.getJSONArray("novels"); + JSONArray chapters = BACKUP.getJSONArray("chapters"); - textView.post(() -> textView.setText(R.string.reading_file)); - progressBar.post(() -> progressBar.setMax(superserialzied.DBChapters.size() + superserialzied.libraries.size() + superserialzied.DBDownloadItems.size() + 1)); - Log.i("Progress", "Restoring downloads"); - for (com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBDownloadItem DBDownloadItem : superserialzied.DBDownloadItems) { - textView.post(() -> textView.setText("Restoring download: " + DBDownloadItem.CHAPTER_URL)); - progressBar.post(() -> progressBar.incrementProgressBy(1)); - DownloadItem downloadItem = new DownloadItem(DefaultScrapers.getByID(DBDownloadItem.FORMATTER_ID), DBDownloadItem.NOVEL_NAME, DBDownloadItem.CHAPTER_NAME, DBDownloadItem.NOVEL_URL, DBDownloadItem.CHAPTER_URL); - if (!Database.DatabaseDownloads.inDownloads(downloadItem)) - Database.DatabaseDownloads.addToDownloads(downloadItem); - } + progressBar.post(() -> progressBar.setMax(novels.length() + chapters.length() + 1)); - Log.i("Progress", "Restoring libraries"); - for (com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBNovel DBNovel : superserialzied.libraries) { - progressBar.post(() -> progressBar.incrementProgressBy(1)); - textView.post(() -> textView.setText("Restoring: " + DBNovel.NOVEL_URL)); - if (!Database.DatabaseLibrary.inLibrary(DBNovel.NOVEL_URL)) - Database.DatabaseLibrary.addToLibrary(DBNovel.FORMATTER_ID, DBNovel.NOVEL_PAGE, DBNovel.NOVEL_URL, DBNovel.STATUS); - - com.github.doomsdayrs.apps.shosetsu.variables.enums.Status status; - switch (DBNovel.STATUS) { - case 0: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD; - break; - case 1: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.READING; - break; - case 2: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.READ; - break; - case 3: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.ONHOLD; - break; - case 4: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.DROPPED; - break; - default: - status = null; - break; + + Log.i("Progress", "Restoring novels"); + for (int x = 0; x < novels.length(); x++) { + JSONObject novel = novels.getJSONObject(x); + String novelURL = novel.getString("novelURL"); + textView.post(() -> textView.setText("Restoring: " + novelURL)); + + if (!inLibrary(novelURL)) { + //TODO Novel } - if (status != null) - Database.DatabaseLibrary.setStatus(DBNovel.NOVEL_URL, status); - if (DBNovel.BOOKMARKED) - Database.DatabaseLibrary.bookMark(DBNovel.NOVEL_URL); + + progressBar.post(() -> progressBar.incrementProgressBy(1)); } Log.i("Progress", "Restoring chapters"); - for (com.github.doomsdayrs.apps.shosetsu.backend.database.objects.DBChapter DBChapter : superserialzied.DBChapters) { - textView.post(() -> textView.setText("Restoring: " + DBChapter.CHAPTER_URL)); + for (int x = 0; x < chapters.length(); x++) { + JSONObject chapter = chapters.getJSONObject(x); + String chapterURL = chapter.getString("chapterURL"); + String novelURL = chapter.getString("novelURL"); + + textView.post(() -> textView.setText("Restoring: " + novelURL + "|" + chapterURL)); progressBar.post(() -> progressBar.incrementProgressBy(1)); - if (!Database.DatabaseChapter.inChapters(DBChapter.CHAPTER_URL)) - Database.DatabaseChapter.addToChapters(DBChapter.NOVEL_URL, DBChapter.CHAPTER_URL, DBChapter.SAVED_DATA); - - Database.DatabaseChapter.updateY(DBChapter.CHAPTER_URL, DBChapter.Y); - - com.github.doomsdayrs.apps.shosetsu.variables.enums.Status status; - switch (DBChapter.READ_CHAPTER) { - case 0: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD; - break; - case 1: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.READING; - break; - case 2: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.READ; - break; - case 3: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.ONHOLD; - break; - case 4: - status = com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.DROPPED; - break; - default: - status = null; - break; + if (!inChapters(chapterURL)) { + //TODO Chapter= } - if (status != null) - Database.DatabaseChapter.setChapterStatus(DBChapter.CHAPTER_URL, status); - - if (DBChapter.BOOKMARKED) - Database.DatabaseChapter.setBookMark(DBChapter.CHAPTER_URL, 1); - //TODO settings backup } textView.post(() -> textView.setText("Restoring settings")); progressBar.post(() -> progressBar.incrementProgressBy(1)); - Settings.ReaderTextColor = superserialzied.settingsSerialized.reader_text_color; - Settings.ReaderTextBackgroundColor = superserialzied.settingsSerialized.reader_text_background_color; - shoDir = superserialzied.settingsSerialized.shoDir; - Settings.downloadPaused = superserialzied.settingsSerialized.paused; - Settings.ReaderTextSize = superserialzied.settingsSerialized.textSize; - Settings.themeMode = superserialzied.settingsSerialized.themeMode; - Settings.paragraphSpacing = superserialzied.settingsSerialized.paraSpace; - Settings.indentSize = superserialzied.settingsSerialized.indent; - - if (isTapToScroll() != superserialzied.settingsSerialized.tap_to_scroll) - toggleTapToScroll(); + //TODO Settings progressBar.post(() -> progressBar.incrementProgressBy(1)); return true; - } catch (IOException | ClassNotFoundException e) { + } catch (IOException | JSONException e) { e.printStackTrace(); } } - */ + return false; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json index 13f36b7b89..d27b451834 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json @@ -1,7 +1,6 @@ { "ignoreThis": "This is an example of schema for the backup, use it for reference. Strings should be serialized before being put into json, and each sub JSON should be serialized aswell", "ignoreThis2": "the type of data is specified in KEY, remove them and the spaces for a proper key for actual JSON files", - "settings": { "reader_text_color": "Settings.ReaderTextColor", "reader_text_background_color": "Settings.ReaderTextBackgroundColor", @@ -18,38 +17,39 @@ "novelURL": "serialize", "FORMATTER_ID": "", "STATUS": "ignore", - "bookmarked": "", - "novelPage": { - "title": "serialize", - "imageURL": "serialize", - "description": "serialize", - "genres": "serialize", - "authors": "serialize", - "status": "convert stati to an int and use a switch to set them", - "tags": [ - "Array of serialized strings" - ], - "artists": [ - "Array of serialized strings" - ], - "language": "serialize", - "maxChapterPage": "", - "novelChapters": "Just set this ARRAY to an empty one." - } + "bookmarked": "ignore, always true", + "reading_status": "ignore", + "reader_type": "", + "title": "serialize", + "imageURL": "serialize", + "description": "serialize", + "genres": "serialize", + "authors": "serialize", + "status": "convert stati to an int and use a switch to set them", + "tags": [ + "Array of serialized strings" + ], + "artists": [ + "Array of serialized strings" + ], + "language": "serialize", + "maxChapterPage": "" } ], + "chapters": [ { "novelURL": "serialize", "chapterURL": "serialize", - "SAVED_DATA": { - "": "This is some form of object, to decrypt on a later date" - }, + "title": "serialize", + "release_date": "serialize", + "order": "", + "Y": "", "READ_CHAPTER": "", "BOOKMARKED": "", - "IS_SAVED": "", - "SAVE_PATH": "serialize" + "IS_SAVED": "ignore, always 0", + "SAVE_PATH": "ignore" } ], "ignoreThis3": "No longer transferring download data" From 3be71a01c27c23805a7f944790a5a4f633b5d3f7 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 27 Oct 2019 20:15:37 -0400 Subject: [PATCH 033/162] One step closer --- .../backup/async/BackupProcess.java | 59 ++++++++++--------- .../backup/async/RestoreProcess.java | 48 ++++++++++++++- 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index 417bda8179..f03f3f46d5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -24,7 +24,9 @@ import android.util.Log; import com.github.doomsdayrs.apps.shosetsu.backend.Serialize; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; import org.json.JSONArray; import org.json.JSONException; @@ -75,40 +77,43 @@ protected Void doInBackground(Void... voids) { Log.i("Progress", "Backing up novels"); { final JSONArray NOVELS = new JSONArray(); - Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.NOVELS + " where " + Database.Columns.BOOKMARKED + "=1", null); + Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Tables.NOVELS + " where " + Columns.BOOKMARKED + "=1", null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { // Gets if it is in library, if not then it skips - boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); + boolean bookmarked = intToBoolean(cursor.getInt(cursor.getColumnIndex(Columns.BOOKMARKED.toString()))); Log.i("NovelBack", "Valid?: " + bookmarked); if (bookmarked) { - String nurl = getNovelURLfromNovelID(cursor.getInt(cursor.getColumnIndex(Database.Columns.PARENT_ID.toString()))); + String nurl = getNovelURLfromNovelID(cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString()))); JSONObject novel = new JSONObject(); - novel.put("novelURL", nurl); - novel.put("FORMATTER_ID", getFormatterIDFromNovelURL(nurl)); + novel.put(Columns.URL.toString(), nurl); + novel.put(Columns.FORMATTER_ID.toString(), getFormatterIDFromNovelURL(nurl)); - novel.put("title", cursor.getString(cursor.getColumnIndex(Database.Columns.TITLE.toString()))); + novel.put(Columns.READING_STATUS.toString(), cursor.getInt(cursor.getColumnIndex(Columns.READING_STATUS.toString()))); + novel.put(Columns.READER_TYPE.toString(), cursor.getInt(cursor.getColumnIndex(Columns.READER_TYPE.toString()))); - novel.put("imageURL", cursor.getString(cursor.getColumnIndex(Database.Columns.IMAGE_URL.toString()))); + novel.put(Columns.TITLE.toString(), cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); - novel.put("description", cursor.getString(cursor.getColumnIndex(Database.Columns.DESCRIPTION.toString()))); + novel.put(Columns.IMAGE_URL.toString(), cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString()))); - novel.put("genres", cursor.getString(cursor.getColumnIndex(Database.Columns.GENRES.toString()))); + novel.put(Columns.DESCRIPTION.toString(), cursor.getString(cursor.getColumnIndex(Columns.DESCRIPTION.toString()))); - novel.put("authors", cursor.getString(cursor.getColumnIndex(Database.Columns.AUTHORS.toString()))); + novel.put(Columns.GENRES.toString(), cursor.getString(cursor.getColumnIndex(Columns.GENRES.toString()))); - novel.put("status", cursor.getString(cursor.getColumnIndex(Database.Columns.STATUS.toString()))); + novel.put(Columns.AUTHORS.toString(), cursor.getString(cursor.getColumnIndex(Columns.AUTHORS.toString()))); - novel.put("tags", cursor.getString(cursor.getColumnIndex(Database.Columns.TAGS.toString()))); + novel.put(Columns.STATUS.toString(), cursor.getString(cursor.getColumnIndex(Columns.STATUS.toString()))); - novel.put("artists", cursor.getString(cursor.getColumnIndex(Database.Columns.ARTISTS.toString()))); + novel.put(Columns.TAGS.toString(), cursor.getString(cursor.getColumnIndex(Columns.TAGS.toString()))); - novel.put("language", cursor.getString(cursor.getColumnIndex(Database.Columns.LANGUAGE.toString()))); + novel.put(Columns.ARTISTS.toString(), cursor.getString(cursor.getColumnIndex(Columns.ARTISTS.toString()))); - novel.put("maxChapterPage", cursor.getInt(cursor.getColumnIndex(Database.Columns.MAX_CHAPTER_PAGE.toString()))); + novel.put(Columns.LANGUAGE.toString(), cursor.getString(cursor.getColumnIndex(Columns.LANGUAGE.toString()))); + + novel.put(Columns.MAX_CHAPTER_PAGE.toString(), cursor.getInt(cursor.getColumnIndex(Columns.MAX_CHAPTER_PAGE.toString()))); NOVELS.put(novel); } @@ -120,25 +125,25 @@ protected Void doInBackground(Void... voids) { Log.i("Progress", "Backing up Chapters"); { final JSONArray CHAPTERS = new JSONArray(); - Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Database.Tables.CHAPTERS, null); + Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Tables.CHAPTERS, null); if (!(cursor.getCount() <= 0)) while (cursor.moveToNext()) { - int novelID = cursor.getInt(cursor.getColumnIndex(Database.Columns.PARENT_ID.toString())); - boolean b = Database.DatabaseNovels.isBookmarked(novelID); + int novelID = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); + boolean b = DatabaseNovels.isBookmarked(novelID); if (b) { - int id = cursor.getInt(cursor.getColumnIndex(Database.Columns.ID.toString())); + int id = cursor.getInt(cursor.getColumnIndex(Columns.ID.toString())); JSONObject chapter = new JSONObject(); chapter.put("novelURL", getNovelURLfromNovelID(novelID)); - chapter.put("chapterURL", getChapterURLFromChapterID(id)); + chapter.put(Columns.URL.toString(), getChapterURLFromChapterID(id)); - chapter.put("title", cursor.getString(cursor.getColumnIndex(Database.Columns.TITLE.toString()))); - chapter.put("release_date", cursor.getString(cursor.getColumnIndex(Database.Columns.RELEASE_DATE.toString()))); - chapter.put("order", cursor.getInt(cursor.getColumnIndex(Database.Columns.ORDER.toString()))); + chapter.put(Columns.TITLE.toString(), cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + chapter.put(Columns.RELEASE_DATE.toString(), cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); + chapter.put(Columns.ORDER.toString(), cursor.getInt(cursor.getColumnIndex(Columns.ORDER.toString()))); - chapter.put("Y", cursor.getInt(cursor.getColumnIndex(Database.Columns.Y.toString()))); - chapter.put("READ_CHAPTER", cursor.getInt(cursor.getColumnIndex(Database.Columns.READ_CHAPTER.toString()))); - chapter.put("BOOKMARKED", cursor.getInt(cursor.getColumnIndex(Database.Columns.BOOKMARKED.toString()))); + chapter.put(Columns.Y.toString(), cursor.getInt(cursor.getColumnIndex(Columns.Y.toString()))); + chapter.put(Columns.READ_CHAPTER.toString(), cursor.getInt(cursor.getColumnIndex(Columns.READ_CHAPTER.toString()))); + chapter.put(Columns.BOOKMARKED.toString(), cursor.getInt(cursor.getColumnIndex(Columns.BOOKMARKED.toString()))); CHAPTERS.put(chapter); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index 015568bb16..0b6afea752 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -29,6 +29,8 @@ import android.widget.Toast; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; import org.json.JSONArray; import org.json.JSONException; @@ -40,7 +42,10 @@ import java.io.IOException; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.inChapters; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.inLibrary; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.sqLiteDatabase; /** * shosetsu @@ -125,11 +130,50 @@ protected Boolean doInBackground(Void... voids) { Log.i("Progress", "Restoring novels"); for (int x = 0; x < novels.length(); x++) { JSONObject novel = novels.getJSONObject(x); - String novelURL = novel.getString("novelURL"); + String novelURL = novel.getString(Columns.URL.toString()); textView.post(() -> textView.setText("Restoring: " + novelURL)); if (!inLibrary(novelURL)) { - //TODO Novel + addNovel(novelURL, novel.getInt(Columns.FORMATTER_ID.toString())); + int id = getNovelIDFromNovelURL(novelURL); + try { + sqLiteDatabase.execSQL("insert into " + Tables.NOVELS + "(" + + Columns.PARENT_ID + "," + + Columns.BOOKMARKED + "," + + Columns.READING_STATUS + "," + + Columns.READER_TYPE + "," + + Columns.TITLE + "," + + Columns.IMAGE_URL + "," + + Columns.DESCRIPTION + "," + + Columns.GENRES + "," + + Columns.AUTHORS + "," + + Columns.STATUS + "," + + Columns.TAGS + "," + + Columns.ARTISTS + "," + + Columns.LANGUAGE + "," + + Columns.MAX_CHAPTER_PAGE + + ")" + "values" + "(" + + id + "," + + 1 + "," + + novel.getInt(Columns.READING_STATUS.toString()) + "," + + novel.getInt(Columns.READER_TYPE.toString()) + "," + + "'" + novel.getString(Columns.TITLE.toString()) + "'," + + "'" + novel.getString(Columns.IMAGE_URL.toString()) + "'," + + "'" + novel.getString(Columns.DESCRIPTION.toString()) + "'," + + "'" + novel.getString(Columns.GENRES.toString()) + "'," + + "'" + novel.getString(Columns.AUTHORS.toString()) + "'," + + "'" + novel.getInt(Columns.STATUS.toString()) + "'," + + "'" + novel.getString(Columns.TAGS.toString()) + "'," + + "'" + novel.getString(Columns.ARTISTS.toString()) + "'," + + "'" + novel.getString(Columns.LANGUAGE.toString()) + "'," + + novel.getInt(Columns.MAX_CHAPTER_PAGE.toString()) + + ")"); + + } catch (Exception e) { + e.printStackTrace(); + } + } else { + //TODO Novel if exists } From 39cea2bc0d5c4bdbd1f33795e3cb04362477dd56 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 28 Oct 2019 21:01:18 -0400 Subject: [PATCH 034/162] Fuck android file manager --- app/build.gradle | 6 +-- .../shosetsu/backend/database/Database.java | 4 +- .../subFragments/backup/BackupSettings.java | 3 +- .../backup/async/RestoreProcess.java | 43 ++++++++++++++++++- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4aac93a5d8..1bab69adb9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,18 +47,18 @@ repositories { } dependencies { - implementation 'com.google.android.material:material:1.1.0-beta01' + implementation 'com.google.android.material:material:1.2.0-alpha01' implementation 'com.graphql-java:graphql-java:2019-09-07T08-08-53-173312e' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible - implementation 'com.google.android.material:material:1.1.0-beta01' + implementation 'com.google.android.material:material:1.2.0-alpha01' testImplementation 'junit:junit:4.13-beta-3' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' - implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.3' + implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.4' implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.2' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 3bc1706217..79a04c29c5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -633,7 +633,7 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { String title = checkStringSerialize(novelChapter.title); String release = checkStringSerialize(novelChapter.release); - + System.out.println(novelChapter.link + " | " + novelChapter.order); try { sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + "(" + @@ -759,7 +759,7 @@ public static boolean isBookmarked(String novelURL) { } public static boolean isBookmarked(int novelID) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID , null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return false; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java index 43408f6c1a..9e8d91c1da 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java @@ -80,7 +80,8 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d String fileEnding = path.substring(i + 1); if (fileEnding.equalsIgnoreCase("shoback")) { Log.i("Selected Folder", "Uri: " + path); - new RestoreProcess(path.substring(path.indexOf("storage")), getContext()).execute(); + //TODO Fix this shit, need's a proper intergrated file manager + new RestoreProcess("/Shosetsu/backup/backup-Mon Oct 28 20:46:16 EDT 2019.shoback", getContext()).execute(); } else Toast.makeText(getContext(), "Invalid file to use!", Toast.LENGTH_LONG).show(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index 0b6afea752..69957946a2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -43,6 +43,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.inChapters; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.inLibrary; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.sqLiteDatabase; @@ -173,7 +174,12 @@ protected Boolean doInBackground(Void... voids) { e.printStackTrace(); } } else { - //TODO Novel if exists + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + + Columns.BOOKMARKED + "=1," + + Columns.READING_STATUS + "=" + novel.get(Columns.READING_STATUS.toString()) + "," + + Columns.READER_TYPE + "=" + novel.get(Columns.READER_TYPE.toString()) + + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL) + ); } @@ -189,7 +195,40 @@ protected Boolean doInBackground(Void... voids) { textView.post(() -> textView.setText("Restoring: " + novelURL + "|" + chapterURL)); progressBar.post(() -> progressBar.incrementProgressBy(1)); if (!inChapters(chapterURL)) { - //TODO Chapter= + int novelID = getNovelIDFromNovelURL(novelURL); + int chapterID = getChapterIDFromChapterURL(chapterURL); + + sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + + "(" + + Columns.ID + "," + + Columns.PARENT_ID + "," + + Columns.TITLE + "," + + Columns.RELEASE_DATE + "," + + Columns.ORDER + "," + + Columns.Y + "," + + Columns.READ_CHAPTER + "," + + Columns.BOOKMARKED + "," + + Columns.IS_SAVED + + ") " + + "values" + + "(" + + chapterID + "," + + novelID + ",'" + + chapter.getString(Columns.TITLE.toString()) + "','" + + chapter.getString(Columns.RELEASE_DATE.toString()) + "'," + + chapter.getInt(Columns.ORDER.toString()) + "," + + chapter.getInt(Columns.Y.toString()) + "," + + chapter.getInt(Columns.READ_CHAPTER.toString()) + "," + + chapter.getInt(Columns.BOOKMARKED.toString()) + "," + + 0 + ")") + ; + } else { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + + Columns.Y + "=1," + + Columns.READ_CHAPTER + "=" + chapter.get(Columns.READING_STATUS.toString()) + "," + + Columns.BOOKMARKED + "=" + chapter.get(Columns.READER_TYPE.toString()) + + " where " + Columns.ID + "=" + getChapterIDFromChapterURL(chapter.getString(Columns.URL.toString())) + ); } } From 782c7f8136c041f7f714f97a0c278c83ed5b7a85 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Tue, 29 Oct 2019 06:37:30 -0400 Subject: [PATCH 035/162] Working out the bugs of Backup/Restore, using new library to retrieve files --- app/build.gradle | 2 ++ .../subFragments/backup/BackupSettings.java | 26 ++++++++++++++----- .../backup/async/RestoreProcess.java | 15 ++++++----- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1bab69adb9..55c34d3bef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,6 +76,8 @@ dependencies { implementation 'joda-time:joda-time:2.10.3' + implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8' + // TODO Implement readerview provided by Mozilla //implementation "org.mozilla.components:feature-readerview:1.0.0" //implementation 'org.mozilla.components:support-base:1.0.0' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java index 9e8d91c1da..9e066759e4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/BackupSettings.java @@ -38,6 +38,11 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.ui.settings.subFragments.backup.async.BackupProcess; import com.github.doomsdayrs.apps.shosetsu.ui.settings.subFragments.backup.async.RestoreProcess; +import com.vincent.filepicker.Constant; +import com.vincent.filepicker.activity.NormalFilePickActivity; +import com.vincent.filepicker.filter.entity.NormalFile; + +import java.util.ArrayList; public class BackupSettings extends Fragment { @@ -61,17 +66,24 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c private void performFileSelection() { Toast.makeText(getContext(), "Please make sure this is on the main storage, SD card storage is not functional yet", Toast.LENGTH_LONG).show(); - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.setType("*/*"); - intent.addCategory(Intent.CATEGORY_OPENABLE); - startActivityForResult(intent, 69); + + Intent intent = new Intent(getContext(), NormalFilePickActivity.class); + intent.putExtra(Constant.MAX_NUMBER, 9); + intent.putExtra(NormalFilePickActivity.SUFFIX, new String[]{"shoback", "json"}); + startActivityForResult(intent, Constant.REQUEST_CODE_PICK_FILE); } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == 69 && resultCode == Activity.RESULT_OK) { - if (data != null && data.getData() != null && data.getData().getPath() != null) { + if (Constant.REQUEST_CODE_PICK_FILE == requestCode && resultCode == Activity.RESULT_OK) { + if (data != null) { + ArrayList list = data.getParcelableArrayListExtra(Constant.RESULT_PICK_FILE); + if (list != null && list.size() > 0) { + NormalFile normalFile = list.get(0); + new RestoreProcess(normalFile.getPath(), getContext()).execute(); + } + /* String path = data.getData().getPath(); Log.i("SelectedPath", path); @@ -84,7 +96,7 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d new RestoreProcess("/Shosetsu/backup/backup-Mon Oct 28 20:46:16 EDT 2019.shoback", getContext()).execute(); } else Toast.makeText(getContext(), "Invalid file to use!", Toast.LENGTH_LONG).show(); - } + }*/ } } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index 69957946a2..d33f49eb09 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -29,6 +29,7 @@ import android.widget.Toast; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; @@ -120,7 +121,7 @@ protected Boolean doInBackground(Void... voids) { } bufferedReader.close(); } - final JSONObject BACKUP = new JSONObject(string.substring(6)); + final JSONObject BACKUP = new JSONObject(string.substring(7)); JSONArray novels = BACKUP.getJSONArray("novels"); JSONArray chapters = BACKUP.getJSONArray("chapters"); @@ -163,7 +164,7 @@ protected Boolean doInBackground(Void... voids) { "'" + novel.getString(Columns.DESCRIPTION.toString()) + "'," + "'" + novel.getString(Columns.GENRES.toString()) + "'," + "'" + novel.getString(Columns.AUTHORS.toString()) + "'," + - "'" + novel.getInt(Columns.STATUS.toString()) + "'," + + "'" + novel.getString(Columns.STATUS.toString()) + "'," + "'" + novel.getString(Columns.TAGS.toString()) + "'," + "'" + novel.getString(Columns.ARTISTS.toString()) + "'," + "'" + novel.getString(Columns.LANGUAGE.toString()) + "'," + @@ -189,13 +190,15 @@ protected Boolean doInBackground(Void... voids) { Log.i("Progress", "Restoring chapters"); for (int x = 0; x < chapters.length(); x++) { JSONObject chapter = chapters.getJSONObject(x); - String chapterURL = chapter.getString("chapterURL"); + String chapterURL = chapter.getString(Columns.URL.toString()); String novelURL = chapter.getString("novelURL"); textView.post(() -> textView.setText("Restoring: " + novelURL + "|" + chapterURL)); progressBar.post(() -> progressBar.incrementProgressBy(1)); if (!inChapters(chapterURL)) { int novelID = getNovelIDFromNovelURL(novelURL); + + Database.DatabaseIdentification.addChapter(novelID, chapterURL); int chapterID = getChapterIDFromChapterURL(chapterURL); sqLiteDatabase.execSQL("insert into " + Tables.CHAPTERS + @@ -224,9 +227,9 @@ protected Boolean doInBackground(Void... voids) { ; } else { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + - Columns.Y + "=1," + - Columns.READ_CHAPTER + "=" + chapter.get(Columns.READING_STATUS.toString()) + "," + - Columns.BOOKMARKED + "=" + chapter.get(Columns.READER_TYPE.toString()) + + Columns.Y + "=" + chapter.getString(Columns.Y.toString()) + "," + + Columns.READ_CHAPTER + "=" + chapter.getString(Columns.READ_CHAPTER.toString()) + "," + + Columns.BOOKMARKED + "=" + chapter.getString(Columns.BOOKMARKED.toString()) + " where " + Columns.ID + "=" + getChapterIDFromChapterURL(chapter.getString(Columns.URL.toString())) ); } From 271754cec1c0c155ed1785b467a8aa981aa7a093 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Tue, 29 Oct 2019 20:25:28 -0400 Subject: [PATCH 036/162] Cant figure out error in updates db --- .../shosetsu/backend/database/Database.java | 26 +++++++++++-------- .../adapters/UpdatedChaptersAdapter.java | 11 ++++++-- .../viewHolder/UpdatedChapterHolder.java | 10 +++---- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 79a04c29c5..f284ab9904 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -712,21 +712,25 @@ else if (novelChapter.order > t1.order) * @return */ public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return null; } else { - NovelChapter novelChapter = null; - try { - novelChapter = new NovelChapter(); - novelChapter.title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); - novelChapter.link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); - novelChapter.release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); - novelChapter.order = cursor.getDouble(cursor.getColumnIndex(Columns.ORDER.toString())); - } catch (Exception e) { - e.printStackTrace(); - } + NovelChapter novelChapter = new NovelChapter(); + + String title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + String link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); + String release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); + double order = cursor.getDouble(cursor.getColumnIndex(Columns.ORDER.toString())); + + novelChapter.title = title; + + novelChapter.link = link; + novelChapter.release = release; + novelChapter.order = order; + + return novelChapter; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index bff2e0671c..85c3e59345 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Download_Manager; @@ -21,7 +22,6 @@ import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import java.util.ArrayList; -import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; @@ -79,7 +79,14 @@ public UpdatedChapterHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int @Override public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, int i) { Log.d("Binding", updates.get(i).CHAPTER_URL); - updatedChapterHolder.setNovelChapter(Objects.requireNonNull(DatabaseChapter.getChapter(updates.get(i).CHAPTER_URL))); + NovelChapter novelChapter = DatabaseChapter.getChapter(updates.get(i).CHAPTER_URL); + if (novelChapter != null) { + updatedChapterHolder.setNovelChapter(novelChapter); + } else { + + throw new NullPointerException("NovelChapter returned null"); + } + updatedChapterHolder.popupMenu.setOnMenuItemClickListener(menuItem -> { NovelPage novelPage = new NovelPage(); String nURL = Database.DatabaseIdentification.getNovelURLFromChapterURL(updatedChapterHolder.novelChapter.link); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 536879af54..79b1a7a9e4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -31,10 +31,9 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; +import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; import com.squareup.picasso.Picasso; -import java.util.Objects; - import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; @@ -70,13 +69,10 @@ public UpdatedChapterHolder(@NonNull View itemView) { public void setNovelChapter(NovelChapter novelChapter) { this.novelChapter = novelChapter; title.setText(novelChapter.title); + NovelCard novelCard = Database.DatabaseNovels.getNovel(Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link)); Picasso.get() .load( - Objects.requireNonNull( - Database.DatabaseNovels.getNovel( - Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link) - ) - ).imageURL) + novelCard.imageURL) .into(image); itemView.setOnClickListener(this); } From ed2832b69f9be3908ea3d452c5f3033e07898023 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 31 Oct 2019 19:08:35 -0400 Subject: [PATCH 037/162] Fixed issue, Moving to refactor data paths --- .../doomsdayrs/apps/shosetsu/backend/database/Database.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index f284ab9904..cedb5ee626 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -712,13 +712,13 @@ else if (novelChapter.order > t1.order) * @return */ public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select * from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.TITLE + "," + Columns.ID + "," + Columns.RELEASE_DATE + "," + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); if (cursor.getCount() <= 0) { cursor.close(); return null; } else { + cursor.moveToNext(); NovelChapter novelChapter = new NovelChapter(); - String title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); String link = DatabaseIdentification.getChapterURLFromChapterID(cursor.getInt(cursor.getColumnIndex(Columns.ID.toString()))); String release = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.RELEASE_DATE.toString()))); @@ -923,7 +923,7 @@ public static NovelCard getNovel(String novelURL) { NovelCard novelCard = new NovelCard( checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), novelURL, - checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString()))), + cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())), DatabaseIdentification.getFormatterIDFromNovelID(parent) ); cursor.close(); From a89ab03d3f90f32385b12c65d1d51933326c7692 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 31 Oct 2019 19:22:50 -0400 Subject: [PATCH 038/162] Working on not using URL's anymore, instead using ints to decrease db back and forth --- .../shosetsu/backend/database/Database.java | 62 ++++++++++++------- .../catalogue/async/NovelBackgroundAdd.java | 2 +- .../apps/shosetsu/ui/novel/NovelFragment.java | 18 +++--- .../apps/shosetsu/ui/novel/StaticNovel.java | 34 +--------- .../shosetsu/ui/reader/ChapterReader.java | 6 +- .../backup/async/RestoreProcess.java | 4 +- 6 files changed, 58 insertions(+), 68 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index cedb5ee626..5f20bf8baf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -190,7 +190,7 @@ public static int getNovelIDFromNovelURL(String url) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " ='" + url + "'", null); if (cursor.getCount() <= 0) { cursor.close(); - return 0; + return -1; } else { cursor.moveToNext(); int id = cursor.getInt(cursor.getColumnIndex(Columns.ID.toString())); @@ -741,10 +741,14 @@ public static class DatabaseNovels { /** * Bookmarks the novel * - * @param novelURL novelURL of the novel + * @param novelID novelID of the novel */ - public static void bookMark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL)); + public static void bookMark(int novelID) { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.PARENT_ID + "=" + novelID); + } + + public static void bookMark(String novelURL) { + bookMark(getNovelIDFromNovelURL(novelURL)); } /** @@ -775,18 +779,22 @@ public static boolean isBookmarked(int novelID) { return a > 0; } + public static void setReaderType(@NotNull int novelID, int reader) { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.ID + "=" + novelID); + } + public static void setReaderType(@NotNull String novelURL, int reader) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); + setReaderType(getNovelIDFromNovelURL(novelURL), reader); } /** * Gets reader type for novel * - * @param novelURL Novel URL + * @param novelID novelID * @return -2 is no such novel, -1 is default, 0 is the same as -1, and 1+ is a specific reading type */ - public static int getReaderType(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READER_TYPE + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + getNovelIDFromNovelURL(novelURL), null); + public static int getReaderType(int novelID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READER_TYPE + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return -2; @@ -798,10 +806,13 @@ public static int getReaderType(@NotNull String novelURL) { return a; } + public static int getReaderType(String novelURL) { + return getReaderType(getNovelIDFromNovelURL(novelURL)); + } - public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @NotNull String novelURL, int readingStatus) { + + public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, String novelURL, int readingStatus) { addNovel(novelURL, formatter); - int id = getNovelIDFromNovelURL(novelURL); String imageURL = novelPage.imageURL; if (imageURL == null) imageURL = ""; @@ -823,7 +834,7 @@ public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, @No Columns.LANGUAGE + "," + Columns.MAX_CHAPTER_PAGE + ")" + "values" + "(" + - id + "," + + getNovelIDFromNovelURL(novelURL) + "," + 0 + "," + readingStatus + "," + -1 + "," + @@ -859,11 +870,11 @@ public static boolean removeFromLibrary(@NotNull String novelURL) { /** * Is a novel in the library or not * - * @param novelURL Novel novelURL + * @param novelID Novel novelID * @return yes or no */ - public static boolean inLibrary(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.URL + " ='" + novelURL + "'", null); + public static boolean inDatabase(int novelID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.ID + " ='" + novelID + "'", null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -872,6 +883,10 @@ public static boolean inLibrary(@NotNull String novelURL) { return true; } + public static boolean inDatabase(String novelURL) { + return -1 != getNovelIDFromNovelURL(novelURL); + } + /** * Get's the entire library to be listed * @@ -938,11 +953,10 @@ public static NovelCard getNovel(String novelURL) { /** * Gets saved novelPage * - * @param novelURL novelURL to retrieve + * @param novelID novel to retrieve * @return Saved novelPage */ - public static NovelPage getNovelPage(@NotNull String novelURL) { - int ID = getNovelIDFromNovelURL(novelURL); + public static NovelPage getNovelPage(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.TITLE + "," + Columns.IMAGE_URL + "," + @@ -954,7 +968,7 @@ public static NovelPage getNovelPage(@NotNull String novelURL) { Columns.ARTISTS + "," + Columns.LANGUAGE + "," + Columns.MAX_CHAPTER_PAGE + - " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + ID, null); + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -985,8 +999,12 @@ public static void setStatus(@NotNull String novelURL, @NotNull Status status) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'"); } - public static Status getStatus(@NotNull String novelURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READING_STATUS + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + " =" + getNovelIDFromNovelURL(novelURL), null); + public static Status getStatus(String novelURL) { + return getStatus(getNovelIDFromNovelURL(novelURL)); + } + + public static Status getStatus(int novelID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READING_STATUS + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); return Status.UNREAD; @@ -1025,9 +1043,9 @@ public static void updateData(@NotNull String novelURL, @NotNull NovelPage novel } - public static void migrateNovel(@NotNull String oldURL, @NotNull String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { + public static void migrateNovel(@NotNull String oldURL, String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { unBookmark(oldURL); - if (!DatabaseNovels.inLibrary(newURL)) + if (!DatabaseNovels.inDatabase(newURL)) addToLibrary(formatterID, newNovel, newURL, status); bookMark(newURL); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index 9f35a48623..d6303fd082 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -39,7 +39,7 @@ public NovelBackgroundAdd(NovelCardViewHolder novelCardsViewHolder) { @Override protected Void doInBackground(View... views) { try { - if (!Database.DatabaseNovels.inLibrary(novelCardsViewHolder.url)) { + if (!Database.DatabaseNovels.inDatabase(novelCardsViewHolder.url)) { Database.DatabaseNovels.addToLibrary(novelCardsViewHolder.formatter.getID(), novelCardsViewHolder.formatter.parseNovel(novelCardsViewHolder.url), novelCardsViewHolder.url, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 6baeae7779..da1188783f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -69,7 +69,6 @@ public NovelFragment() { setHasOptionsMenu(true); } - @Override public void onDestroy() { super.onDestroy(); @@ -87,6 +86,7 @@ public void onDestroy() { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d("OnCreateView", "NovelFragment"); View view = inflater.inflate(R.layout.fragment_novel, container, false); + // Attach UI to program { progressBar = view.findViewById(R.id.fragment_novel_progress); viewPager = view.findViewById(R.id.fragment_novel_viewpager); @@ -95,15 +95,19 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c errorMessage = view.findViewById(R.id.error_message); errorButton = view.findViewById(R.id.error_button); } - novelFragmentMain = new NovelFragmentMain(); - novelFragmentMain.setNovelFragment(this); - novelFragmentChapters = new NovelFragmentChapters(); - novelFragmentChapters.setNovelFragment(this); + + // Create sub-fragments + { + novelFragmentMain = new NovelFragmentMain(); + novelFragmentMain.setNovelFragment(this); + novelFragmentChapters = new NovelFragmentChapters(); + novelFragmentChapters.setNovelFragment(this); + } //TODO FINISH TRACKING //boolean track = SettingsController.isTrackingEnabled(); if (savedInstanceState == null) { - if (isOnline() && !Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { + if (isOnline() && !Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { setViewPager(); if (StaticNovel.novelLoader != null && !StaticNovel.novelLoader.isCancelled()) { @@ -114,7 +118,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c StaticNovel.novelLoader.execute(getActivity()); } else { - StaticNovel.novelPage = Database.DatabaseNovels.getNovelPage(StaticNovel.novelURL); + StaticNovel.novelPage = Database.DatabaseNovels.getNovelPage(StaticNovel.novelID); StaticNovel.status = Database.DatabaseNovels.getStatus(StaticNovel.novelURL); if (StaticNovel.novelPage != null) Statics.mainActionBar.setTitle(StaticNovel.novelPage.title); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java index b77eeced9f..b33359cb0a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java @@ -42,7 +42,7 @@ public class StaticNovel { /** * Global variable of the current loaded novel */ - public static String novelURL; + public static int novelID; public static NovelPage novelPage; public static List novelChapters = new ArrayList<>(); @@ -111,36 +111,4 @@ public static int lastRead() { } else return -2; } else return -1; } - - - public static void destroy() { - formatter = null; - novelChapters = null; - novelURL = null; - novelPage = null; - - if (novelLoader != null) { - if (!novelLoader.isCancelled()) { - novelLoader.setC(false); - novelLoader.cancel(true); - } - novelLoader = null; - } - if (novelLoader != null) { - if (!novelLoader.isCancelled()) { - novelLoader.setC(false); - novelLoader.cancel(true); - } - novelLoader = null; - } - - if (chapterLoader != null) { - if (!chapterLoader.isCancelled()) { - chapterLoader.setC(false); - chapterLoader.cancel(true); - } - chapterLoader = null; - } - status = Status.UNREAD; - } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index c823d3dcc8..dccae9acb9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -50,7 +50,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.getNextChapter; -import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.novelURL; +import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.novelID; /* * This file is part of Shosetsu. @@ -213,7 +213,7 @@ public boolean onCreateOptionsMenu(Menu menu) { readers[0] = menu.findItem(R.id.reader_0); readers[1] = menu.findItem(R.id.reader_1); - readerType = getReaderType(novelURL); + readerType = getReaderType(novelID); switch (readerType) { case 1: @@ -566,7 +566,7 @@ private class ReaderChange implements Utilities.DemarkAction { @Override public void action(int spared) { readerType = spared; - setReaderType(novelURL, spared); + setReaderType(novelID, spared); setUpReader(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index d33f49eb09..fe5dbb038e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -46,7 +46,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.addNovel; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.inLibrary; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.inDatabase; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.sqLiteDatabase; /** @@ -135,7 +135,7 @@ protected Boolean doInBackground(Void... voids) { String novelURL = novel.getString(Columns.URL.toString()); textView.post(() -> textView.setText("Restoring: " + novelURL)); - if (!inLibrary(novelURL)) { + if (!inDatabase(novelURL)) { addNovel(novelURL, novel.getInt(Columns.FORMATTER_ID.toString())); int id = getNovelIDFromNovelURL(novelURL); try { From 9ea32099cae3ff187fac7d7ad86bb1ac3773384e Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 1 Nov 2019 22:36:36 -0400 Subject: [PATCH 039/162] refactor, refactor, refactor, refactor, refactor a hundred more times. Progress on rewrite is going well, As now I removing old methods that use more resources, and trying to streamline data transfer in the program --- app/src/main/AndroidManifest.xml | 2 +- .../apps/shosetsu/backend/Utilities.java | 15 +- .../shosetsu/backend/database/Database.java | 154 +++++++++++++----- .../shosetsu/backend/tracking/Anilist.java | 2 +- .../catalogue/async/CataloguePageLoader.java | 2 +- .../catalogue/async/CatalogueQuerySearch.java | 1 + .../listeners/CatalogueHitBottom.java | 4 +- .../viewHolders/LibraryViewHolder.java | 2 +- .../adapters/MigratingMapAdapter.java | 2 +- .../apps/shosetsu/ui/novel/StaticNovel.java | 13 ++ .../ui/novel/adapters/ChaptersAdapter.java | 12 +- .../shosetsu/ui/novel/async/NovelLoader.java | 4 +- .../NovelFragmentMainAddToLibrary.java | 13 +- .../ui/novel/pages/NovelFragmentChapters.java | 7 +- .../ui/novel/pages/NovelFragmentMain.java | 2 +- .../novel/viewHolders/ChaptersViewHolder.java | 13 +- .../shosetsu/ui/reader/ChapterReader.java | 23 ++- .../ui/settings/SettingsFragment.java | 1 + .../settings/subFragments/InfoSettings.java | 14 +- .../subFragments/backup/async/schema.json | 2 - .../adapters/UpdatedChaptersAdapter.java | 4 +- .../apps/shosetsu/ui/webView/WebViewApp.java | 1 - .../apps/shosetsu/variables/DownloadItem.java | 20 ++- .../apps/shosetsu/variables/enums/Status.java | 3 +- .../variables/recycleObjects/NovelCard.java | 6 +- .../recycleObjects/SettingsItem.java | 10 +- app/src/main/res/layout/nav_header.xml | 1 - app/src/main/res/layout/toolbar_main.xml | 4 +- .../main/res/layout/updated_novel_card.xml | 1 + app/src/main/res/menu/toolbar_chapters.xml | 2 +- 30 files changed, 226 insertions(+), 114 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bf7a1253f9..c11a3018c1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,7 +23,7 @@ android:theme="@style/Theme.MaterialComponents" tools:ignore="GoogleAppIndexingWarning" android:requestLegacyExternalStorage="true" - tools:targetApi="n"> + tools:targetApi="q"> getDownloadList() { String nName = cursor.getString(cursor.getColumnIndex(Columns.NOVEL_NAME.toString())); String cName = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_NAME.toString())); int formatter = cursor.getInt(cursor.getColumnIndex(Columns.FORMATTER_ID.toString())); - downloadItems.add(new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, DatabaseIdentification.getNovelURLFromChapterID(id), DatabaseIdentification.getChapterURLFromChapterID(id))); + downloadItems.add(new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, id)); } cursor.close(); @@ -372,7 +372,7 @@ public static DownloadItem getFirstDownload() { String cName = cursor.getString(cursor.getColumnIndex(Columns.CHAPTER_NAME.toString())); int formatter = getFormatterIDFromChapterID(id); cursor.close(); - return new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, DatabaseIdentification.getNovelURLFromChapterID(id), DatabaseIdentification.getChapterURLFromChapterID(id)); + return new DownloadItem(DefaultScrapers.getByID(formatter), nName, cName, id); } } @@ -439,40 +439,50 @@ public static void purgeUneededCache() { } /** - * @param novelURL URL of novel + * @param novelID ID of novel * @return Count of chapters left to read */ - public static int getCountOfChaptersUnread(String novelURL) { - int novelID = getNovelIDFromNovelURL(novelURL); + public static int getCountOfChaptersUnread(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + "=" + novelID + "" + " and " + Columns.READ_CHAPTER + "!=" + Status.READ, null); int count = cursor.getCount(); cursor.close(); return count; } - public static void updateOrder(String chapterURL, int order) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.ORDER + "='" + order + "' where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + @Deprecated + public static int getCountOfChaptersUnread(String novelURL) { + return getCountOfChaptersUnread(getNovelIDFromNovelURL(novelURL)); + } + + public static void updateOrder(int chapterID, int order) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.ORDER + "='" + order + "' where " + Columns.ID + "=" + chapterID); } /** * Updates the Y coordinate * Precondition is the chapter is already in the database. * - * @param chapterURL novelURL to update - * @param y integer value scroll + * @param chapterID ID to update + * @param y integer value scroll */ + + public static void updateY(int chapterID, int y) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.ID + "=" + chapterID); + } + + @Deprecated public static void updateY(String chapterURL, int y) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + updateY(DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), y); } /** * Precondition is the chapter is already in the database * - * @param chapterURL chapterURL to the chapter + * @param chapterID chapterID to the chapter * @return order of chapter */ - public static int getY(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + public static int getY(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.Y + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); return 0; @@ -484,12 +494,17 @@ public static int getY(String chapterURL) { } } + @Deprecated + public static int getY(String chapterURL) { + return getY(DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + } + /** - * @param chapterURL chapter to check + * @param chapterID chapter to check * @return returns chapter status */ - public static Status getStatus(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + public static Status getStatus(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); return Status.UNREAD; @@ -506,35 +521,49 @@ else if (y == 1) } } + @Deprecated + public static Status getStatus(String chapterURL) { + return getStatus(getChapterIDFromChapterURL(chapterURL)); + } + /** * Sets chapter status * - * @param chapterURL chapter to be set - * @param status status to be set + * @param chapterID chapter to be set + * @param status status to be set */ + public static void setChapterStatus(int chapterID, Status status) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + chapterID); + } + + @Deprecated public static void setChapterStatus(String chapterURL, Status status) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + setChapterStatus(getChapterIDFromChapterURL(chapterURL), status); } /** * Sets bookmark true or false (1 for true, 0 is false) * - * @param chapterURL chapter chapterURL - * @param b 1 is true, 0 is false + * @param chapterID chapterID + * @param b 1 is true, 0 is false */ - public static void setBookMark(String chapterURL, int b) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.BOOKMARKED + "=" + b + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + public static void setBookMark(int chapterID, int b) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.BOOKMARKED + "=" + b + " where " + Columns.ID + "=" + chapterID); + } + @Deprecated + public static void setBookMark(String chapterURL, int b) { + setBookMark(getChapterIDFromChapterURL(chapterURL), b); } /** * is this chapter bookmarked? * - * @param chapterURL imageURL to the chapter + * @param chapterID * @return if bookmarked? */ - public static boolean isBookMarked(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + public static boolean isBookMarked(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); return false; @@ -547,34 +576,48 @@ public static boolean isBookMarked(String chapterURL) { } + @Deprecated + public static boolean isBookMarked(String chapterURL) { + return isBookMarked(getChapterIDFromChapterURL(chapterURL)); + } + /** * Removes save path from chapter * - * @param chapterURL chapter to remove save path of + * @param chapterID chapter to remove save path of */ + public static void removePath(int chapterID) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "=null," + Columns.IS_SAVED + "=0 where " + Columns.ID + "=" + chapterID); + } + + @Deprecated public static void removePath(String chapterURL) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "=null," + Columns.IS_SAVED + "=0 where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + removePath(getChapterIDFromChapterURL(chapterURL)); } /** * Adds save path * - * @param chapterURL chapter to update + * @param chapterID chapter to update * @param chapterPath save path to set */ + public static void addSavedPath(int chapterID, String chapterPath) { + sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "='" + chapterPath + "'," + Columns.IS_SAVED + "=1 where " + Columns.ID + "=" + chapterID); + } + public static void addSavedPath(String chapterURL, String chapterPath) { - sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "='" + chapterPath + "'," + Columns.IS_SAVED + "=1 where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); + addSavedPath(getChapterIDFromChapterURL(chapterURL), chapterPath); } /** * Is the chapter saved * - * @param chapterURL novelURL of the chapter + * @param chapterID novelURL of the chapter * @return true if saved, false otherwise */ - public static boolean isSaved(String chapterURL) { + public static boolean isSaved(int chapterID) { // Log.d("CheckSave", chapterURL); - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.IS_SAVED + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); // Log.d("CheckSave", chapterURL + " FALSE"); @@ -589,14 +632,19 @@ public static boolean isSaved(String chapterURL) { } } + @Deprecated + public static boolean isSaved(String chapterURL) { + return isSaved(getChapterIDFromChapterURL(chapterURL)); + } + /** * Gets the novel from local storage * - * @param chapterURL novelURL of the chapter + * @param chapterID novelURL of the chapter * @return String of passage */ - public static String getSavedNovelPassage(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.SAVE_PATH + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + public static String getSavedNovelPassage(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.SAVE_PATH + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -608,6 +656,11 @@ public static String getSavedNovelPassage(String chapterURL) { } } + @Deprecated + public static String getSavedNovelPassage(String chapterURL) { + return getSavedNovelPassage(getChapterIDFromChapterURL(chapterURL)); + } + /** * If the chapter URL is present or not * @@ -661,9 +714,9 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { } } + @Deprecated public static List getChapters(String novelURL) { - int novelID = getNovelIDFromNovelURL(novelURL); - return getChapters(novelID); + return getChapters(getNovelIDFromNovelURL(novelURL)); } /** @@ -708,11 +761,11 @@ else if (novelChapter.order > t1.order) /** * Gets a chapter by it's URL * - * @param chapterURL + * @param chapterID * @return */ - public static NovelChapter getChapter(String chapterURL) { - Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.TITLE + "," + Columns.ID + "," + Columns.RELEASE_DATE + "," + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), null); + public static NovelChapter getChapter(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.TITLE + "," + Columns.ID + "," + Columns.RELEASE_DATE + "," + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { cursor.close(); return null; @@ -734,6 +787,11 @@ public static NovelChapter getChapter(String chapterURL) { return novelChapter; } } + + @Deprecated + public static NovelChapter getChapter(String chapterURL) { + return getChapter(getChapterIDFromChapterURL(chapterURL)); + } } public static class DatabaseNovels { @@ -758,7 +816,11 @@ public static void bookMark(String novelURL) { * @return if removed successfully */ public static void unBookmark(@NotNull String novelURL) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + getNovelIDFromNovelURL(novelURL)); + unBookmark(getNovelIDFromNovelURL(novelURL)); + } + + public static void unBookmark(int novelID) { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + novelID); } @@ -908,7 +970,7 @@ public static ArrayList getLibrary() { int parent = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); novelCards.add(new NovelCard( checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), - DatabaseIdentification.getNovelURLfromNovelID(parent), + parent, DatabaseIdentification.getNovelURLfromNovelID(parent), cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())), DatabaseIdentification.getFormatterIDFromNovelID(parent) )); @@ -937,7 +999,7 @@ public static NovelCard getNovel(String novelURL) { try { NovelCard novelCard = new NovelCard( checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), - novelURL, + parent, novelURL, cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())), DatabaseIdentification.getFormatterIDFromNovelID(parent) ); @@ -995,6 +1057,10 @@ public static NovelPage getNovelPage(int novelID) { return null; } + public static NovelPage getNovelPage(String novelURL) { + return getNovelPage(getNovelIDFromNovelURL(novelURL)); + } + public static void setStatus(@NotNull String novelURL, @NotNull Status status) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'"); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Anilist.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Anilist.java index e3cd19d06b..dd7f9c7cf8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Anilist.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Anilist.java @@ -27,7 +27,7 @@ class Anilist { @SuppressWarnings("EmptyMethod") - void auth(String username, String password){ + void auth(String username, String password) { } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index 9eef56b047..89a231fb48 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -51,7 +51,7 @@ public CataloguePageLoader(CatalogueFragment catalogueFragment) { } /** - * @param catalogueFragment the fragment this is assigned to (reference to parent) + * @param catalogueFragment the fragment this is assigned to (reference to parent) * @param catalogueHitBottom The listener to update once new page is loaded */ public CataloguePageLoader(CatalogueFragment catalogueFragment, CatalogueHitBottom catalogueHitBottom) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java index 0cbb958687..0a8d0b26cf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java @@ -40,6 +40,7 @@ public CatalogueQuerySearch(CatalogueFragment catalogueFragment) { /** * Search catalogue + * * @param strings ignored * @return List of results */ diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueHitBottom.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueHitBottom.java index 8c43f6a2bc..b7e807760c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueHitBottom.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueHitBottom.java @@ -39,13 +39,13 @@ public CatalogueHitBottom(CatalogueFragment catalogueFragment) { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (!catalogueFragment.isQuery&&!catalogueFragment.isInSearch) + if (!catalogueFragment.isQuery && !catalogueFragment.isInSearch) if (!running) if (!catalogueFragment.library_view.canScrollVertically(1)) { Log.d("CatalogueFragmentLoad", "Getting next page"); running = true; catalogueFragment.currentMaxPage++; - new CataloguePageLoader(catalogueFragment, this).execute(catalogueFragment.currentMaxPage); + new CataloguePageLoader(catalogueFragment, this).execute(catalogueFragment.currentMaxPage); } } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index 78bbbbe1bf..dcaeb66e95 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -84,7 +84,7 @@ private void removeFromSelect() { public void onClick(View v) { NovelFragment novelFragment = new NovelFragment(); StaticNovel.formatter = formatter; - StaticNovel.novelURL = novelCard.novelURL; + StaticNovel.setNovelID(novelCard.novelID); assert libraryFragment.getFragmentManager() != null; libraryFragment.getFragmentManager().beginTransaction() .addToBackStack("tag") diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java index 65c53f2ae7..7e7727c476 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java @@ -72,7 +72,7 @@ public void onBindViewHolder(@NonNull CompressedHolder holder, int position) { @Override public int getItemCount() { - if (migrationView.novelResults.size()> 0) + if (migrationView.novelResults.size() > 0) return migrationView.novelResults.get(migrationView.selection).size(); else return 0; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java index b33359cb0a..75bed9f44e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java @@ -43,6 +43,19 @@ public class StaticNovel { * Global variable of the current loaded novel */ public static int novelID; + public static String novelURL; + + public static void setNovelID(int novelID) { + StaticNovel.novelID = novelID; + novelURL = Database.DatabaseIdentification.getNovelURLfromNovelID(novelID); + } + + public static void setBaseValues(int novelID, String novelURL) { + StaticNovel.novelID = novelID; + StaticNovel.novelURL = novelURL; + } + + public static NovelPage novelPage; public static List novelChapters = new ArrayList<>(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index 868e9f76a2..ec8631ffdf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -20,6 +20,7 @@ import com.github.doomsdayrs.apps.shosetsu.ui.novel.viewHolders.ChaptersViewHolder; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; /* @@ -74,11 +75,14 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int chaptersViewHolder.library_card_title.setText(novelChapter.title); chaptersViewHolder.novelFragmentChapters = novelFragmentChapters; + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + chaptersViewHolder.chapterID = chapterID; + //TODO The getNovelID in this method likely will cause slowdowns due to IO if (!Database.DatabaseChapter.inChapters(novelChapter.link)) Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(StaticNovel.novelURL), novelChapter); - if (Database.DatabaseChapter.isBookMarked(novelChapter.link)) { + if (Database.DatabaseChapter.isBookMarked(chapterID)) { chaptersViewHolder.library_card_title.setTextColor(chaptersViewHolder.itemView.getResources().getColor(R.color.bookmarked)); chaptersViewHolder.popupMenu.getMenu().findItem(R.id.popup_chapter_menu_bookmark).setTitle("UnBookmark"); } else { @@ -99,7 +103,7 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int } else chaptersViewHolder.checkBox.setVisibility(View.GONE); - if (Database.DatabaseChapter.isSaved(novelChapter.link)) { + if (Database.DatabaseChapter.isSaved(chapterID)) { chaptersViewHolder.downloadTag.setVisibility(View.VISIBLE); chaptersViewHolder.popupMenu.getMenu().findItem(R.id.popup_chapter_menu_download).setTitle("Delete"); } else { @@ -107,7 +111,7 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int chaptersViewHolder.downloadTag.setVisibility(View.INVISIBLE); } - switch (Database.DatabaseChapter.getStatus(novelChapter.link)) { + switch (Database.DatabaseChapter.getStatus(chapterID)) { case READING: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -118,7 +122,7 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int chaptersViewHolder.status.setText(Status.READING.getStatus()); chaptersViewHolder.readTag.setVisibility(View.VISIBLE); chaptersViewHolder.read.setVisibility(View.VISIBLE); - chaptersViewHolder.read.setText(String.valueOf(Database.DatabaseChapter.getY(novelChapter.link))); + chaptersViewHolder.read.setText(String.valueOf(Database.DatabaseChapter.getY(chapterID))); break; case UNREAD: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 2f752437e4..a21f34aa19 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -97,7 +97,7 @@ protected Boolean doInBackground(Activity... voids) { try { StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL); - if (C && !Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { + if (C && !Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } //TODO The getNovelID in this method likely will cause slowdowns due to IO @@ -174,7 +174,7 @@ protected void onPostExecute(Boolean aBoolean) { } else { assert novelFragmentMain != null; novelFragmentMain.swipeRefreshLayout.setRefreshing(false); - if (Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { try { Database.DatabaseNovels.updateData(StaticNovel.novelURL, StaticNovel.novelPage); } catch (Exception e) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java index 69077b3e05..ac540122ca 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java @@ -39,15 +39,16 @@ public NovelFragmentMainAddToLibrary(NovelFragmentMain novelFragmentMain) { @Override public void onClick(View v) { if (!novelFragmentMain.inLibrary) { - if (!Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) - Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, StaticNovel.status.getA()); - Database.DatabaseNovels.bookMark(StaticNovel.novelURL); + // Thinking about this, this is an impossible combination as the novel should've loaded before this + // if (!Database.DatabaseNovels.inLibrary(StaticNovel.novelID)) + // Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel, StaticNovel.status.getA()); + Database.DatabaseNovels.bookMark(StaticNovel.novelID); novelFragmentMain.inLibrary = true; novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); } else { - Database.DatabaseNovels.unBookmark(StaticNovel.novelURL); - novelFragmentMain.inLibrary = false; - novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_outline_black_24dp); + Database.DatabaseNovels.unBookmark(StaticNovel.novelID); + novelFragmentMain.inLibrary = false; + novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_outline_black_24dp); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index edb9349807..48fe3750b3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -96,6 +96,7 @@ private int findMaxPosition() { max = x; return max; } + public static ChaptersAdapter adapter; public SwipeRefreshLayout swipeRefreshLayout; public NovelFragment novelFragment; @@ -205,7 +206,7 @@ public void setNovels() { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); - if (Database.DatabaseNovels.inLibrary(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { StaticNovel.novelChapters = Database.DatabaseChapter.getChapters(StaticNovel.novelURL); if (StaticNovel.novelChapters != null && StaticNovel.novelChapters.size() != 0) resumeRead.setVisibility(View.VISIBLE); @@ -250,7 +251,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.chapter_download_selected: for (NovelChapter novelChapter : selectedChapters) if (!Database.DatabaseChapter.isSaved(novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link); + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID); Download_Manager.addToDownload(downloadItem); } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); @@ -259,7 +260,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.chapter_delete_selected: for (NovelChapter novelChapter : selectedChapters) if (Database.DatabaseChapter.isSaved(novelChapter.link)) - Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link)); + Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID)); NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index 5a7285b021..0f41b3ba9d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -100,7 +100,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { Intent intent = new Intent(getActivity(), MigrationView.class); try { ArrayList novelCards = new ArrayList<>(); - novelCards.add(new NovelCard(StaticNovel.novelPage.title, StaticNovel.novelURL, StaticNovel.novelPage.imageURL, StaticNovel.formatter.getID())); + novelCards.add(new NovelCard(StaticNovel.novelPage.title, StaticNovel.novelID, StaticNovel.novelURL, StaticNovel.novelPage.imageURL, StaticNovel.formatter.getID())); intent.putExtra("selected", serializeToString(novelCards)); } catch (IOException e) { e.printStackTrace(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index eab03e7c1a..470c1f9772 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -51,6 +51,7 @@ public class ChaptersViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public NovelChapter novelChapter; + public int chapterID = -1; private final ImageView moreOptions; public final MaterialCardView cardView; @@ -99,11 +100,11 @@ public ChaptersViewHolder(@NonNull View itemView) { NovelFragmentChapters.adapter.notifyDataSetChanged(); return true; case R.id.popup_chapter_menu_download: - if (!Database.DatabaseChapter.isSaved(novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link); + if (!Database.DatabaseChapter.isSaved(chapterID)) { + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link))) { + if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID))) { downloadTag.setVisibility(View.INVISIBLE); } } @@ -111,15 +112,15 @@ public ChaptersViewHolder(@NonNull View itemView) { return true; case R.id.popup_chapter_menu_mark_read: - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.READ); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); NovelFragmentChapters.adapter.notifyDataSetChanged(); return true; case R.id.popup_chapter_menu_mark_unread: - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.UNREAD); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.UNREAD); NovelFragmentChapters.adapter.notifyDataSetChanged(); return true; case R.id.popup_chapter_menu_mark_reading: - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.READING); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); NovelFragmentChapters.adapter.notifyDataSetChanged(); return true; case R.id.browser: diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index dccae9acb9..da0f550458 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -92,6 +92,8 @@ public class ChapterReader extends AppCompatActivity { public String title; public Formatter formatter; + + public int chapterID; public String chapterURL; public String unformattedText = null; public String text = null; @@ -134,6 +136,7 @@ protected void onSaveInstanceState(@NotNull Bundle outState) { super.onSaveInstanceState(outState); outState.putString("unformattedText", text); outState.putString("text", text); + outState.putInt("chapterID", chapterID); outState.putString("chapterURL", chapterURL); outState.putInt("formatter", formatter.getID()); outState.putString("title", title); @@ -156,7 +159,7 @@ public boolean onCreateOptionsMenu(Menu menu) { // Bookmark { bookmark = menu.findItem(R.id.chapter_view_bookmark); - bookmarked = Database.DatabaseChapter.isBookMarked(chapterURL); + bookmarked = Database.DatabaseChapter.isBookMarked(chapterID); if (bookmarked) bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); @@ -340,10 +343,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { if (savedInstanceState != null) { unformattedText = savedInstanceState.getString("unformattedText"); title = savedInstanceState.getString("title"); + chapterID = savedInstanceState.getInt("chapterID"); chapterURL = savedInstanceState.getString("chapterURL"); formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); text = savedInstanceState.getString("text"); } else { + chapterID = getIntent().getIntExtra("chapterID", -1); chapterURL = getIntent().getStringExtra("chapterURL"); title = getIntent().getStringExtra("title"); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); @@ -460,14 +465,14 @@ public void bottom() { // Log.d("TY", String.valueOf(textView.getScrollY())); - if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterURL) != Status.READ) - Database.DatabaseChapter.updateY(chapterURL, y); + if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterID) != Status.READ) + Database.DatabaseChapter.updateY(chapterID, y); } } else { Log.i("Scroll", "Marking chapter as READ"); if (chapterURL != null) { - Database.DatabaseChapter.setChapterStatus(chapterURL, Status.READ); - Database.DatabaseChapter.updateY(chapterURL, 0); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); + Database.DatabaseChapter.updateY(chapterID, 0); nextChapter.setVisibility(View.VISIBLE); } //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) @@ -480,10 +485,10 @@ public void bottom() { */ public void loadChapter() { ready = false; - if (Database.DatabaseChapter.isSaved(chapterURL)) { - unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterURL)); + if (Database.DatabaseChapter.isSaved(chapterID)) { + unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterID)); setUpReader(); - scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterURL))); + scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterID))); if (getSupportActionBar() != null) getSupportActionBar().setTitle(title); ready = true; @@ -493,7 +498,7 @@ public void loadChapter() { new ReaderViewLoader(this).execute(); } - Database.DatabaseChapter.setChapterStatus(chapterURL, Status.READING); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); } /** diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java index cc53ad3722..1215f52b63 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java @@ -44,6 +44,7 @@ */ public class SettingsFragment extends Fragment { private static final ArrayList cards = new ArrayList<>(); + static { cards.add(new SettingsCard(Types.DOWNLOAD)); cards.add(new SettingsCard(Types.VIEW)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java index 8a9b5e9bf4..a9889b4d82 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java @@ -40,32 +40,32 @@ public class InfoSettings extends Fragment { - private void onClickAppVer(View v){ - // TODO: Add the app version number after consultation + private void onClickAppVer(View v) { + // TODO: Add the app version number after consultation Toast.makeText(v.getContext(), "AppVer", Toast.LENGTH_SHORT).show(); } - private void onClickReportBug(View v){ + private void onClickReportBug(View v) { Toast.makeText(v.getContext(), "ReportBug", Toast.LENGTH_SHORT).show(); String bugReportLink = getString(R.string.report_bug_link); Intent bugReportingIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(bugReportLink)); startActivity(bugReportingIntent); } - private void onClickAuthor(View v){ + private void onClickAuthor(View v) { Toast.makeText(v.getContext(), "Author", Toast.LENGTH_SHORT).show(); String authorGitHubLink = getString(R.string.author_github); Intent authorGitHubIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authorGitHubLink)); startActivity(authorGitHubIntent); } - private void onClickDisclaimer(View v){ + private void onClickDisclaimer(View v) { // TODO: Show full disclaimer on click Toast.makeText(v.getContext(), "Disclaimer", Toast.LENGTH_SHORT).show(); } - private void onClickLicense(View v){ - // TODO: Show full license on click + private void onClickLicense(View v) { + // TODO: Show full license on click Toast.makeText(v.getContext(), "License", Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json index d27b451834..75ff492724 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/schema.json @@ -36,7 +36,6 @@ "maxChapterPage": "" } ], - "chapters": [ { "novelURL": "serialize", @@ -44,7 +43,6 @@ "title": "serialize", "release_date": "serialize", "order": "", - "Y": "", "READ_CHAPTER": "", "BOOKMARKED": "", diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index 85c3e59345..6e045364d3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -114,10 +114,10 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, return true; case R.id.popup_chapter_menu_download: if (!Database.DatabaseChapter.isSaved(updatedChapterHolder.novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link); + DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link, novelID, chapterID); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link))) { + if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link, novelID, chapterID))) { updatedChapterHolder.downloadTag.setVisibility(View.INVISIBLE); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java index 14b80cdb46..f7d2c3c8c5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java @@ -72,5 +72,4 @@ public void onPageFinished(WebView view, String url) { } - } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java index 41d110507a..f2ddcf0772 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java @@ -2,6 +2,10 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLfromNovelID; + /* * This file is part of Shosetsu. * @@ -34,6 +38,8 @@ public class DownloadItem { public final String chapterName; public final String novelURL; public final String chapterURL; + public final int novelID; + public final int chapterID; //Variables only for download manager @@ -41,19 +47,19 @@ public class DownloadItem { /** * Constructor - * - * @param formatter formatter to work with + * @param formatter formatter to work with * @param novelName name of the novel * @param chapterName name of the chapter - * @param novelURL NovelURL - * @param chapterURL ChapterURL + * @param chapterID ChapterID */ - public DownloadItem(Formatter formatter, String novelName, String chapterName, String novelURL, String chapterURL) { + public DownloadItem(Formatter formatter, String novelName, String chapterName, int chapterID) { this.formatter = formatter; this.novelName = cleanse(novelName); this.chapterName = cleanse(chapterName); - this.novelURL = novelURL; - this.chapterURL = chapterURL; + this.novelID = getNovelIDFromChapterID(chapterID); + this.novelURL = getNovelURLfromNovelID(novelID); + this.chapterURL = getChapterURLFromChapterID(chapterID); + this.chapterID = chapterID; } /** diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java index 82018747e0..2f8d450065 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java @@ -54,4 +54,5 @@ public String getStatus() { @Override public String toString() { return "" + a; - }} + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java index 3d5b759c3c..74ec7c705e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java @@ -24,6 +24,8 @@ * @author github.com/doomsdayrs */ public class NovelCard extends RecycleCard { + + public final int novelID; /** * NovelURL */ @@ -42,12 +44,14 @@ public class NovelCard extends RecycleCard { * Constructor * * @param title title + * @param novelID * @param novelURL novelURL * @param imageURL imageURL * @param formatterID id of formatter */ - public NovelCard(String title, String novelURL, String imageURL, int formatterID) { + public NovelCard(String title, int novelID, String novelURL, String imageURL, int formatterID) { super(title); + this.novelID = novelID; this.novelURL = novelURL; this.imageURL = imageURL; this.formatterID = formatterID; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java index b83c25f8db..15a0e670d0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java @@ -34,19 +34,19 @@ public class SettingsItem { protected TextView itemTitle; protected TextView itemDesc; - public SettingsItem(@NonNull View view){ + public SettingsItem(@NonNull View view) { itemView = view; itemTitle = itemView.findViewById(R.id.settings_item_title); - if (itemTitle == null){ + if (itemTitle == null) { // TODO: Log error & quit gracefully } itemDesc = itemView.findViewById(R.id.settings_item_desc); - if (itemDesc == null){ + if (itemDesc == null) { // TODO: Log error & quit gracefully } } - public void invalidate(){ + public void invalidate() { itemView.invalidate(); } @@ -66,7 +66,7 @@ public void setDesc(@NonNull String desc) { itemDesc.setText(desc); } - public void setOnClickListener(View.OnClickListener onClickListener){ + public void setOnClickListener(View.OnClickListener onClickListener) { itemView.setOnClickListener(onClickListener); } } diff --git a/app/src/main/res/layout/nav_header.xml b/app/src/main/res/layout/nav_header.xml index c041ed1a58..4d9da25ad5 100644 --- a/app/src/main/res/layout/nav_header.xml +++ b/app/src/main/res/layout/nav_header.xml @@ -3,7 +3,6 @@ android:layout_width="match_parent" android:layout_height="200dp" android:gravity="bottom" - android:background="@color/colorLightAccent" android:orientation="vertical" android:padding="16dp" android:theme="@style/ThemeOverlay.AppCompat.Dark"> diff --git a/app/src/main/res/layout/toolbar_main.xml b/app/src/main/res/layout/toolbar_main.xml index 707bc888b9..05cec0bddc 100644 --- a/app/src/main/res/layout/toolbar_main.xml +++ b/app/src/main/res/layout/toolbar_main.xml @@ -1,8 +1,6 @@ \ No newline at end of file + android:elevation="4dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/updated_novel_card.xml b/app/src/main/res/layout/updated_novel_card.xml index 0654e9a313..79924d8bf4 100644 --- a/app/src/main/res/layout/updated_novel_card.xml +++ b/app/src/main/res/layout/updated_novel_card.xml @@ -13,6 +13,7 @@ android:cropToPadding="true" app:layout_constraintDimensionRatio="1:1" app:layout_constraintStart_toStartOf="parent" + android:contentDescription="@string/todo" app:layout_constraintTop_toTopOf="parent" /> + app:showAsAction="ifRoom" /> Date: Mon, 4 Nov 2019 06:48:53 -0500 Subject: [PATCH 040/162] Fixed a few errors --- .../ui/novel/pages/NovelFragmentChapters.java | 44 ++++++++++++------- .../novel/viewHolders/ChaptersViewHolder.java | 4 +- .../adapters/UpdatedChaptersAdapter.java | 21 +++++---- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 48fe3750b3..aa54d024c3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -37,6 +37,8 @@ import java.util.ArrayList; import java.util.Collections; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; + /* * This file is part of Shosetsu. * @@ -249,18 +251,22 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return true; case R.id.chapter_download_selected: - for (NovelChapter novelChapter : selectedChapters) - if (!Database.DatabaseChapter.isSaved(novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID); + for (NovelChapter novelChapter : selectedChapters) { + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + if (!Database.DatabaseChapter.isSaved(chapterID)) { + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID); Download_Manager.addToDownload(downloadItem); } + } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; case R.id.chapter_delete_selected: - for (NovelChapter novelChapter : selectedChapters) - if (Database.DatabaseChapter.isSaved(novelChapter.link)) - Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID)); + for (NovelChapter novelChapter : selectedChapters) { + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + if (Database.DatabaseChapter.isSaved(chapterID)) + Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID)); + } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; @@ -271,23 +277,31 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return true; case R.id.chapter_mark_read: - for (NovelChapter novelChapter : selectedChapters) - if (Database.DatabaseChapter.getStatus(novelChapter.link).getA() != 2) - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.READ); + for (NovelChapter novelChapter : selectedChapters) { + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + + if (Database.DatabaseChapter.getStatus(chapterID).getA() != 2) + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); + } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; case R.id.chapter_mark_unread: - for (NovelChapter novelChapter : selectedChapters) - if (Database.DatabaseChapter.getStatus(novelChapter.link).getA() != 0) - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.UNREAD); + for (NovelChapter novelChapter : selectedChapters) { + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + + if (Database.DatabaseChapter.getStatus(chapterID).getA() != 0) + Database.DatabaseChapter.setChapterStatus(chapterID, Status.UNREAD); + } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; case R.id.chapter_mark_reading: - for (NovelChapter novelChapter : selectedChapters) - if (Database.DatabaseChapter.getStatus(novelChapter.link).getA() != 0) - Database.DatabaseChapter.setChapterStatus(novelChapter.link, Status.READING); + for (NovelChapter novelChapter : selectedChapters) { + int chapterID = getChapterIDFromChapterURL(novelChapter.link); + if (Database.DatabaseChapter.getStatus(chapterID).getA() != 0) + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); + } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index 470c1f9772..40d34fe585 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -101,10 +101,10 @@ public ChaptersViewHolder(@NonNull View itemView) { return true; case R.id.popup_chapter_menu_download: if (!Database.DatabaseChapter.isSaved(chapterID)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID); + DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, StaticNovel.novelURL, novelChapter.link, novelID, chapterID))) { + if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID))) { downloadTag.setVisibility(View.INVISIBLE); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index 6e045364d3..65136e3fc9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -27,6 +27,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; /* @@ -101,6 +102,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, Formatter formatter = DefaultScrapers.getByID(getFormatterIDFromNovelURL(nURL)); + int chapterID = getChapterIDFromChapterURL(novelChapter.link); if (novelPage != null) switch (menuItem.getItemId()) { case R.id.popup_chapter_menu_bookmark: @@ -112,30 +114,31 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, } notifyDataSetChanged(); return true; - case R.id.popup_chapter_menu_download: - if (!Database.DatabaseChapter.isSaved(updatedChapterHolder.novelChapter.link)) { - DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link, novelID, chapterID); + case R.id.popup_chapter_menu_download: { + if (!Database.DatabaseChapter.isSaved(chapterID)) { + DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, chapterID); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, nURL, updatedChapterHolder.novelChapter.link, novelID, chapterID))) { + if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, chapterID))) { updatedChapterHolder.downloadTag.setVisibility(View.INVISIBLE); } } - notifyDataSetChanged(); - return true; + } + notifyDataSetChanged(); + return true; case R.id.popup_chapter_menu_mark_read: - Database.DatabaseChapter.setChapterStatus(updatedChapterHolder.novelChapter.link, Status.READ); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); notifyDataSetChanged(); return true; case R.id.popup_chapter_menu_mark_unread: - Database.DatabaseChapter.setChapterStatus(updatedChapterHolder.novelChapter.link, Status.UNREAD); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.UNREAD); notifyDataSetChanged(); return true; case R.id.popup_chapter_menu_mark_reading: - Database.DatabaseChapter.setChapterStatus(updatedChapterHolder.novelChapter.link, Status.READING); + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); notifyDataSetChanged(); return true; From 6b18f03d20761c98478c92bc2582c08f6a0822be Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Mon, 4 Nov 2019 06:59:58 -0500 Subject: [PATCH 041/162] Working on more refactoring --- .../apps/shosetsu/backend/Download_Manager.java | 2 +- .../shosetsu/ui/catalogue/async/NovelBackgroundAdd.java | 7 ++++--- .../shosetsu/ui/library/adapter/LibraryNovelAdapter.java | 2 +- .../doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java | 8 +++++++- .../shosetsu/ui/novel/pages/NovelFragmentChapters.java | 4 +++- .../doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java | 3 +++ 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index f33cae9436..a0d58f6501 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -84,7 +84,7 @@ public static void addToDownload(DownloadItem downloadItem) { public static boolean delete(Context context, DownloadItem downloadItem) { Log.d("DeletingChapter", downloadItem.toString()); File file = new File(shoDir + "/download/" + downloadItem.formatter.getID() + "/" + downloadItem.novelName + "/" + downloadItem.chapterName + ".txt"); - Database.DatabaseChapter.removePath(downloadItem.chapterURL); + Database.DatabaseChapter.removePath(downloadItem.chapterID); if (file.exists()) if (!file.delete()) if (context != null) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index d6303fd082..09896eae77 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -53,10 +53,11 @@ protected Void doInBackground(View... views) { views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } } catch (Exception e) { - if (views[0] != null) + + if (views[0] != null) { views[0].post(() -> Toast.makeText(views[0].getContext(), "Failed to add to library: " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_LONG).show()); - String message = novelCardsViewHolder.library_card_title.getText().toString() + " : " + e.getMessage(); - Log.e("NovelBackgroundAdd", message); + views[0].post(() -> Log.e("NovelBackgroundAdd", novelCardsViewHolder.library_card_title.getText().toString() + " : " + e.getMessage())); + } } return null; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java index ef1dae7935..5e6d8654fe 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java @@ -80,7 +80,7 @@ public void onBindViewHolder(@NonNull LibraryViewHolder libraryViewHolder, int i } } - int count = Database.DatabaseChapter.getCountOfChaptersUnread(novelCard.novelURL); + int count = Database.DatabaseChapter.getCountOfChaptersUnread(novelCard.novelID); if (count != 0) { libraryViewHolder.chip.setVisibility(View.VISIBLE); libraryViewHolder.chip.setText(String.valueOf(count)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index da1188783f..7fb478f2f7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -51,7 +51,7 @@ * @author github.com/doomsdayrs */ public class NovelFragment extends Fragment { - + public int novelID; public NovelFragmentMain novelFragmentMain; public NovelFragmentChapters novelFragmentChapters; @@ -81,6 +81,11 @@ public void onDestroy() { StaticNovel.novelLoader = null; } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + outState.putInt("novelID", novelID); + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -125,6 +130,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c setViewPager(); } } else { + novelID = savedInstanceState.getInt("novelID"); setViewPager(); } return view; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index aa54d024c3..0e9c586a24 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -66,6 +66,7 @@ * TODO Check filesystem if the chapter is saved, even if not in DB. */ public class NovelFragmentChapters extends Fragment { + public ArrayList selectedChapters = new ArrayList<>(); public boolean contains(NovelChapter novelChapter) { @@ -168,6 +169,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { if (savedInstanceState != null) { selectedChapters = (ArrayList) savedInstanceState.getSerializable("selChapter"); + currentMaxPage = savedInstanceState.getInt("maxPage"); } Log.d("NovelFragmentChapters", "Creating"); View view = inflater.inflate(R.layout.fragment_novel_chapters, container, false); @@ -209,7 +211,7 @@ public void setNovels() { RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); if (Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { - StaticNovel.novelChapters = Database.DatabaseChapter.getChapters(StaticNovel.novelURL); + StaticNovel.novelChapters = Database.DatabaseChapter.getChapters(novelFragment.novelID); if (StaticNovel.novelChapters != null && StaticNovel.novelChapters.size() != 0) resumeRead.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index da0f550458..38ff697f99 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -78,6 +78,9 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { + int chapterID; + + public boolean ready = false; public TextView textView; From c90e431a82d2cd65135d5b9fde0bbd57111c3011 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 7 Nov 2019 06:46:47 -0500 Subject: [PATCH 042/162] Removed a lot of unneeded methods --- .../apps/shosetsu/backend/Utilities.java | 16 ++--- .../shosetsu/backend/database/Database.java | 66 +++---------------- .../backend/database/objects/Update.java | 6 +- .../viewHolder/NovelCardViewHolder.java | 2 + .../viewHolders/LibraryViewHolder.java | 1 + .../apps/shosetsu/ui/novel/StaticNovel.java | 4 +- .../novel/viewHolders/ChaptersViewHolder.java | 2 +- .../shosetsu/ui/reader/ChapterReader.java | 3 +- .../ui/reader/async/ReaderViewLoader.java | 2 +- .../adapters/UpdatedChaptersAdapter.java | 4 +- 10 files changed, 31 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 04398408a2..0f173b1641 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -387,26 +387,26 @@ public static void swapReaderColor() { /** * Gets y position of a bookmark * - * @param chapterURL chapter chapterURL + * @param chapterID chapter id * @return y position */ - public static int getYBookmark(String chapterURL) { - return Database.DatabaseChapter.getY(chapterURL); + public static int getYBookmark(int chapterID) { + return Database.DatabaseChapter.getY(chapterID); } /** * Toggles bookmark * - * @param chapterURL imageURL of chapter + * @param chapterID id * @return true means added, false means removed */ - public static boolean toggleBookmarkChapter(String chapterURL) { + public static boolean toggleBookmarkChapter(int chapterID) { //TODO Simplify - if (Database.DatabaseChapter.isBookMarked(chapterURL)) { - Database.DatabaseChapter.setBookMark(chapterURL, 0); + if (Database.DatabaseChapter.isBookMarked(chapterID)) { + Database.DatabaseChapter.setBookMark(chapterID, 0); return false; } else { - Database.DatabaseChapter.setBookMark(chapterURL, 1); + Database.DatabaseChapter.setBookMark(chapterID, 1); return true; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 1f476eed90..c41f5f642c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -32,8 +32,9 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelURLfromNovelID; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.hasChapter; /* @@ -449,10 +450,6 @@ public static int getCountOfChaptersUnread(int novelID) { return count; } - @Deprecated - public static int getCountOfChaptersUnread(String novelURL) { - return getCountOfChaptersUnread(getNovelIDFromNovelURL(novelURL)); - } public static void updateOrder(int chapterID, int order) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.ORDER + "='" + order + "' where " + Columns.ID + "=" + chapterID); @@ -470,10 +467,6 @@ public static void updateY(int chapterID, int y) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.Y + "='" + y + "' where " + Columns.ID + "=" + chapterID); } - @Deprecated - public static void updateY(String chapterURL, int y) { - updateY(DatabaseIdentification.getChapterIDFromChapterURL(chapterURL), y); - } /** * Precondition is the chapter is already in the database @@ -494,10 +487,6 @@ public static int getY(int chapterID) { } } - @Deprecated - public static int getY(String chapterURL) { - return getY(DatabaseIdentification.getChapterIDFromChapterURL(chapterURL)); - } /** * @param chapterID chapter to check @@ -521,11 +510,6 @@ else if (y == 1) } } - @Deprecated - public static Status getStatus(String chapterURL) { - return getStatus(getChapterIDFromChapterURL(chapterURL)); - } - /** * Sets chapter status * @@ -536,11 +520,6 @@ public static void setChapterStatus(int chapterID, Status status) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.READ_CHAPTER + "=" + status + " where " + Columns.ID + "=" + chapterID); } - @Deprecated - public static void setChapterStatus(String chapterURL, Status status) { - setChapterStatus(getChapterIDFromChapterURL(chapterURL), status); - } - /** * Sets bookmark true or false (1 for true, 0 is false) * @@ -551,10 +530,6 @@ public static void setBookMark(int chapterID, int b) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.BOOKMARKED + "=" + b + " where " + Columns.ID + "=" + chapterID); } - @Deprecated - public static void setBookMark(String chapterURL, int b) { - setBookMark(getChapterIDFromChapterURL(chapterURL), b); - } /** * is this chapter bookmarked? @@ -576,11 +551,6 @@ public static boolean isBookMarked(int chapterID) { } - @Deprecated - public static boolean isBookMarked(String chapterURL) { - return isBookMarked(getChapterIDFromChapterURL(chapterURL)); - } - /** * Removes save path from chapter * @@ -590,11 +560,6 @@ public static void removePath(int chapterID) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "=null," + Columns.IS_SAVED + "=0 where " + Columns.ID + "=" + chapterID); } - @Deprecated - public static void removePath(String chapterURL) { - removePath(getChapterIDFromChapterURL(chapterURL)); - } - /** * Adds save path * @@ -632,10 +597,6 @@ public static boolean isSaved(int chapterID) { } } - @Deprecated - public static boolean isSaved(String chapterURL) { - return isSaved(getChapterIDFromChapterURL(chapterURL)); - } /** * Gets the novel from local storage @@ -656,10 +617,6 @@ public static String getSavedNovelPassage(int chapterID) { } } - @Deprecated - public static String getSavedNovelPassage(String chapterURL) { - return getSavedNovelPassage(getChapterIDFromChapterURL(chapterURL)); - } /** * If the chapter URL is present or not @@ -714,11 +671,6 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { } } - @Deprecated - public static List getChapters(String novelURL) { - return getChapters(getNovelIDFromNovelURL(novelURL)); - } - /** * Gets chapters of a novel * @@ -788,10 +740,7 @@ public static NovelChapter getChapter(int chapterID) { } } - @Deprecated - public static NovelChapter getChapter(String chapterURL) { - return getChapter(getChapterIDFromChapterURL(chapterURL)); - } + } public static class DatabaseNovels { @@ -820,7 +769,7 @@ public static void unBookmark(@NotNull String novelURL) { } public static void unBookmark(int novelID) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.ID + "=" + novelID); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.PARENT_ID + "=" + novelID); } @@ -1226,11 +1175,12 @@ public static ArrayList getTimeBetween(long date1, long date2) throws Ex } else { while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); + int parentID = getNovelIDFromChapterID(id); novelCards.add(new Update( - getNovelURLFromChapterID(id), + getNovelURLfromNovelID(parentID), getChapterURLFromChapterID(id), - cursor.getLong(cursor.getColumnIndex(Columns.TIME.toString())) - )); + cursor.getLong(cursor.getColumnIndex(Columns.TIME.toString())), + id, parentID)); } cursor.close(); return novelCards; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java index 77936a53d5..edb28f19b9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java @@ -25,9 +25,13 @@ */ public class Update extends BaseChapter { public final long time; + public final int chapterID; + public final int novelID; - public Update(String novel_url, String chapter_url, long time) { + public Update(String novel_url, String chapter_url, long time, int chapterID, int novelID) { super(novel_url, chapter_url); this.time = time; + this.chapterID = chapterID; + this.novelID = novelID; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java index dafdfe607b..7ef13717d2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java @@ -10,6 +10,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.async.NovelBackgroundAdd; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; @@ -58,6 +59,7 @@ public void onClick(View v) { NovelFragment novelFragment = new NovelFragment(); StaticNovel.formatter = formatter; StaticNovel.novelURL = url; + novelFragment.novelID = Database.DatabaseIdentification.getNovelIDFromNovelURL(url); if (catalogueFragment.getFragmentManager() != null) catalogueFragment.getFragmentManager().beginTransaction() diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index dcaeb66e95..af9c08e720 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -83,6 +83,7 @@ private void removeFromSelect() { @Override public void onClick(View v) { NovelFragment novelFragment = new NovelFragment(); + novelFragment.novelID = novelCard.novelID; StaticNovel.formatter = formatter; StaticNovel.setNovelID(novelCard.novelID); assert libraryFragment.getFragmentManager() != null; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java index 75bed9f44e..f96ca5c927 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java @@ -97,7 +97,7 @@ public static int lastRead() { if (StaticNovel.novelChapters.size() != 0) { if (!NovelFragmentChapters.reversed) { for (int x = novelChapters.size() - 1; x >= 0; x--) { - Status status = Database.DatabaseChapter.getStatus(novelChapters.get(x).link); + Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); switch (status) { default: break; @@ -109,7 +109,7 @@ public static int lastRead() { } } else { for (int x = 0; x < novelChapters.size(); x++) { - Status status = Database.DatabaseChapter.getStatus(novelChapters.get(x).link); + Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); switch (status) { default: break; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index 40d34fe585..a1fe790d0a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -90,7 +90,7 @@ public ChaptersViewHolder(@NonNull View itemView) { popupMenu.setOnMenuItemClickListener(menuItem -> { switch (menuItem.getItemId()) { case R.id.popup_chapter_menu_bookmark: - if (toggleBookmarkChapter(novelChapter.link)) + if (toggleBookmarkChapter(chapterID)) library_card_title.setTextColor(itemView.getResources().getColor(R.color.bookmarked)); else { Log.i("SetDefault", String.valueOf(ChaptersAdapter.DefaultTextColor)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 38ff697f99..86e966cc3f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -78,7 +78,6 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { - int chapterID; public boolean ready = false; @@ -263,7 +262,7 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { tap_to_scroll.setChecked(toggleTapToScroll()); return true; case R.id.chapter_view_bookmark: - bookmarked = toggleBookmarkChapter(chapterURL); + bookmarked = toggleBookmarkChapter(chapterID); if (bookmarked) bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index ccbb4f9d0b..5a2b6384f3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -51,7 +51,7 @@ protected String doInBackground(ChapterReader... chapterReaders) { chapterReader.runOnUiThread(chapterReader::setUpReader); chapterReader.runOnUiThread(() -> chapterReader.scrollView.post(() -> - chapterReader.scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterReader.chapterURL))) + chapterReader.scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterReader.chapterID))) ); chapterReader.runOnUiThread(() -> chapterReader.ready = true); } catch (Exception e) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index 65136e3fc9..cdf2c753b2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -80,7 +80,7 @@ public UpdatedChapterHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int @Override public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, int i) { Log.d("Binding", updates.get(i).CHAPTER_URL); - NovelChapter novelChapter = DatabaseChapter.getChapter(updates.get(i).CHAPTER_URL); + NovelChapter novelChapter = DatabaseChapter.getChapter(updates.get(i).chapterID); if (novelChapter != null) { updatedChapterHolder.setNovelChapter(novelChapter); } else { @@ -106,7 +106,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, if (novelPage != null) switch (menuItem.getItemId()) { case R.id.popup_chapter_menu_bookmark: - if (toggleBookmarkChapter(updatedChapterHolder.novelChapter.link)) + if (toggleBookmarkChapter(chapterID)) updatedChapterHolder.title.setTextColor(updatedChapterHolder.itemView.getResources().getColor(R.color.bookmarked)); else { Log.i("SetDefault", String.valueOf(DefaultTextColor)); From 4be8ed54effdbcc7eb0a812aa52dedae21c1d62d Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 7 Nov 2019 08:12:35 -0500 Subject: [PATCH 043/162] Completed removal of old methods. Now to simplify code --- .../shosetsu/backend/database/Database.java | 51 ++++--------------- .../catalogue/adapters/CatalogueAdapter.java | 3 +- .../catalogue/async/CataloguePageLoader.java | 3 +- .../catalogue/async/CatalogueQuerySearch.java | 3 +- .../catalogue/async/NovelBackgroundAdd.java | 4 +- .../viewHolder/NovelCardViewHolder.java | 1 + .../shosetsu/ui/library/LibraryFragment.java | 2 +- .../shosetsu/ui/migration/async/Transfer.java | 3 +- .../apps/shosetsu/ui/novel/NovelFragment.java | 2 +- .../ui/novel/pages/NovelFragmentMain.java | 4 +- .../adapters/UpdatedChaptersAdapter.java | 3 +- .../viewHolder/UpdatedChapterHolder.java | 4 +- .../recycleObjects/CatalogueNovelCard.java | 8 +-- 13 files changed, 35 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index c41f5f642c..8836eda965 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -754,29 +754,16 @@ public static void bookMark(int novelID) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=1 where " + Columns.PARENT_ID + "=" + novelID); } - public static void bookMark(String novelURL) { - bookMark(getNovelIDFromNovelURL(novelURL)); - } - /** * UnBookmarks the novel * - * @param novelURL novelURL + * @param novelID id * @return if removed successfully */ - public static void unBookmark(@NotNull String novelURL) { - unBookmark(getNovelIDFromNovelURL(novelURL)); - } - public static void unBookmark(int novelID) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.PARENT_ID + "=" + novelID); } - - public static boolean isBookmarked(String novelURL) { - return isBookmarked(getNovelIDFromNovelURL(novelURL)); - } - public static boolean isBookmarked(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.BOOKMARKED + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + "=" + novelID, null); if (cursor.getCount() <= 0) { @@ -794,10 +781,6 @@ public static void setReaderType(@NotNull int novelID, int reader) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.ID + "=" + novelID); } - public static void setReaderType(@NotNull String novelURL, int reader) { - setReaderType(getNovelIDFromNovelURL(novelURL), reader); - } - /** * Gets reader type for novel * @@ -817,11 +800,6 @@ public static int getReaderType(int novelID) { return a; } - public static int getReaderType(String novelURL) { - return getReaderType(getNovelIDFromNovelURL(novelURL)); - } - - public static void addToLibrary(int formatter, @NotNull NovelPage novelPage, String novelURL, int readingStatus) { addNovel(novelURL, formatter); String imageURL = novelPage.imageURL; @@ -932,13 +910,12 @@ public static ArrayList getLibrary() { } } - public static NovelCard getNovel(String novelURL) { + public static NovelCard getNovel(int novelID) { Log.d("DL", "Getting"); - int parent = getNovelIDFromNovelURL(novelURL); Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), new String[]{Columns.PARENT_ID.toString(), Columns.TITLE.toString(), Columns.IMAGE_URL.toString()}, - Columns.BOOKMARKED + "=1 and " + Columns.PARENT_ID + "=" + parent, null, null, null, null); + Columns.BOOKMARKED + "=1 and " + Columns.PARENT_ID + "=" + novelID, null, null, null, null); if (cursor.getCount() <= 0) { cursor.close(); @@ -948,9 +925,9 @@ public static NovelCard getNovel(String novelURL) { try { NovelCard novelCard = new NovelCard( checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))), - parent, novelURL, + novelID, getNovelURLfromNovelID(novelID), cursor.getString(cursor.getColumnIndex(Columns.IMAGE_URL.toString())), - DatabaseIdentification.getFormatterIDFromNovelID(parent) + DatabaseIdentification.getFormatterIDFromNovelID(novelID) ); cursor.close(); return novelCard; @@ -1006,16 +983,8 @@ public static NovelPage getNovelPage(int novelID) { return null; } - public static NovelPage getNovelPage(String novelURL) { - return getNovelPage(getNovelIDFromNovelURL(novelURL)); - } - - public static void setStatus(@NotNull String novelURL, @NotNull Status status) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "='" + getNovelIDFromNovelURL(novelURL) + "'"); - } - - public static Status getStatus(String novelURL) { - return getStatus(getNovelIDFromNovelURL(novelURL)); + public static void setStatus(int novelID, @NotNull Status status) { + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "=" + novelID); } public static Status getStatus(int novelID) { @@ -1058,11 +1027,11 @@ public static void updateData(@NotNull String novelURL, @NotNull NovelPage novel } - public static void migrateNovel(@NotNull String oldURL, String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { - unBookmark(oldURL); + public static void migrateNovel(int oldID, String newURL, int formatterID, @NotNull NovelPage newNovel, int status) { + unBookmark(oldID); if (!DatabaseNovels.inDatabase(newURL)) addToLibrary(formatterID, newNovel, newURL, status); - bookMark(newURL); + bookMark(getNovelIDFromNovelURL(newURL)); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java index 590439337b..d2d1d530e1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java @@ -67,6 +67,7 @@ public NovelCardViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int public void onBindViewHolder(@NonNull NovelCardViewHolder novelCardsViewHolder, int i) { CatalogueNovelCard recycleCard = recycleCards.get(i); if (recycleCard != null) { + novelCardsViewHolder.novelID = recycleCard.novelID; novelCardsViewHolder.url = recycleCard.novelURL; novelCardsViewHolder.library_card_title.setText(recycleCard.title); if (recycleCard.imageURL != null) { @@ -77,7 +78,7 @@ public void onBindViewHolder(@NonNull NovelCardViewHolder novelCardsViewHolder, } else novelCardsViewHolder.library_card_image.setVisibility(View.GONE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (Database.DatabaseNovels.isBookmarked(recycleCard.novelURL)) { + if (Database.DatabaseNovels.isBookmarked(recycleCard.novelID)) { if (catalogueFragment.getContext() != null) novelCardsViewHolder.constraintLayout.setForeground(new ColorDrawable(ContextCompat.getColor(catalogueFragment.getContext(), R.color.shade))); } else novelCardsViewHolder.constraintLayout.setForeground(new ColorDrawable()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index 89a231fb48..24386c8143 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -6,6 +6,7 @@ import android.widget.Toast; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.listeners.CatalogueHitBottom; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; @@ -91,7 +92,7 @@ protected Boolean doInBackground(Integer... integers) { } for (Novel novel : novels) - catalogueFragment.catalogueNovelCards.add(new CatalogueNovelCard(novel.imageURL, novel.title, novel.link)); + catalogueFragment.catalogueNovelCards.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); catalogueFragment.library_view.post(() -> catalogueFragment.catalogueAdapter.notifyDataSetChanged()); if (catalogueHitBottom != null) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java index 0a8d0b26cf..58056510fc 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java @@ -3,6 +3,7 @@ import android.os.AsyncTask; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; @@ -50,7 +51,7 @@ protected ArrayList doInBackground(String... strings) { try { List novels = catalogueFragment.formatter.search(strings[0]); for (Novel novel : novels) - result.add(new CatalogueNovelCard(novel.imageURL, novel.title, novel.link)); + result.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); } catch (IOException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index 09896eae77..a9089db5ae 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -44,11 +44,11 @@ protected Void doInBackground(View... views) { if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } - if (Database.DatabaseNovels.isBookmarked(novelCardsViewHolder.url)) { + if (Database.DatabaseNovels.isBookmarked(novelCardsViewHolder.novelID)) { if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Already in the library", Toast.LENGTH_SHORT).show()); } else { - Database.DatabaseNovels.bookMark(novelCardsViewHolder.url); + Database.DatabaseNovels.bookMark(novelCardsViewHolder.novelID); if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java index 7ef13717d2..19fbef7072 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java @@ -44,6 +44,7 @@ public class NovelCardViewHolder extends RecyclerView.ViewHolder implements View public CatalogueFragment catalogueFragment; public Formatter formatter; public String url; + public int novelID; public NovelCardViewHolder(@NonNull View itemView) { super(itemView); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 022aa229ba..0f97b15d49 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -233,7 +233,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.remove_from_library: for (NovelCard novelCard : selectedNovels) { - Database.DatabaseNovels.unBookmark(novelCard.novelURL); + Database.DatabaseNovels.unBookmark(novelCard.novelID); libraryNovelCards.remove(novelCard); } selectedNovels = new ArrayList<>(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java index 6e9711cf18..51f91ae8ee 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java @@ -120,7 +120,8 @@ protected Void doInBackground(Void... voids) { } if (C) { migrationView.pageCount.post(() -> migrationView.pageCount.setText("")); - Database.DatabaseNovels.migrateNovel(strings[0], strings[1], formatter.getID(), novelPage, Database.DatabaseNovels.getStatus(strings[0]).getA()); + int oldID = getNovelIDFromNovelURL(strings[0]); + Database.DatabaseNovels.migrateNovel(oldID, strings[1], formatter.getID(), novelPage, Database.DatabaseNovels.getStatus(oldID).getA()); } } catch (IOException e) { if (e.getMessage() != null) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 7fb478f2f7..6ea155aecd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -124,7 +124,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c StaticNovel.novelLoader.execute(getActivity()); } else { StaticNovel.novelPage = Database.DatabaseNovels.getNovelPage(StaticNovel.novelID); - StaticNovel.status = Database.DatabaseNovels.getStatus(StaticNovel.novelURL); + StaticNovel.status = Database.DatabaseNovels.getStatus(novelID); if (StaticNovel.novelPage != null) Statics.mainActionBar.setTitle(StaticNovel.novelPage.title); setViewPager(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index 0f41b3ba9d..c6fd59c93d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -124,7 +124,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.toolbar_novel, menu); - if (Database.DatabaseNovels.isBookmarked(StaticNovel.novelURL)) { + if (Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) { menu.findItem(R.id.source_migrate).setVisible(true); } else menu.findItem(R.id.source_migrate).setVisible(false); @@ -174,7 +174,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c floatingActionButton.hide(); - if (Database.DatabaseNovels.isBookmarked(StaticNovel.novelURL)) + if (Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) inLibrary(); if (inLibrary) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index cdf2c753b2..91c9b92313 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -29,6 +29,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; /* * This file is part of Shosetsu. @@ -93,7 +94,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, String nURL = Database.DatabaseIdentification.getNovelURLFromChapterURL(updatedChapterHolder.novelChapter.link); if (nURL != null) - novelPage = Database.DatabaseNovels.getNovelPage(nURL); + novelPage = Database.DatabaseNovels.getNovelPage(getNovelIDFromNovelURL(nURL)); if (novelPage == null) { Log.e("DatabaseError", "No such novel in DB"); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 79b1a7a9e4..b18802dc29 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -35,6 +35,7 @@ import com.squareup.picasso.Picasso; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openChapter; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; /** @@ -69,7 +70,8 @@ public UpdatedChapterHolder(@NonNull View itemView) { public void setNovelChapter(NovelChapter novelChapter) { this.novelChapter = novelChapter; title.setText(novelChapter.title); - NovelCard novelCard = Database.DatabaseNovels.getNovel(Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link)); + //TODO fix this disgust + NovelCard novelCard = Database.DatabaseNovels.getNovel(Database.DatabaseIdentification.getNovelIDFromChapterID(getChapterIDFromChapterURL(novelChapter.link))); Picasso.get() .load( novelCard.imageURL) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java index 687c8d31d6..ec495ca0ef 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java @@ -29,6 +29,7 @@ public class CatalogueNovelCard extends RecycleCard implements Serializable { */ public final String imageURL; + public final int novelID; /** * link to the novel */ @@ -36,14 +37,15 @@ public class CatalogueNovelCard extends RecycleCard implements Serializable { /** * Constructor - * - * @param imageURL image chapterURL + * @param imageURL image chapterURL * @param title title + * @param novelID * @param novelURL novelURL */ - public CatalogueNovelCard(String imageURL, String title, String novelURL) { + public CatalogueNovelCard(String imageURL, String title, int novelID, String novelURL) { super(title); this.imageURL = imageURL; + this.novelID = novelID; this.novelURL = novelURL; } From 6817ef775527571359c2be2e2d087cbf293c54b4 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 7 Nov 2019 08:20:59 -0500 Subject: [PATCH 044/162] Changing some comments --- .../apps/shosetsu/variables/DownloadItem.java | 12 +++++++----- .../variables/recycleObjects/RecycleCard.java | 11 ++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java index f2ddcf0772..f2813c02bd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java @@ -22,13 +22,14 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 16 / 06 / 2019 * * @author github.com/doomsdayrs - */ - -/** + *

* These items symbolize download items and their data */ public class DownloadItem { @@ -47,10 +48,11 @@ public class DownloadItem { /** * Constructor - * @param formatter formatter to work with + * + * @param formatter formatter to work with * @param novelName name of the novel * @param chapterName name of the chapter - * @param chapterID ChapterID + * @param chapterID ChapterID */ public DownloadItem(Formatter formatter, String novelName, String chapterName, int chapterID) { this.formatter = formatter; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java index b61f4f7b12..34cf2c5fe4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java @@ -20,16 +20,22 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu + *

* 9 / June / 2019 * * @author github.com/doomsdayrs + * + * This is a recycle card, it is used for the recyclers in the program. */ -public class RecycleCard implements Serializable { +public class RecycleCard { /** * If there isn't an image loaded in, this will be the image */ - public final int libraryImageResource; + public final int libraryImageResource = R.drawable.ic_close_black_24dp; /** * Text of the card @@ -42,7 +48,6 @@ public class RecycleCard implements Serializable { * @param title text of card */ RecycleCard(String title) { - this.libraryImageResource = R.drawable.ic_close_black_24dp; this.title = title; } From 99d9404d368d11d9cfad72d2477d71327e2a0964 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 7 Nov 2019 09:23:16 -0500 Subject: [PATCH 045/162] working on ALOT. Chapterloader is where i am at --- .../apps/shosetsu/backend/Utilities.java | 12 +- .../viewHolder/NovelCardViewHolder.java | 1 - .../shosetsu/ui/library/LibraryFragment.java | 1 - .../viewHolders/LibraryViewHolder.java | 1 - .../apps/shosetsu/ui/novel/NovelFragment.java | 109 ++++++++++++--- .../apps/shosetsu/ui/novel/StaticNovel.java | 127 ------------------ .../ui/novel/adapters/ChaptersAdapter.java | 1 - .../ui/novel/async/ChapterLoader.java | 61 +++++---- .../shosetsu/ui/novel/async/NovelLoader.java | 1 - .../NovelFragmentMainAddToLibrary.java | 1 - .../ui/novel/pages/NovelFragmentChapters.java | 51 +++---- .../ui/novel/pages/NovelFragmentMain.java | 39 +++--- .../novel/viewHolders/ChaptersViewHolder.java | 1 - .../shosetsu/ui/reader/ChapterReader.java | 16 ++- .../apps/shosetsu/variables/enums/Status.java | 20 ++- 15 files changed, 195 insertions(+), 247 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 0f173b1641..c8145da434 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -424,19 +424,25 @@ public static void setTextSize(int size) { * * @param activity * @param novelChapter - * @param nurl + * @param novelID * @param formatterID */ - public static void openChapter(Activity activity, NovelChapter novelChapter, String nurl, int formatterID) { + public static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID) { + openChapter(activity, novelChapter, novelID, formatterID, null); + } + + public static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); Intent intent = new Intent(activity, ChapterReader.class); intent.putExtra("title", novelChapter.title); intent.putExtra("chapterID", chapterID); intent.putExtra("chapterURL", novelChapter.link); - intent.putExtra("novelURL", nurl); + intent.putExtra("novelID", novelID); intent.putExtra("formatter", formatterID); + intent.putExtra("chapters", chapters); activity.startActivity(intent); + } public static void openInWebview(@NotNull Activity activity, @NotNull String url) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java index 19fbef7072..49946bb593 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java @@ -14,7 +14,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.async.NovelBackgroundAdd; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; /* * This file is part of Shosetsu. diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 0f97b15d49..33f0bac760 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -217,7 +217,6 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.updater_now: Update_Manager.init(libraryNovelCards, context); return true; - case R.id.chapter_select_all: for (NovelCard novelChapter : libraryNovelCards) if (!contains(novelChapter)) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index af9c08e720..64f61928fb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -32,7 +32,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.ui.library.LibraryFragment; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; import com.google.android.material.card.MaterialCardView; import com.google.android.material.chip.Chip; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 6ea155aecd..3c82805d1e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -15,15 +15,22 @@ import androidx.fragment.app.Fragment; import androidx.viewpager.widget.ViewPager; +import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.NovelPagerAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; +import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; +import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.tabs.TabLayout; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; import java.util.List; @@ -51,7 +58,76 @@ * @author github.com/doomsdayrs */ public class NovelFragment extends Fragment { + + public int novelID; + public String novelURL; + public NovelPage novelPage; + public Formatter formatter; + public Status status = Status.UNREAD; + + public List novelChapters = new ArrayList<>(); + + /** + * @param chapterURL Current chapter URL + * @return chapter after the input, returns the current chapter if no more + */ + public static NovelChapter getNextChapter(@NotNull String chapterURL, String[] novelChapters) { + if (novelChapters != null && novelChapters.length != 0) + for (int x = 0; x < novelChapters.length; x++) { + if (novelChapters[x].equalsIgnoreCase(chapterURL)) { + if (NovelFragmentChapters.reversed) { + if (x - 1 != -1) + return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x - 1])); + else + return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x])); + } else { + if (x + 1 != novelChapters.length) + return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x + 1])); + else + return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x])); + } + } + } + return null; + } + + /** + * @return position of last read chapter, reads array from reverse. If -1 then the array is null, if -2 the array is empty, else if not found plausible chapter returns the first. + */ + public int lastRead() { + if (novelChapters != null) { + if (novelChapters.size() != 0) { + if (!NovelFragmentChapters.reversed) { + for (int x = novelChapters.size() - 1; x >= 0; x--) { + Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); + switch (status) { + default: + break; + case READ: + return x + 1; + case READING: + return x; + } + } + } else { + for (int x = 0; x < novelChapters.size(); x++) { + Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); + switch (status) { + default: + break; + case READ: + return x - 1; + case READING: + return x; + } + } + } + return 0; + } else return -2; + } else return -1; + } + public NovelFragmentMain novelFragmentMain; public NovelFragmentChapters novelFragmentChapters; @@ -72,18 +148,15 @@ public NovelFragment() { @Override public void onDestroy() { super.onDestroy(); - if (StaticNovel.chapterLoader != null) - StaticNovel.chapterLoader.cancel(true); - if (StaticNovel.novelLoader != null) - StaticNovel.novelLoader.cancel(true); - - StaticNovel.chapterLoader = null; - StaticNovel.novelLoader = null; } @Override public void onSaveInstanceState(@NonNull Bundle outState) { outState.putInt("novelID", novelID); + outState.putString("novelURL", novelURL); + outState.putInt("formatter", formatter.getID()); + outState.putInt("status", status.getA()); + } @Nullable @@ -112,25 +185,21 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c //boolean track = SettingsController.isTrackingEnabled(); if (savedInstanceState == null) { - if (isOnline() && !Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { + if (isOnline() && !Database.DatabaseNovels.inDatabase(novelID)) { setViewPager(); - - if (StaticNovel.novelLoader != null && !StaticNovel.novelLoader.isCancelled()) { - StaticNovel.novelLoader.setC(false); - StaticNovel.novelLoader.cancel(true); - } - StaticNovel.novelLoader = new NovelLoader(this, true); - - StaticNovel.novelLoader.execute(getActivity()); + new NovelLoader(this, false).execute(getActivity()); } else { - StaticNovel.novelPage = Database.DatabaseNovels.getNovelPage(StaticNovel.novelID); - StaticNovel.status = Database.DatabaseNovels.getStatus(novelID); - if (StaticNovel.novelPage != null) - Statics.mainActionBar.setTitle(StaticNovel.novelPage.title); + novelPage = Database.DatabaseNovels.getNovelPage(novelID); + status = Database.DatabaseNovels.getStatus(novelID); + if (novelPage != null) + Statics.mainActionBar.setTitle(novelPage.title); setViewPager(); } } else { novelID = savedInstanceState.getInt("novelID"); + novelURL = savedInstanceState.getString("novelURL"); + formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); + status = Status.getStatus(savedInstanceState.getInt("status")); setViewPager(); } return view; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java deleted file mode 100644 index f96ca5c927..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/StaticNovel.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.ui.novel; - -import android.annotation.SuppressLint; - -import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.ChapterLoader; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; -import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; - -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * Shosetsu - * 18 / 06 / 2019 - * - * @author github.com/doomsdayrs - */ -public class StaticNovel { - //TODO fix error with chapters here - /** - * Global variable of the current loaded novel - */ - public static int novelID; - public static String novelURL; - - public static void setNovelID(int novelID) { - StaticNovel.novelID = novelID; - novelURL = Database.DatabaseIdentification.getNovelURLfromNovelID(novelID); - } - - public static void setBaseValues(int novelID, String novelURL) { - StaticNovel.novelID = novelID; - StaticNovel.novelURL = novelURL; - } - - - public static NovelPage novelPage; - - public static List novelChapters = new ArrayList<>(); - public static Formatter formatter; - public static Status status = Status.UNREAD; - @SuppressLint("StaticFieldLeak") - public static NovelLoader novelLoader = null; - @SuppressLint("StaticFieldLeak") - public static ChapterLoader chapterLoader = null; - - /** - * @param chapterURL Current chapter URL - * @return chapter after the input, returns the current chapter if no more - */ - public static NovelChapter getNextChapter(@NotNull String chapterURL) { - if (novelChapters != null && novelChapters.size() != 0) - for (int x = 0; x < novelChapters.size(); x++) { - if (novelChapters.get(x).link.equalsIgnoreCase(chapterURL)) { - - if (NovelFragmentChapters.reversed) { - if (x - 1 != -1) - return novelChapters.get(x - 1); - else return novelChapters.get(x); - } else { - if (x + 1 != novelChapters.size()) - return novelChapters.get(x + 1); - else return novelChapters.get(x); - } - } - } - return null; - } - - /** - * @return position of last read chapter, reads array from reverse. If -1 then the array is null, if -2 the array is empty, else if not found plausible chapter returns the first. - */ - public static int lastRead() { - if (StaticNovel.novelChapters != null) { - if (StaticNovel.novelChapters.size() != 0) { - if (!NovelFragmentChapters.reversed) { - for (int x = novelChapters.size() - 1; x >= 0; x--) { - Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); - switch (status) { - default: - break; - case READ: - return x + 1; - case READING: - return x; - } - } - } else { - for (int x = 0; x < novelChapters.size(); x++) { - Status status = Database.DatabaseChapter.getStatus(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters.get(x).link)); - switch (status) { - default: - break; - case READ: - return x - 1; - case READING: - return x; - } - } - } - return 0; - } else return -2; - } else return -1; - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index ec8631ffdf..377881b9ae 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -15,7 +15,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import com.github.doomsdayrs.apps.shosetsu.ui.novel.viewHolders.ChaptersViewHolder; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 2b48ccde79..5fde48cc69 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -6,15 +6,17 @@ import android.util.Log; import android.view.View; +import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; @@ -34,17 +36,23 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 17 / 06 / 2019 * * @author github.com/doomsdayrs - */ - - -/** + *

* This task loads a novel for the novel fragment */ public class ChapterLoader extends AsyncTask { + NovelPage novelPage; + String novelURL; + ArrayList novelChapters; + Formatter formatter; + + // References private final NovelFragmentChapters novelFragmentChapters; private boolean C = true; @@ -78,37 +86,37 @@ public void setC(boolean c) { @Override protected Boolean doInBackground(Activity... voids) { this.activity = voids[0]; - StaticNovel.novelPage = null; - Log.d("ChapLoad", StaticNovel.novelURL); + novelPage = null; + Log.d("ChapLoad", novelURL); if (novelFragmentChapters != null) if (novelFragmentChapters.getActivity() != null) novelFragmentChapters.getActivity().runOnUiThread(() -> novelFragmentChapters.novelFragment.errorView.setVisibility(View.GONE)); try { - if (StaticNovel.novelChapters == null) - StaticNovel.novelChapters = new ArrayList<>(); + if (novelChapters == null) + novelChapters = new ArrayList<>(); int page = 1; - if (StaticNovel.formatter.isIncrementingChapterList()) { - StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL, page); + if (formatter.isIncrementingChapterList()) { + novelPage = formatter.parseNovel(novelURL, page); int mangaCount = 0; - while (page <= StaticNovel.novelPage.maxChapterPage && C) { + while (page <= novelPage.maxChapterPage && C) { if (novelFragmentChapters != null) { - String s = "Page: " + page + "/" + StaticNovel.novelPage.maxChapterPage; + String s = "Page: " + page + "/" + novelPage.maxChapterPage; novelFragmentChapters.pageCount.post(() -> novelFragmentChapters.pageCount.setText(s)); } - StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL, page); - for (NovelChapter novelChapter : StaticNovel.novelPage.novelChapters) + novelPage = formatter.parseNovel(novelURL, page); + for (NovelChapter novelChapter : novelPage.novelChapters) add(mangaCount, novelChapter); page++; Utilities.wait(300); } } else { - StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL, page); + novelPage = formatter.parseNovel(novelURL, page); int mangaCount = 0; - for (NovelChapter novelChapter : StaticNovel.novelPage.novelChapters) + for (NovelChapter novelChapter : novelPage.novelChapters) add(mangaCount, novelChapter); } return true; @@ -130,22 +138,13 @@ private void add(int mangaCount, NovelChapter novelChapter) { if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - StaticNovel.novelChapters.add(novelChapter); - Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(StaticNovel.novelURL), novelChapter); + novelChapters.add(novelChapter); + Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(novelURL), novelChapter); } } private void refresh(View view) { - if (StaticNovel.chapterLoader != null && StaticNovel.chapterLoader.isCancelled()) - StaticNovel.chapterLoader.cancel(true); - - if (StaticNovel.chapterLoader == null || StaticNovel.chapterLoader.isCancelled()) - - if (novelFragmentChapters != null && novelFragmentChapters.getActivity() != null) - StaticNovel.chapterLoader = new ChapterLoader(novelFragmentChapters); - else throw new NullPointerException("WHEREI SSS ITTTT"); - - StaticNovel.chapterLoader.execute(activity); + new ChapterLoader(novelFragmentChapters).execute(activity); } /** @@ -156,7 +155,7 @@ protected void onPreExecute() { if (novelFragmentChapters != null) { novelFragmentChapters.swipeRefreshLayout.setRefreshing(true); - if (StaticNovel.formatter.isIncrementingChapterList()) + if (formatter.isIncrementingChapterList()) novelFragmentChapters.pageCount.setVisibility(View.VISIBLE); } } @@ -184,7 +183,7 @@ protected void onCancelled() { protected void onPostExecute(Boolean aBoolean) { if (novelFragmentChapters != null) { novelFragmentChapters.swipeRefreshLayout.setRefreshing(false); - if (StaticNovel.formatter.isIncrementingChapterList()) + if (formatter.isIncrementingChapterList()) novelFragmentChapters.pageCount.setVisibility(View.GONE); if (aBoolean) activity.runOnUiThread(novelFragmentChapters::setNovels); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index a21f34aa19..c7c3f998c2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -9,7 +9,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java index ac540122ca..97b5cc3edb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java @@ -4,7 +4,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; import com.google.android.material.floatingactionbutton.FloatingActionButton; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 0e9c586a24..f7a79af235 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -25,7 +25,6 @@ import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.ChaptersAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.ChapterLoader; import com.github.doomsdayrs.apps.shosetsu.variables.DownloadItem; @@ -79,9 +78,9 @@ public boolean contains(NovelChapter novelChapter) { private int currentMaxPage = 1; private int findMinPosition() { - int min = StaticNovel.novelChapters.size(); - for (int x = 0; x < StaticNovel.novelChapters.size(); x++) - if (contains(StaticNovel.novelChapters.get(x))) + int min = novelFragment.novelChapters.size(); + for (int x = 0; x < novelFragment.novelChapters.size(); x++) + if (contains(novelFragment.novelChapters.get(x))) if (x < min) min = x; return min; @@ -93,8 +92,8 @@ private int findMinPosition() { private int findMaxPosition() { int max = -1; - for (int x = StaticNovel.novelChapters.size() - 1; x >= 0; x--) - if (contains(StaticNovel.novelChapters.get(x))) + for (int x = novelFragment.novelChapters.size() - 1; x >= 0; x--) + if (contains(novelFragment.novelChapters.get(x))) if (x > max) max = x; return max; @@ -132,15 +131,6 @@ public void onDestroy() { Log.d("NFChapters", "Destroy"); recyclerView = null; adapter = null; - if (StaticNovel.novelLoader != null && !StaticNovel.novelLoader.isCancelled()) { - StaticNovel.novelLoader.setC(false); - StaticNovel.novelLoader.cancel(true); - } - - if (StaticNovel.chapterLoader != null && !StaticNovel.chapterLoader.isCancelled()) { - StaticNovel.chapterLoader.setC(false); - StaticNovel.chapterLoader.cancel(true); - } } /** @@ -179,12 +169,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c resumeRead = view.findViewById(R.id.resume); resumeRead.setVisibility(View.GONE); swipeRefreshLayout.setOnRefreshListener(() -> { - if (StaticNovel.chapterLoader != null && !StaticNovel.chapterLoader.isCancelled()) { - StaticNovel.chapterLoader.setC(false); - StaticNovel.chapterLoader.cancel(true); - } - StaticNovel.chapterLoader = new ChapterLoader(this); - StaticNovel.chapterLoader.execute(getActivity()); + new ChapterLoader(this).execute(getActivity()); }); if (savedInstanceState != null) { @@ -193,9 +178,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c setNovels(); onResume(); resumeRead.setOnClickListener(view1 -> { - int i = StaticNovel.lastRead(); + int i = novelFragment.lastRead(); if (i != -1 && i != -2) - Utilities.openChapter(getActivity(), StaticNovel.novelChapters.get(i), StaticNovel.novelURL, StaticNovel.formatter.getID()); + Utilities.openChapter(getActivity(), novelFragment.novelChapters.get(i), novelFragment.novelID, novelFragment.formatter.getID()); else Toast.makeText(getContext(), "No chapters! How did you even press this!", Toast.LENGTH_SHORT).show(); }); @@ -210,16 +195,16 @@ public void setNovels() { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); - if (Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { - StaticNovel.novelChapters = Database.DatabaseChapter.getChapters(novelFragment.novelID); - if (StaticNovel.novelChapters != null && StaticNovel.novelChapters.size() != 0) + if (Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + novelFragment.novelChapters = Database.DatabaseChapter.getChapters(novelFragment.novelID); + if (novelFragment.novelChapters != null && novelFragment.novelChapters.size() != 0) resumeRead.setVisibility(View.VISIBLE); } adapter = new ChaptersAdapter(this); adapter.setHasStableIds(true); recyclerView.setLayoutManager(layoutManager); - // if (StaticNovel.formatter.isIncrementingChapterList()) { + // if (novelFragment.formatter.isIncrementingChapterList()) { // if (SettingsController.isOnline()) // recyclerView.addOnScrollListener(new NovelFragmentChaptersHitBottom(this)); @@ -246,7 +231,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.chapter_select_all: - for (NovelChapter novelChapter : StaticNovel.novelChapters) + for (NovelChapter novelChapter : novelFragment.novelChapters) if (!contains(novelChapter)) selectedChapters.add(novelChapter); NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); @@ -256,7 +241,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { for (NovelChapter novelChapter : selectedChapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); if (!Database.DatabaseChapter.isSaved(chapterID)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID); + DownloadItem downloadItem = new DownloadItem(novelFragment.formatter, novelFragment.novelPage.title, novelChapter.title, chapterID); Download_Manager.addToDownload(downloadItem); } } @@ -267,7 +252,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { for (NovelChapter novelChapter : selectedChapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); if (Database.DatabaseChapter.isSaved(chapterID)) - Download_Manager.delete(getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID)); + Download_Manager.delete(getContext(), new DownloadItem(novelFragment.formatter, novelFragment.novelPage.title, novelChapter.title, chapterID)); } NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; @@ -311,13 +296,13 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { int min = findMinPosition(); int max = findMaxPosition(); for (int x = min; x < max; x++) - if (!contains(StaticNovel.novelChapters.get(x))) - selectedChapters.add(StaticNovel.novelChapters.get(x)); + if (!contains(novelFragment.novelChapters.get(x))) + selectedChapters.add(novelFragment.novelChapters.get(x)); NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); return true; case R.id.chapter_filter: - Collections.reverse(StaticNovel.novelChapters); + Collections.reverse(novelFragment.novelChapters); NovelFragmentChapters.reversed = !NovelFragmentChapters.reversed; return NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java index c6fd59c93d..34d8eba233 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java @@ -21,7 +21,6 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.migration.MigrationView; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.listeners.NovelFragmentMainAddToLibrary; import com.github.doomsdayrs.apps.shosetsu.ui.novel.listeners.NovelFragmentUpdate; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; @@ -100,7 +99,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { Intent intent = new Intent(getActivity(), MigrationView.class); try { ArrayList novelCards = new ArrayList<>(); - novelCards.add(new NovelCard(StaticNovel.novelPage.title, StaticNovel.novelID, StaticNovel.novelURL, StaticNovel.novelPage.imageURL, StaticNovel.formatter.getID())); + novelCards.add(new NovelCard(novelFragment.novelPage.title, novelFragment.novelID, novelFragment.novelURL, novelFragment.novelPage.imageURL, novelFragment.formatter.getID())); intent.putExtra("selected", serializeToString(novelCards)); } catch (IOException e) { e.printStackTrace(); @@ -110,11 +109,11 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return true; case R.id.webview: if (getActivity() != null) - openInWebview(getActivity(), StaticNovel.novelURL); + openInWebview(getActivity(), novelFragment.novelURL); return true; case R.id.browser: if (getActivity() != null) - openInBrowser(getActivity(), StaticNovel.novelURL); + openInBrowser(getActivity(), novelFragment.novelURL); return true; } return false; @@ -180,7 +179,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (inLibrary) floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); - if (StaticNovel.novelPage != null && title != null) + if (novelFragment.novelPage != null && title != null) setData(); floatingActionButton.setOnClickListener(new NovelFragmentMainAddToLibrary(this)); @@ -193,25 +192,25 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c * Sets the data of this page */ public void setData() { - if (StaticNovel.novelPage == null) { + if (novelFragment.novelPage == null) { Log.e("NULL", "Invalid novel page"); return; } - title.setText(StaticNovel.novelPage.title); + title.setText(novelFragment.novelPage.title); - if (StaticNovel.novelPage.authors != null && StaticNovel.novelPage.authors.length > 0) - authors.setText(Arrays.toString(StaticNovel.novelPage.authors)); + if (novelFragment.novelPage.authors != null && novelFragment.novelPage.authors.length > 0) + authors.setText(Arrays.toString(novelFragment.novelPage.authors)); - description.setText(StaticNovel.novelPage.description); + description.setText(novelFragment.novelPage.description); - if (StaticNovel.novelPage.artists != null && StaticNovel.novelPage.artists.length > 0) - artists.setText(Arrays.toString(StaticNovel.novelPage.artists)); + if (novelFragment.novelPage.artists != null && novelFragment.novelPage.artists.length > 0) + artists.setText(Arrays.toString(novelFragment.novelPage.artists)); - status.setText(StaticNovel.status.getStatus()); - if (StaticNovel.novelPage.status != null) { + status.setText(novelFragment.status.getStatus()); + if (novelFragment.novelPage.status != null) { String s = "unknown"; - switch (StaticNovel.novelPage.status) { + switch (novelFragment.novelPage.status) { case PAUSED: pStat.setText(R.string.paused); s = "Paused"; @@ -229,9 +228,9 @@ public void setData() { } System.out.println("PS: " + s); } - if (StaticNovel.novelPage.genres != null && getContext() != null) { + if (novelFragment.novelPage.genres != null && getContext() != null) { LayoutInflater layoutInflater = LayoutInflater.from(getContext()); - for (String string : StaticNovel.novelPage.genres) { + for (String string : novelFragment.novelPage.genres) { Chip chip = (Chip) layoutInflater.inflate(R.layout.genre_chip, null, false); chip.setText(string); genres.addView(chip); @@ -239,13 +238,13 @@ public void setData() { } else genres.setVisibility(View.GONE); Picasso.get() - .load(StaticNovel.novelPage.imageURL) + .load(novelFragment.novelPage.imageURL) .into(imageView); Picasso.get() - .load(StaticNovel.novelPage.imageURL) + .load(novelFragment.novelPage.imageURL) .into(imageView_background); floatingActionButton.show(); - formatterName.setText(StaticNovel.formatter.getName()); + formatterName.setText(novelFragment.formatter.getName()); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index a1fe790d0a..2ee1b90c57 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -15,7 +15,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Download_Manager; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel; import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.ChaptersAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import com.github.doomsdayrs.apps.shosetsu.variables.DownloadItem; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 86e966cc3f..585e90426d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -49,8 +49,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; -import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.getNextChapter; -import static com.github.doomsdayrs.apps.shosetsu.ui.novel.StaticNovel.novelID; +import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; /* * This file is part of Shosetsu. @@ -78,8 +77,6 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { - - public boolean ready = false; public TextView textView; @@ -96,6 +93,10 @@ public class ChapterReader extends AppCompatActivity { public Formatter formatter; public int chapterID; + public int novelID; + + public String[] chapters; + public String chapterURL; public String unformattedText = null; public String text = null; @@ -349,10 +350,14 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { chapterURL = savedInstanceState.getString("chapterURL"); formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); text = savedInstanceState.getString("text"); + novelID = savedInstanceState.getInt("novelID"); + chapters = savedInstanceState.getStringArray("chapters"); } else { + chapters = getIntent().getStringArrayExtra("chapters"); chapterID = getIntent().getIntExtra("chapterID", -1); chapterURL = getIntent().getStringExtra("chapterURL"); title = getIntent().getStringExtra("title"); + novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } Log.i("Reading", chapterURL); @@ -394,7 +399,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { nextChapter = findViewById(R.id.next_chapter); nextChapter.setOnClickListener(view -> { - NovelChapter novelChapter = getNextChapter(chapterURL); + + NovelChapter novelChapter = getNextChapter(chapterURL, chapters); if (novelChapter != null) { if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java index 2f8d450065..3f40035051 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java @@ -32,7 +32,8 @@ public enum Status { READ(2, "Read"), // These two are for novels only ONHOLD(3, "OnHold"), - DROPPED(4, "Dropped"); + DROPPED(4, "Dropped"), + UNKNOWN(-1, "Unknown"); private final int a; @@ -55,4 +56,21 @@ public String getStatus() { public String toString() { return "" + a; } + + public static Status getStatus(int a) { + switch (a) { + case 0: + return UNREAD; + case 1: + return READING; + case 2: + return READ; + case 3: + return ONHOLD; + case 4: + return DROPPED; + default: + return UNKNOWN; + } + } } From bcae6806752fd4d3b623541ca346717c132fdd5c Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 7 Nov 2019 22:25:30 -0500 Subject: [PATCH 046/162] Tired, going to sleep now Cya . _.)/* --- .../apps/shosetsu/ui/novel/NovelFragment.java | 1 + .../ui/novel/async/ChapterLoader.java | 65 ++++----- .../shosetsu/ui/novel/async/NovelLoader.java | 123 +++++++++--------- .../ui/novel/pages/NovelFragmentChapters.java | 2 +- 4 files changed, 90 insertions(+), 101 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 3c82805d1e..d17bbfb876 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -68,6 +68,7 @@ public class NovelFragment extends Fragment { public List novelChapters = new ArrayList<>(); + /** * @param chapterURL Current chapter URL * @return chapter after the input, returns the current chapter if no more diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 5fde48cc69..bf34e98f11 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -1,6 +1,5 @@ package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; -import android.annotation.SuppressLint; import android.app.Activity; import android.os.AsyncTask; import android.util.Log; @@ -11,12 +10,9 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; @@ -47,34 +43,31 @@ * This task loads a novel for the novel fragment */ public class ChapterLoader extends AsyncTask { - NovelPage novelPage; - String novelURL; - ArrayList novelChapters; - Formatter formatter; + private NovelPage novelPage; + private String novelURL; + private Formatter formatter; - - // References - private final NovelFragmentChapters novelFragmentChapters; - private boolean C = true; - - @SuppressLint("StaticFieldLeak") - private Activity activity; + private NovelFragmentChapters novelFragmentChapters; /** * Constructor - * - * @param novelFragment reference to the fragment */ - ChapterLoader(NovelFragment novelFragment) { - novelFragmentChapters = novelFragment.novelFragmentChapters; + public ChapterLoader(NovelPage novelPage, String novelURL, Formatter formatter) { + this.novelPage = novelPage; + this.novelURL = novelURL; + this.formatter = formatter; } - public ChapterLoader(NovelFragmentChapters chapters) { - novelFragmentChapters = chapters; + ChapterLoader(ChapterLoader chapterLoader) { + this.novelPage = chapterLoader.novelPage; + this.novelURL = chapterLoader.novelURL; + this.formatter = chapterLoader.formatter; + this.novelFragmentChapters = chapterLoader.novelFragmentChapters; } - public void setC(boolean c) { - C = c; + public ChapterLoader setNovelFragmentChapters(NovelFragmentChapters novelFragmentChapters) { + this.novelFragmentChapters = novelFragmentChapters; + return this; } /** @@ -85,7 +78,7 @@ public void setC(boolean c) { */ @Override protected Boolean doInBackground(Activity... voids) { - this.activity = voids[0]; + Activity activity = voids[0]; novelPage = null; Log.d("ChapLoad", novelURL); @@ -94,21 +87,19 @@ protected Boolean doInBackground(Activity... voids) { novelFragmentChapters.getActivity().runOnUiThread(() -> novelFragmentChapters.novelFragment.errorView.setVisibility(View.GONE)); try { - if (novelChapters == null) - novelChapters = new ArrayList<>(); int page = 1; if (formatter.isIncrementingChapterList()) { novelPage = formatter.parseNovel(novelURL, page); int mangaCount = 0; - while (page <= novelPage.maxChapterPage && C) { + while (page <= novelPage.maxChapterPage && !activity.isDestroyed()) { if (novelFragmentChapters != null) { String s = "Page: " + page + "/" + novelPage.maxChapterPage; novelFragmentChapters.pageCount.post(() -> novelFragmentChapters.pageCount.setText(s)); } novelPage = formatter.parseNovel(novelURL, page); for (NovelChapter novelChapter : novelPage.novelChapters) - add(mangaCount, novelChapter); + add(activity, mangaCount, novelChapter); page++; Utilities.wait(300); @@ -117,7 +108,7 @@ protected Boolean doInBackground(Activity... voids) { novelPage = formatter.parseNovel(novelURL, page); int mangaCount = 0; for (NovelChapter novelChapter : novelPage.novelChapters) - add(mangaCount, novelChapter); + add(activity, mangaCount, novelChapter); } return true; } catch (IOException e) { @@ -126,25 +117,24 @@ protected Boolean doInBackground(Activity... voids) { novelFragmentChapters.getActivity().runOnUiThread(() -> { novelFragmentChapters.novelFragment.errorView.setVisibility(View.VISIBLE); novelFragmentChapters.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentChapters.novelFragment.errorButton.setOnClickListener(this::refresh); + novelFragmentChapters.novelFragment.errorButton.setOnClickListener(view -> refresh(view, activity)); }); } return false; } - private void add(int mangaCount, NovelChapter novelChapter) { + private void add(Activity activity, int mangaCount, NovelChapter novelChapter) { //TODO The getNovelID in this method likely will cause slowdowns due to IO - if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { + if (!activity.isDestroyed() && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - novelChapters.add(novelChapter); Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(novelURL), novelChapter); } } - private void refresh(View view) { - new ChapterLoader(novelFragmentChapters).execute(activity); + private void refresh(View view, Activity activity) { + new ChapterLoader(this).execute(activity); } /** @@ -163,14 +153,12 @@ protected void onPreExecute() { @Override protected void onCancelled(Boolean aBoolean) { Log.d("ChapterLoader", "Cancel"); - C = false; onPostExecute(false); } @Override protected void onCancelled() { Log.d("ChapterLoader", "Cancel"); - C = false; onPostExecute(false); } @@ -186,7 +174,8 @@ protected void onPostExecute(Boolean aBoolean) { if (formatter.isIncrementingChapterList()) novelFragmentChapters.pageCount.setVisibility(View.GONE); if (aBoolean) - activity.runOnUiThread(novelFragmentChapters::setNovels); + if (novelFragmentChapters.getActivity() != null) + novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setNovels); novelFragmentChapters.resumeRead.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index c7c3f998c2..596a950ab8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -1,19 +1,19 @@ package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; -import android.annotation.SuppressLint; import android.app.Activity; import android.os.AsyncTask; import android.util.Log; import android.view.View; +import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import java.io.IOException; -import java.util.ArrayList; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; @@ -43,17 +43,15 @@ * This task loads a novel for the novel fragment */ public class NovelLoader extends AsyncTask { + String novelURL; + Formatter formatter; + NovelPage novelPage; + int novelID; + // References private final NovelFragment novelFragment; private final NovelFragmentMain novelFragmentMain; - private boolean C = true; - - public void setC(boolean c) { - C = c; - } - @SuppressLint("StaticFieldLeak") - private Activity activity; private boolean loadAll; /** @@ -73,6 +71,11 @@ public NovelLoader(NovelFragmentMain novelFragmentMain, boolean loadAll) { this.novelFragmentMain = novelFragmentMain; } + NovelLoader(NovelLoader novelLoader) { + this.novelFragment = novelLoader.novelFragment; + this.loadAll = novelLoader.loadAll; + this.novelFragmentMain = novelLoader.novelFragmentMain; + } /** * Background process @@ -83,9 +86,8 @@ public NovelLoader(NovelFragmentMain novelFragmentMain, boolean loadAll) { @Override protected Boolean doInBackground(Activity... voids) { - this.activity = voids[0]; - StaticNovel.novelPage = null; - Log.d("Loading", StaticNovel.novelURL); + Activity activity = voids[0]; + Log.d("Loading", novelURL); if (loadAll) { if (novelFragment != null && novelFragment.getActivity() != null) novelFragment.getActivity().runOnUiThread(() -> novelFragment.errorView.setVisibility(View.GONE)); @@ -95,21 +97,18 @@ protected Boolean doInBackground(Activity... voids) { try { - StaticNovel.novelPage = StaticNovel.formatter.parseNovel(StaticNovel.novelURL); - if (C && !Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { - Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); + novelPage = formatter.parseNovel(novelURL); + if (!activity.isDestroyed() && !Database.DatabaseNovels.inDatabase(novelID)) { + Database.DatabaseNovels.addToLibrary(formatter.getID(), novelPage, novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } //TODO The getNovelID in this method likely will cause slowdowns due to IO - int novelID = getNovelIDFromNovelURL(StaticNovel.novelURL); - for (NovelChapter novelChapter : StaticNovel.novelPage.novelChapters) - if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) + int novelID = getNovelIDFromNovelURL(novelURL); + for (NovelChapter novelChapter : novelPage.novelChapters) + if (!activity.isDestroyed() && !Database.DatabaseChapter.inChapters(novelChapter.link)) Database.DatabaseChapter.addToChapters(novelID, novelChapter); - System.out.println(StaticNovel.novelChapters); - if (StaticNovel.novelChapters == null) - StaticNovel.novelChapters = new ArrayList<>(); - StaticNovel.novelChapters.addAll(StaticNovel.novelPage.novelChapters); - Log.d("Loaded Novel:", StaticNovel.novelPage.title); + + Log.d("Loaded Novel:", novelPage.title); return true; } catch (IOException e) { if (loadAll) { @@ -117,13 +116,13 @@ protected Boolean doInBackground(Activity... voids) { novelFragment.getActivity().runOnUiThread(() -> { novelFragment.errorView.setVisibility(View.VISIBLE); novelFragment.errorMessage.setText(e.getMessage()); - novelFragment.errorButton.setOnClickListener(this::refresh); + novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); } else if (novelFragmentMain != null && novelFragmentMain.getActivity() != null) novelFragmentMain.getActivity().runOnUiThread(() -> { novelFragmentMain.novelFragment.errorView.setVisibility(View.VISIBLE); novelFragmentMain.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentMain.novelFragment.errorButton.setOnClickListener(this::refresh); + novelFragmentMain.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); @@ -131,13 +130,8 @@ protected Boolean doInBackground(Activity... voids) { return false; } - private void refresh(View view) { - if (StaticNovel.novelLoader != null && StaticNovel.novelLoader.isCancelled()) - StaticNovel.novelLoader.cancel(true); - - if (StaticNovel.novelLoader == null || StaticNovel.novelLoader.isCancelled()) - StaticNovel.novelLoader = new NovelLoader(novelFragmentMain, loadAll); - StaticNovel.novelLoader.execute(activity); + private void refresh(Activity activity) { + new NovelLoader(this).execute(activity); } /** @@ -156,7 +150,6 @@ protected void onPreExecute() { @Override protected void onCancelled() { - C = false; onPostExecute(false); } @@ -167,40 +160,46 @@ protected void onCancelled() { */ @Override protected void onPostExecute(Boolean aBoolean) { - if (loadAll) { - assert novelFragment != null; - novelFragment.progressBar.setVisibility(View.GONE); - } else { - assert novelFragmentMain != null; - novelFragmentMain.swipeRefreshLayout.setRefreshing(false); - if (Database.DatabaseNovels.inDatabase(StaticNovel.novelID)) { - try { - Database.DatabaseNovels.updateData(StaticNovel.novelURL, StaticNovel.novelPage); - } catch (Exception e) { - e.printStackTrace(); - } - } + Activity activity = null; + if (novelFragmentMain != null) + activity = novelFragmentMain.getActivity(); + else if (novelFragment != null) { + activity = novelFragment.getActivity(); } - if (aBoolean) { - Statics.mainActionBar.setTitle(StaticNovel.novelPage.title); - activity.runOnUiThread(() -> { - assert novelFragment != null; - if (loadAll) - novelFragment.novelFragmentMain.setData(); - else { - assert novelFragmentMain != null; - novelFragmentMain.setData(); - } - }); + if (activity != null) { if (loadAll) { - if (StaticNovel.chapterLoader != null && StaticNovel.chapterLoader.isCancelled()) - StaticNovel.chapterLoader.cancel(true); + if (novelFragment != null) { + novelFragment.progressBar.setVisibility(View.GONE); + } + } else { + if (novelFragmentMain != null) { + novelFragmentMain.swipeRefreshLayout.setRefreshing(false); + } + if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + try { + Database.DatabaseNovels.updateData(novelURL, novelPage); + } catch (Exception e) { + e.printStackTrace(); + } + } + } - if ((StaticNovel.chapterLoader == null || StaticNovel.chapterLoader.isCancelled()) && novelFragment != null) - StaticNovel.chapterLoader = new ChapterLoader(novelFragment); - activity.runOnUiThread(() -> StaticNovel.chapterLoader.execute(activity)); + if (aBoolean) { + Statics.mainActionBar.setTitle(novelPage.title); + activity.runOnUiThread(() -> { + if (loadAll) + if (novelFragment != null) { + novelFragment.novelFragmentMain.setData(); + } else { + novelFragmentMain.setData(); + } + }); + if (loadAll) { + activity.runOnUiThread(() -> new ChapterLoader(novelPage, novelURL, formatter).execute()); + } } } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index f7a79af235..06f3d76569 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -169,7 +169,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c resumeRead = view.findViewById(R.id.resume); resumeRead.setVisibility(View.GONE); swipeRefreshLayout.setOnRefreshListener(() -> { - new ChapterLoader(this).execute(getActivity()); + new ChapterLoader(novelFragment.novelPage, novelFragment.novelURL, novelFragment.formatter).setNovelFragmentChapters(this).execute(getActivity()); }); if (savedInstanceState != null) { From ca9df44f0b5c83f9e755de924161b7419b7213ea Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 8 Nov 2019 14:01:54 -0500 Subject: [PATCH 047/162] Finnaly completed removal of StaticNovel, no more hanging values :D --- .../viewHolder/NovelCardViewHolder.java | 5 +-- .../viewHolders/LibraryViewHolder.java | 4 +- .../apps/shosetsu/ui/novel/NovelFragment.java | 10 ++--- .../ui/novel/adapters/ChaptersAdapter.java | 8 ++-- .../shosetsu/ui/novel/async/NovelLoader.java | 42 +++++++++---------- .../NovelFragmentMainAddToLibrary.java | 22 +++++----- .../novel/listeners/NovelFragmentUpdate.java | 10 ++--- ...agmentMain.java => NovelFragmentInfo.java} | 4 +- .../novel/viewHolders/ChaptersViewHolder.java | 6 +-- .../viewHolder/UpdatedChapterHolder.java | 3 +- 10 files changed, 57 insertions(+), 57 deletions(-) rename app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/{NovelFragmentMain.java => NovelFragmentInfo.java} (99%) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java index 49946bb593..5bf1b7a192 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/NovelCardViewHolder.java @@ -57,10 +57,9 @@ public NovelCardViewHolder(@NonNull View itemView) { @Override public void onClick(View v) { NovelFragment novelFragment = new NovelFragment(); - StaticNovel.formatter = formatter; - StaticNovel.novelURL = url; + novelFragment.novelURL = url; + novelFragment.formatter = formatter; novelFragment.novelID = Database.DatabaseIdentification.getNovelIDFromNovelURL(url); - if (catalogueFragment.getFragmentManager() != null) catalogueFragment.getFragmentManager().beginTransaction() .addToBackStack("tag") diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index 64f61928fb..19180eecce 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -82,9 +82,9 @@ private void removeFromSelect() { @Override public void onClick(View v) { NovelFragment novelFragment = new NovelFragment(); + novelFragment.formatter = formatter; + novelFragment.novelURL = novelCard.novelURL; novelFragment.novelID = novelCard.novelID; - StaticNovel.formatter = formatter; - StaticNovel.setNovelID(novelCard.novelID); assert libraryFragment.getFragmentManager() != null; libraryFragment.getFragmentManager().beginTransaction() .addToBackStack("tag") diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index d17bbfb876..e331ac32b9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -23,7 +23,7 @@ import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.NovelPagerAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; @@ -130,7 +130,7 @@ public int lastRead() { } - public NovelFragmentMain novelFragmentMain; + public NovelFragmentInfo novelFragmentInfo; public NovelFragmentChapters novelFragmentChapters; public ProgressBar progressBar; @@ -177,8 +177,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c // Create sub-fragments { - novelFragmentMain = new NovelFragmentMain(); - novelFragmentMain.setNovelFragment(this); + novelFragmentInfo = new NovelFragmentInfo(); + novelFragmentInfo.setNovelFragment(this); novelFragmentChapters = new NovelFragmentChapters(); novelFragmentChapters.setNovelFragment(this); } @@ -211,7 +211,7 @@ private void setViewPager() { List fragments = new ArrayList<>(); { Log.d("FragmentLoading", "Main"); - fragments.add(novelFragmentMain); + fragments.add(novelFragmentInfo); Log.d("FragmentLoading", "Chapters"); fragments.add(novelFragmentChapters); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index 377881b9ae..da034202f6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -69,7 +69,7 @@ public ChaptersViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i @Override public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int i) { - NovelChapter novelChapter = StaticNovel.novelChapters.get(i); + NovelChapter novelChapter = novelFragmentChapters.novelFragment.novelChapters.get(i); chaptersViewHolder.novelChapter = novelChapter; chaptersViewHolder.library_card_title.setText(novelChapter.title); chaptersViewHolder.novelFragmentChapters = novelFragmentChapters; @@ -79,7 +79,7 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int //TODO The getNovelID in this method likely will cause slowdowns due to IO if (!Database.DatabaseChapter.inChapters(novelChapter.link)) - Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(StaticNovel.novelURL), novelChapter); + Database.DatabaseChapter.addToChapters(getNovelIDFromNovelURL(novelFragmentChapters.novelFragment.novelURL), novelChapter); if (Database.DatabaseChapter.isBookMarked(chapterID)) { chaptersViewHolder.library_card_title.setTextColor(chaptersViewHolder.itemView.getResources().getColor(R.color.bookmarked)); @@ -154,8 +154,8 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int @Override public int getItemCount() { - if (StaticNovel.novelChapters != null) - return StaticNovel.novelChapters.size(); + if (novelFragmentChapters.novelFragment.novelChapters != null) + return novelFragmentChapters.novelFragment.novelChapters.size(); else return 0; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 596a950ab8..f1c88d8aed 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -10,7 +10,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import java.io.IOException; @@ -50,7 +50,7 @@ public class NovelLoader extends AsyncTask { // References private final NovelFragment novelFragment; - private final NovelFragmentMain novelFragmentMain; + private final NovelFragmentInfo novelFragmentInfo; private boolean loadAll; @@ -62,19 +62,19 @@ public class NovelLoader extends AsyncTask { public NovelLoader(NovelFragment novelFragment, boolean loadAll) { this.novelFragment = novelFragment; this.loadAll = loadAll; - this.novelFragmentMain = null; + this.novelFragmentInfo = null; } - public NovelLoader(NovelFragmentMain novelFragmentMain, boolean loadAll) { + public NovelLoader(NovelFragmentInfo novelFragmentInfo, boolean loadAll) { this.novelFragment = null; this.loadAll = loadAll; - this.novelFragmentMain = novelFragmentMain; + this.novelFragmentInfo = novelFragmentInfo; } NovelLoader(NovelLoader novelLoader) { this.novelFragment = novelLoader.novelFragment; this.loadAll = novelLoader.loadAll; - this.novelFragmentMain = novelLoader.novelFragmentMain; + this.novelFragmentInfo = novelLoader.novelFragmentInfo; } /** @@ -92,8 +92,8 @@ protected Boolean doInBackground(Activity... voids) { if (novelFragment != null && novelFragment.getActivity() != null) novelFragment.getActivity().runOnUiThread(() -> novelFragment.errorView.setVisibility(View.GONE)); - } else if (novelFragmentMain != null && novelFragmentMain.getActivity() != null) - novelFragmentMain.getActivity().runOnUiThread(() -> novelFragmentMain.novelFragment.errorView.setVisibility(View.GONE)); + } else if (novelFragmentInfo != null && novelFragmentInfo.getActivity() != null) + novelFragmentInfo.getActivity().runOnUiThread(() -> novelFragmentInfo.novelFragment.errorView.setVisibility(View.GONE)); try { @@ -118,11 +118,11 @@ protected Boolean doInBackground(Activity... voids) { novelFragment.errorMessage.setText(e.getMessage()); novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); - } else if (novelFragmentMain != null && novelFragmentMain.getActivity() != null) - novelFragmentMain.getActivity().runOnUiThread(() -> { - novelFragmentMain.novelFragment.errorView.setVisibility(View.VISIBLE); - novelFragmentMain.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentMain.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); + } else if (novelFragmentInfo != null && novelFragmentInfo.getActivity() != null) + novelFragmentInfo.getActivity().runOnUiThread(() -> { + novelFragmentInfo.novelFragment.errorView.setVisibility(View.VISIBLE); + novelFragmentInfo.novelFragment.errorMessage.setText(e.getMessage()); + novelFragmentInfo.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); @@ -143,8 +143,8 @@ protected void onPreExecute() { assert novelFragment != null; novelFragment.progressBar.setVisibility(View.VISIBLE); } else { - assert novelFragmentMain != null; - novelFragmentMain.swipeRefreshLayout.setRefreshing(true); + assert novelFragmentInfo != null; + novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); } } @@ -161,8 +161,8 @@ protected void onCancelled() { @Override protected void onPostExecute(Boolean aBoolean) { Activity activity = null; - if (novelFragmentMain != null) - activity = novelFragmentMain.getActivity(); + if (novelFragmentInfo != null) + activity = novelFragmentInfo.getActivity(); else if (novelFragment != null) { activity = novelFragment.getActivity(); } @@ -173,8 +173,8 @@ else if (novelFragment != null) { novelFragment.progressBar.setVisibility(View.GONE); } } else { - if (novelFragmentMain != null) { - novelFragmentMain.swipeRefreshLayout.setRefreshing(false); + if (novelFragmentInfo != null) { + novelFragmentInfo.swipeRefreshLayout.setRefreshing(false); } if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { try { @@ -190,9 +190,9 @@ else if (novelFragment != null) { activity.runOnUiThread(() -> { if (loadAll) if (novelFragment != null) { - novelFragment.novelFragmentMain.setData(); + novelFragment.novelFragmentInfo.setData(); } else { - novelFragmentMain.setData(); + novelFragmentInfo.setData(); } }); if (loadAll) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java index 97b5cc3edb..3092cb0c52 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentMainAddToLibrary.java @@ -4,7 +4,7 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.google.android.material.floatingactionbutton.FloatingActionButton; /* @@ -29,25 +29,25 @@ * @author github.com/doomsdayrs */ public class NovelFragmentMainAddToLibrary implements FloatingActionButton.OnClickListener { - private final NovelFragmentMain novelFragmentMain; + private final NovelFragmentInfo novelFragmentInfo; - public NovelFragmentMainAddToLibrary(NovelFragmentMain novelFragmentMain) { - this.novelFragmentMain = novelFragmentMain; + public NovelFragmentMainAddToLibrary(NovelFragmentInfo novelFragmentInfo) { + this.novelFragmentInfo = novelFragmentInfo; } @Override public void onClick(View v) { - if (!novelFragmentMain.inLibrary) { + if (!novelFragmentInfo.inLibrary) { // Thinking about this, this is an impossible combination as the novel should've loaded before this // if (!Database.DatabaseNovels.inLibrary(StaticNovel.novelID)) // Database.DatabaseNovels.addToLibrary(StaticNovel.formatter.getID(), StaticNovel.novelPage, StaticNovel, StaticNovel.status.getA()); - Database.DatabaseNovels.bookMark(StaticNovel.novelID); - novelFragmentMain.inLibrary = true; - novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); + Database.DatabaseNovels.bookMark(novelFragmentInfo.novelFragment.novelID); + novelFragmentInfo.inLibrary = true; + novelFragmentInfo.floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); } else { - Database.DatabaseNovels.unBookmark(StaticNovel.novelID); - novelFragmentMain.inLibrary = false; - novelFragmentMain.floatingActionButton.setImageResource(R.drawable.ic_add_circle_outline_black_24dp); + Database.DatabaseNovels.unBookmark(novelFragmentInfo.novelFragment.novelID); + novelFragmentInfo.inLibrary = false; + novelFragmentInfo.floatingActionButton.setImageResource(R.drawable.ic_add_circle_outline_black_24dp); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java index 303cf4ac26..0499d400ff 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java @@ -3,7 +3,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentMain; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; /* * This file is part of Shosetsu. @@ -28,14 +28,14 @@ */ public class NovelFragmentUpdate implements SwipeRefreshLayout.OnRefreshListener { - private NovelFragmentMain novelFragmentMain; + private NovelFragmentInfo novelFragmentInfo; - public NovelFragmentUpdate(NovelFragmentMain novelFragmentMain) { - this.novelFragmentMain = novelFragmentMain; + public NovelFragmentUpdate(NovelFragmentInfo novelFragmentInfo) { + this.novelFragmentInfo = novelFragmentInfo; } @Override public void onRefresh() { - new NovelLoader(novelFragmentMain, false).execute(novelFragmentMain.getActivity()); + new NovelLoader(novelFragmentInfo, false).execute(novelFragmentInfo.getActivity()); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java similarity index 99% rename from app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java rename to app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java index 34d8eba233..45daa832a8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentMain.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java @@ -62,7 +62,7 @@ /** * The page you see when you select a novel */ -public class NovelFragmentMain extends Fragment { +public class NovelFragmentInfo extends Fragment { private ImageView imageView; private ImageView imageView_background; @@ -84,7 +84,7 @@ public class NovelFragmentMain extends Fragment { /** * Constructor */ - public NovelFragmentMain() { + public NovelFragmentInfo() { setHasOptionsMenu(true); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index 2ee1b90c57..e591c29cd0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -100,10 +100,10 @@ public ChaptersViewHolder(@NonNull View itemView) { return true; case R.id.popup_chapter_menu_download: if (!Database.DatabaseChapter.isSaved(chapterID)) { - DownloadItem downloadItem = new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID); + DownloadItem downloadItem = new DownloadItem(novelFragmentChapters.novelFragment.formatter, novelFragmentChapters.novelFragment.novelPage.title, novelChapter.title, chapterID); Download_Manager.addToDownload(downloadItem); } else { - if (Download_Manager.delete(itemView.getContext(), new DownloadItem(StaticNovel.formatter, StaticNovel.novelPage.title, novelChapter.title, chapterID))) { + if (Download_Manager.delete(itemView.getContext(), new DownloadItem(novelFragmentChapters.novelFragment.formatter, novelFragmentChapters.novelFragment.novelPage.title, novelChapter.title, chapterID))) { downloadTag.setVisibility(View.INVISIBLE); } } @@ -165,6 +165,6 @@ private void removeFromSelect() { @Override public void onClick(View v) { - openChapter(novelFragmentChapters.getActivity(), novelChapter, StaticNovel.novelURL, StaticNovel.formatter.getID()); + openChapter(novelFragmentChapters.getActivity(), novelChapter, novelFragmentChapters.novelFragment.novelID, novelFragmentChapters.novelFragment.formatter.getID()); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index b18802dc29..67ae7414b4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -37,6 +37,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterIDFromChapterURL; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getFormatterIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; /** * shosetsu @@ -84,6 +85,6 @@ public void onClick(View view) { String nurl = Database.DatabaseIdentification.getNovelURLFromChapterURL(novelChapter.link); Formatter formatter = DefaultScrapers.getByID(getFormatterIDFromNovelURL(nurl)); if (formatter != null) - openChapter((Activity) itemView.getContext(), novelChapter, nurl, formatter.getID()); + openChapter((Activity) itemView.getContext(), novelChapter, getNovelIDFromNovelURL(nurl), formatter.getID()); } } From 037c5255d3da1ff2db5cd618723d1716ba5f06da Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 8 Nov 2019 18:08:18 -0500 Subject: [PATCH 048/162] Small edit to copying of self to new thread --- .../shosetsu/ui/novel/async/NovelLoader.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index f1c88d8aed..b2b04befd9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -33,20 +33,22 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 17 / 06 / 2019 * * @author github.com/doomsdayrs - */ - -/** + *

* This task loads a novel for the novel fragment + *

*/ public class NovelLoader extends AsyncTask { - String novelURL; - Formatter formatter; - NovelPage novelPage; - int novelID; + private String novelURL; + private Formatter formatter; + private NovelPage novelPage; + private int novelID; // References private final NovelFragment novelFragment; @@ -71,7 +73,11 @@ public NovelLoader(NovelFragmentInfo novelFragmentInfo, boolean loadAll) { this.novelFragmentInfo = novelFragmentInfo; } - NovelLoader(NovelLoader novelLoader) { + private NovelLoader(NovelLoader novelLoader) { + this.novelURL = novelLoader.novelURL; + this.formatter = novelLoader.formatter; + this.novelPage = novelLoader.novelPage; + this.novelID = novelLoader.novelID; this.novelFragment = novelLoader.novelFragment; this.loadAll = novelLoader.loadAll; this.novelFragmentInfo = novelLoader.novelFragmentInfo; From aed42597399dddf92ebb243a6ca852c203cd284a Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 9 Nov 2019 07:18:46 -0500 Subject: [PATCH 049/162] Time to work on scraping a webview --- app/build.gradle | 4 +- .../shosetsu/variables/DefaultScrapers.java | 50 +++++++++++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 55c34d3bef..b03bab52fa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -58,8 +58,8 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' - implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.4' - implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.2' + implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.5' + implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.4' implementation 'com.squareup.picasso:picasso:2.71828' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java index 85970f89f3..75bd3aab0d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java @@ -8,8 +8,11 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelGenre; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Ordering; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueCard; +import org.jsoup.nodes.Document; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -46,11 +49,11 @@ // TODO Make this full dynamic, not needing to be predefined // > Make IDs built into the formatter public enum DefaultScrapers implements Formatter { - NOVELFULL(new NovelFull(1)), - BOXNOVEL(new BoxNovel(2)), - SYOSETU(new Syosetu(3)), + NOVELFULL(new NovelFull()), + BOXNOVEL(new BoxNovel()), + SYOSETU(new Syosetu()), //NOVELPLANENT(new NovelPlanet(4)), - BESTLIGHTNOVEL(new BestLightNovel(5)); + BESTLIGHTNOVEL(new BestLightNovel()); public static final ArrayList formatters = new ArrayList<>(); @@ -142,14 +145,37 @@ public Ordering latestOrder() { return formatter.latestOrder(); } + @Override + public String getNovelPassage(Document document) { + return formatter.getNovelPassage(document); + } + + @Deprecated public String getNovelPassage(String URL) throws IOException { return formatter.getNovelPassage(URL); } + @Override + public NovelPage parseNovel(Document document) { + return formatter.parseNovel(document); + } + + @Override + public NovelPage parseNovel(Document document, int i) { + return formatter.parseNovel(document, i); + } + + @Override + public String novelPageCombiner(String s, int i) { + return formatter.novelPageCombiner(s, i); + } + + @Deprecated public NovelPage parseNovel(String URL) throws IOException { return formatter.parseNovel(URL); } + @Deprecated public NovelPage parseNovel(String URL, int increment) throws IOException { return formatter.parseNovel(URL, increment); } @@ -158,11 +184,27 @@ public String getLatestURL(int page) { return formatter.getLatestURL(page); } + @Override + public List parseLatest(Document document) { + return formatter.parseLatest(document); + } + + @Deprecated public List parseLatest(String URL) throws IOException { return formatter.parseLatest(URL); } @Override + public String getSearchString(String s) { + return formatter.getSearchString(s); + } + + @Override + public List parseSearch(Document document) { + return formatter.parseSearch(document); + } + + @Deprecated public List search(String query) throws IOException { return formatter.search(query); } From 25acb94c6b71c6b8f83e9f949517d01405114d9c Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 9 Nov 2019 18:52:04 -0500 Subject: [PATCH 050/162] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa THE SYNC ERRORs --- .../backend/scraper/WebViewScrapper.java | 94 +++++++++++++++++++ .../ui/catalogue/CatalogueFragment.java | 6 ++ .../ui/catalogue/CataloguesFragment.java | 9 +- .../catalogue/adapters/CataloguesAdapter.java | 7 +- .../catalogue/async/CataloguePageLoader.java | 78 ++++++--------- .../catalogue/async/CatalogueQuerySearch.java | 11 +-- .../catalogue/viewHolder/CatalogueHolder.java | 6 +- .../apps/shosetsu/ui/main/MainActivity.java | 12 ++- .../main/listener/NavigationSwapListener.java | 3 +- app/src/main/res/layout/activity_main.xml | 11 ++- 10 files changed, 173 insertions(+), 64 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java new file mode 100644 index 0000000000..ab16560c7e --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -0,0 +1,94 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.scraper; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.annotation.SuppressLint; +import android.webkit.JavascriptInterface; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import java.util.concurrent.TimeUnit; + +/** + * shosetsu + * 09 / 11 / 2019 + * + * @author github.com/doomsdayrs + */ +public class WebViewScrapper { + private final WebView webView; + private String returnedHTML = null; + private boolean checked = false; + + @SuppressLint("SetJavaScriptEnabled") + public WebViewScrapper(WebView webView) { + this.webView = webView; + webView.getSettings().setJavaScriptEnabled(true); + webView.addJavascriptInterface(this, "HTMLOUT"); + + webView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + view.loadUrl(url); + returnedHTML = null; + return false; + } + + public void onPageFinished(WebView view, String url) { + view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');"); + checked = !returnedHTML.contains("cf-browser-verification"); + } + }); + } + + @JavascriptInterface + public void processHTML(String html) { + returnedHTML = html; + //cf-browser-verification + } + + /** + * Put this in an async task, or you will have a bad time. + * + * @param url URL to retrieve; + * @return Document of the URL + * @throws InterruptedException This fucked up hard + */ + public Document docFromURL(String url) { + webView.loadUrl(url); + + int count = 0; + while (checked && returnedHTML == null) { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + count++; + if (count == 120) { + return null; + } + } + Document document = Jsoup.parse(returnedHTML); + returnedHTML = null; + return document; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java index e5bf425e3a..2d85596a15 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java @@ -25,6 +25,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.WebviewCookieHandler; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.adapters.CatalogueAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.async.CataloguePageLoader; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.listeners.CatalogueHitBottom; @@ -65,6 +66,7 @@ */ //TODO fix issue with not loading public class CatalogueFragment extends Fragment { + public WebViewScrapper webViewScrapper; public ArrayList catalogueNovelCards = new ArrayList<>(); public Formatter formatter; public SwipeRefreshLayout swipeRefreshLayout; @@ -91,6 +93,10 @@ public CatalogueFragment() { setHasOptionsMenu(true); } + public void setWebViewScrapper(WebViewScrapper webViewScrapper) { + this.webViewScrapper = webViewScrapper; + } + public void setFormatter(Formatter formatter) { this.formatter = formatter; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java index d331b215f7..f988c2c982 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java @@ -16,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.adapters.CataloguesAdapter; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; @@ -49,6 +50,7 @@ */ //TODO Searching mechanics here public class CataloguesFragment extends Fragment { + private WebViewScrapper webViewScrapper; private ArrayList cards = null; /** @@ -86,13 +88,18 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c View view = inflater.inflate(R.layout.fragment_catalogues, container, false); RecyclerView recyclerView = view.findViewById(R.id.catalogues_recycler); + if (recyclerView != null) { recyclerView.setHasFixedSize(true); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(Objects.requireNonNull(container).getContext()); - RecyclerView.Adapter adapter = new CataloguesAdapter(cards, fragmentManager); + RecyclerView.Adapter adapter = new CataloguesAdapter(cards, fragmentManager, webViewScrapper); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); } return view; } + + public void setWebViewScrapper(WebViewScrapper webViewScrapper) { + this.webViewScrapper = webViewScrapper; + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java index 9d757b17c1..e1b3a5ae53 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.viewHolder.CatalogueHolder; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueCard; import com.squareup.picasso.Picasso; @@ -37,12 +38,14 @@ * @author github.com/doomsdayrs */ public class CataloguesAdapter extends RecyclerView.Adapter { + private final WebViewScrapper webViewScrapper; private final ArrayList catalogues; private final FragmentManager fragmentManager; - public CataloguesAdapter(ArrayList catalogues, FragmentManager fragmentManager) { + public CataloguesAdapter(ArrayList catalogues, FragmentManager fragmentManager, WebViewScrapper webViewScrapper) { this.catalogues = catalogues; this.fragmentManager = fragmentManager; + this.webViewScrapper = webViewScrapper; } @@ -50,7 +53,7 @@ public CataloguesAdapter(ArrayList catalogues, FragmentManager fr @Override public CatalogueHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalogue_item_card, viewGroup, false); - return new CatalogueHolder(view, fragmentManager); + return new CatalogueHolder(view, fragmentManager, webViewScrapper); } @Override diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index 24386c8143..b9b9310520 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -11,7 +11,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.listeners.CatalogueHitBottom; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; -import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; @@ -75,57 +74,42 @@ protected Boolean doInBackground(Integer... integers) { catalogueFragment.getActivity().runOnUiThread(() -> Toast.makeText(catalogueFragment.getContext(), "CLOUDFLARE", Toast.LENGTH_SHORT).show()); } - try { - List novels; - if (catalogueFragment.formatter.hasCloudFlare()) { - try { - TimeUnit.SECONDS.sleep(5); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - // Loads novel list - if (integers.length == 0) - novels = catalogueFragment.formatter.parseLatest(catalogueFragment.formatter.getLatestURL(1)); - else { - novels = catalogueFragment.formatter.parseLatest(catalogueFragment.formatter.getLatestURL(integers[0])); - } - - for (Novel novel : novels) - catalogueFragment.catalogueNovelCards.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); - catalogueFragment.library_view.post(() -> catalogueFragment.catalogueAdapter.notifyDataSetChanged()); - - if (catalogueHitBottom != null) { - catalogueFragment.library_view.post(() -> { - catalogueFragment.catalogueAdapter.notifyDataSetChanged(); - catalogueFragment.library_view.addOnScrollListener(catalogueHitBottom); - }); - catalogueHitBottom.running = false; - Log.d("CatalogueFragmentLoad", "Completed"); + List novels; + if (catalogueFragment.formatter.hasCloudFlare()) { + try { + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); } - Log.d("FragmentRefresh", "Complete"); + } + // Loads novel list + if (integers.length == 0) + novels = catalogueFragment.formatter.parseLatest(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getLatestURL(1))); + else { + novels = catalogueFragment.formatter.parseLatest(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getLatestURL(integers[0]))); + } - if (catalogueFragment.getActivity() != null) - catalogueFragment.getActivity().runOnUiThread(() -> { - catalogueFragment.catalogueAdapter.notifyDataSetChanged(); - catalogueFragment.swipeRefreshLayout.setRefreshing(false); - }); + for (Novel novel : novels) + catalogueFragment.catalogueNovelCards.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); + catalogueFragment.library_view.post(() -> catalogueFragment.catalogueAdapter.notifyDataSetChanged()); - return true; - } catch (IOException e) { - if (catalogueFragment.getActivity() != null) - catalogueFragment.getActivity().runOnUiThread(() -> { - catalogueFragment.errorView.setVisibility(View.VISIBLE); - catalogueFragment.errorMessage.setText(e.getMessage()); - if (catalogueHitBottom == null) - catalogueFragment.errorButton.setOnClickListener(view -> new CataloguePageLoader(catalogueFragment).execute(integers)); - else - catalogueFragment.errorButton.setOnClickListener(view -> new CataloguePageLoader(catalogueFragment, catalogueHitBottom).execute(integers)); + if (catalogueHitBottom != null) { + catalogueFragment.library_view.post(() -> { + catalogueFragment.catalogueAdapter.notifyDataSetChanged(); + catalogueFragment.library_view.addOnScrollListener(catalogueHitBottom); + }); + catalogueHitBottom.running = false; + Log.d("CatalogueFragmentLoad", "Completed"); + } + Log.d("FragmentRefresh", "Complete"); - }); + if (catalogueFragment.getActivity() != null) + catalogueFragment.getActivity().runOnUiThread(() -> { + catalogueFragment.catalogueAdapter.notifyDataSetChanged(); + catalogueFragment.swipeRefreshLayout.setRefreshing(false); + }); - } - return false; + return true; } /** diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java index 58056510fc..e154594233 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java @@ -7,7 +7,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; -import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -48,13 +47,9 @@ public CatalogueQuerySearch(CatalogueFragment catalogueFragment) { @Override protected ArrayList doInBackground(String... strings) { ArrayList result = new ArrayList<>(); - try { - List novels = catalogueFragment.formatter.search(strings[0]); - for (Novel novel : novels) - result.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); - } catch (IOException e) { - e.printStackTrace(); - } + List novels = catalogueFragment.formatter.parseSearch(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getSearchString(strings[0]))); + for (Novel novel : novels) + result.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); return result; } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java index 2e2a82dafe..f99a5c909e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java @@ -29,6 +29,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isOnline; @@ -40,16 +41,18 @@ * @author github.com/doomsdayrs */ public class CatalogueHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + WebViewScrapper webViewScrapper; public final ImageView library_card_image; public final TextView library_card_title; final FragmentManager fragmentManager; Formatter formatter; - public CatalogueHolder(@NonNull View itemView, FragmentManager fragmentManager) { + public CatalogueHolder(@NonNull View itemView, FragmentManager fragmentManager, WebViewScrapper webViewScrapper) { super(itemView); library_card_image = itemView.findViewById(R.id.catalogue_item_card_image); library_card_title = itemView.findViewById(R.id.catalogue_item_card_text); this.fragmentManager = fragmentManager; + this.webViewScrapper = webViewScrapper; } public void setFormatter(Formatter formatter) { @@ -64,6 +67,7 @@ public void onClick(View v) { if (isOnline()) { CatalogueFragment catalogueFragment = new CatalogueFragment(); catalogueFragment.setFormatter(formatter); + catalogueFragment.setWebViewScrapper(webViewScrapper); setFormatter(formatter); fragmentManager.beginTransaction() .addToBackStack("tag") diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index 6f1df30f4b..dba66828df 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -6,6 +6,7 @@ import android.net.ConnectivityManager; import android.os.Bundle; import android.util.Log; +import android.webkit.WebView; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; @@ -19,6 +20,8 @@ import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.DBHelper; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; +import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CataloguesFragment; import com.github.doomsdayrs.apps.shosetsu.ui.downloads.DownloadsFragment; import com.github.doomsdayrs.apps.shosetsu.ui.library.LibraryFragment; import com.github.doomsdayrs.apps.shosetsu.ui.main.listener.NavigationSwapListener; @@ -61,13 +64,15 @@ public class MainActivity extends AppCompatActivity { public DrawerLayout drawerLayout; public NavigationView navigationView; + public final CataloguesFragment cataloguesFragment = new CataloguesFragment(); + private WebView webView; public final LibraryFragment libraryFragment = new LibraryFragment(); + private WebViewScrapper webViewScrapper; public final UpdatesFragment updatesFragment = new UpdatesFragment(); public final SettingsFragment settingsFragment = new SettingsFragment(); public final DownloadsFragment downloadsFragment = new DownloadsFragment(); - /** * Main activity * @@ -163,12 +168,17 @@ public void onFailed(AppUpdaterError error) { //Sets up the sidebar drawerLayout = findViewById(R.id.drawer_layout); navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(new NavigationSwapListener(this)); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawerLayout.addDrawerListener(toggle); toggle.syncState(); + webView = findViewById(R.id.absolute_webview); + webViewScrapper = new WebViewScrapper(webView); + cataloguesFragment.setWebViewScrapper(webViewScrapper); + // Sets up DB DBHelper helper = new DBHelper(this); Database.sqLiteDatabase = helper.getWritableDatabase(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java index d68e5544c9..4fe77fd556 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java @@ -7,7 +7,6 @@ import androidx.core.view.GravityCompat; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CataloguesFragment; import com.github.doomsdayrs.apps.shosetsu.ui.main.MainActivity; import com.google.android.material.navigation.NavigationView; @@ -57,7 +56,7 @@ public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { Log.d("Nav", "Catalogue selected"); mainActivity.getSupportFragmentManager().beginTransaction() .addToBackStack("tag") - .replace(R.id.fragment_container, new CataloguesFragment()) + .replace(R.id.fragment_container, mainActivity.cataloguesFragment) .commit(); } break; diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index eabd93a6ac..627b69ca7a 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -9,6 +9,12 @@ tools:context="com.github.doomsdayrs.apps.shosetsu.ui.main.MainActivity" tools:openDrawer="start"> + + + + android:layout_height="?attr/actionBarSize" + app:elevation="4dp" /> From 1b31934804853a1013bd2ec5cd416877566bf097 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 9 Nov 2019 20:17:13 -0500 Subject: [PATCH 051/162] Thinking about this more now tbh --- .../apps/shosetsu/backend/scraper/WebViewScrapper.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index ab16560c7e..002588f3c8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -65,6 +65,12 @@ public void processHTML(String html) { //cf-browser-verification } + + public void loadUrl(String url) { + webView.loadUrl(url); + } + + /** * Put this in an async task, or you will have a bad time. * @@ -73,8 +79,6 @@ public void processHTML(String html) { * @throws InterruptedException This fucked up hard */ public Document docFromURL(String url) { - webView.loadUrl(url); - int count = 0; while (checked && returnedHTML == null) { try { From 65b221a4daa2a5ab98f0145757640c76f82b7062 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 9 Nov 2019 21:38:50 -0500 Subject: [PATCH 052/162] aaaaaaaaaaaaaaaaaaaaa the code hurts me --- .../backend/scraper/WebViewScrapper.java | 110 ++++++++++++++---- .../apps/shosetsu/ui/main/MainActivity.java | 2 +- 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index 002588f3c8..6e79d47d44 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -18,6 +18,9 @@ */ import android.annotation.SuppressLint; +import android.app.Activity; +import android.os.AsyncTask; +import android.util.Log; import android.webkit.JavascriptInterface; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -25,8 +28,10 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import java.util.ArrayList; import java.util.concurrent.TimeUnit; + /** * shosetsu * 09 / 11 / 2019 @@ -35,12 +40,18 @@ */ public class WebViewScrapper { private final WebView webView; - private String returnedHTML = null; - private boolean checked = false; + private static Looper looper; + private Activity activity; + private ArrayList toBeProcessed = new ArrayList<>(); + private ArrayList storedPages = new ArrayList<>(); + private boolean running = false; + private boolean next = false; @SuppressLint("SetJavaScriptEnabled") - public WebViewScrapper(WebView webView) { + public WebViewScrapper(WebView webView, Activity activity) { this.webView = webView; + this.activity = activity; + webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(this, "HTMLOUT"); @@ -48,51 +59,110 @@ public WebViewScrapper(WebView webView) { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); - returnedHTML = null; return false; } public void onPageFinished(WebView view, String url) { - view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');"); - checked = !returnedHTML.contains("cf-browser-verification"); + view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'','" + url + "');"); + StoredPage storedPage = getStoredPage(url); + if (storedPage.html.contains("cf-browser-verification")) { + storedPage.html = null; + } else { + next = true; + } } }); } - @JavascriptInterface - public void processHTML(String html) { - returnedHTML = html; - //cf-browser-verification + public StoredPage getStoredPage(String url) { + for (StoredPage storedPage : storedPages) + if (storedPage.url.equals(url)) + return storedPage; + return null; } + @JavascriptInterface + public void processHTML(String html, String url) { + Log.i("ProcessingHTML", url); + StoredPage storedPage = new StoredPage(url); + storedPage.html = html; + storedPages.add(storedPage); + } public void loadUrl(String url) { - webView.loadUrl(url); + toBeProcessed.add(url); + if (!running) { + looper = new Looper(this); + looper.execute(); + } } - /** * Put this in an async task, or you will have a bad time. * * @param url URL to retrieve; * @return Document of the URL - * @throws InterruptedException This fucked up hard */ public Document docFromURL(String url) { - int count = 0; - while (checked && returnedHTML == null) { + activity.runOnUiThread(() -> loadUrl(url)); + int a = 0; + Log.i("WaitingURL", url); + while (getStoredPage(url) == null) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } - count++; - if (count == 120) { + Log.i("WaitLoop", String.valueOf(a)); + a++; + if (a == 240) { return null; } } - Document document = Jsoup.parse(returnedHTML); - returnedHTML = null; - return document; + return Jsoup.parse(getStoredPage(url).html); + } + + static class StoredPage { + final String url; + String html = null; + + StoredPage(String url) { + this.url = url; + } + } + + static class Looper extends AsyncTask { + final WebViewScrapper webViewScrapper; + + Looper(WebViewScrapper webViewScrapper) { + this.webViewScrapper = webViewScrapper; + } + + @Override + protected void onPreExecute() { + Log.i("Starting", "ScraperLoop"); + webViewScrapper.running = true; + } + + @Override + protected void onPostExecute(Void aVoid) { + Log.i("Finished", "ScraperLoop"); + webViewScrapper.running = false; + } + + @Override + protected Void doInBackground(Void... voids) { + while (webViewScrapper.toBeProcessed.size() > 0) { + String url = webViewScrapper.toBeProcessed.get(0); + Log.i("ProcessingURL", url); + webViewScrapper.activity.runOnUiThread(() -> webViewScrapper.webView.loadUrl(url)); + int a = 0; + while (!webViewScrapper.next) { + a++; + Log.i("NextLoop", String.valueOf(a)); + } + } + return null; + } } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index dba66828df..364a4f5a16 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -176,7 +176,7 @@ public void onFailed(AppUpdaterError error) { toggle.syncState(); webView = findViewById(R.id.absolute_webview); - webViewScrapper = new WebViewScrapper(webView); + webViewScrapper = new WebViewScrapper(webView, this); cataloguesFragment.setWebViewScrapper(webViewScrapper); // Sets up DB From 23da6ed1e520217b2d48d82182968ddd6587e199 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 10 Nov 2019 14:43:17 -0500 Subject: [PATCH 053/162] It worked, then broke. so now i figure out a new way --- .../backend/scraper/WebViewScrapper.java | 144 +++++------------- .../scraper/WebViewScrapperClient.java | 63 ++++++++ .../catalogue/async/CataloguePageLoader.java | 6 +- app/src/main/res/layout/activity_main.xml | 2 +- 4 files changed, 102 insertions(+), 113 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index 6e79d47d44..7adb9d8faa 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -19,17 +19,12 @@ import android.annotation.SuppressLint; import android.app.Activity; -import android.os.AsyncTask; -import android.util.Log; -import android.webkit.JavascriptInterface; import android.webkit.WebView; -import android.webkit.WebViewClient; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import java.util.ArrayList; -import java.util.concurrent.TimeUnit; +import java.io.IOException; /** @@ -39,130 +34,59 @@ * @author github.com/doomsdayrs */ public class WebViewScrapper { + private final WebView webView; - private static Looper looper; private Activity activity; - private ArrayList toBeProcessed = new ArrayList<>(); - private ArrayList storedPages = new ArrayList<>(); - private boolean running = false; - private boolean next = false; + public boolean completed = false; + String html; + private boolean working = false; + + /** + * Constructor + * + * @param webView Webview to use + * @param activity How to handle Scraping + */ @SuppressLint("SetJavaScriptEnabled") public WebViewScrapper(WebView webView, Activity activity) { this.webView = webView; this.activity = activity; - webView.getSettings().setJavaScriptEnabled(true); - webView.addJavascriptInterface(this, "HTMLOUT"); - - webView.setWebViewClient(new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - view.loadUrl(url); - return false; - } - - public void onPageFinished(WebView view, String url) { - view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'','" + url + "');"); - StoredPage storedPage = getStoredPage(url); - if (storedPage.html.contains("cf-browser-verification")) { - storedPage.html = null; - } else { - next = true; - } - } - }); - } - - public StoredPage getStoredPage(String url) { - for (StoredPage storedPage : storedPages) - if (storedPage.url.equals(url)) - return storedPage; - return null; - } - - @JavascriptInterface - public void processHTML(String html, String url) { - Log.i("ProcessingHTML", url); - StoredPage storedPage = new StoredPage(url); - storedPage.html = html; - storedPages.add(storedPage); + // webView.addJavascriptInterface(this, "HTMLOUT"); + webView.setWebViewClient(new WebViewScrapperClient(this)); } - public void loadUrl(String url) { - toBeProcessed.add(url); - if (!running) { - looper = new Looper(this); - looper.execute(); - } - } + // @JavascriptInterface + // public void processHTML(String html) { + // Log.i("ProcessingHTML", "of latestURL"); + // this.html = html; + // } /** - * Put this in an async task, or you will have a bad time. + * Put this in an async task, or you will have a bad time * * @param url URL to retrieve; * @return Document of the URL */ - public Document docFromURL(String url) { - activity.runOnUiThread(() -> loadUrl(url)); - int a = 0; - Log.i("WaitingURL", url); - while (getStoredPage(url) == null) { - try { - TimeUnit.SECONDS.sleep(1); - } catch (InterruptedException e) { - e.printStackTrace(); - } - Log.i("WaitLoop", String.valueOf(a)); - a++; - if (a == 240) { - return null; + public static Document docFromURL(String url, boolean cloudflare) { + + try { + if (!cloudflare) + return Jsoup.connect(url).get(); + else { + //TODO handle cookies + return Jsoup.connect(url).get(); } + } catch (IOException e) { + e.printStackTrace(); } - return Jsoup.parse(getStoredPage(url).html); - } - - static class StoredPage { - final String url; - String html = null; - StoredPage(String url) { - this.url = url; - } + return null; } - static class Looper extends AsyncTask { - final WebViewScrapper webViewScrapper; - - Looper(WebViewScrapper webViewScrapper) { - this.webViewScrapper = webViewScrapper; - } - - @Override - protected void onPreExecute() { - Log.i("Starting", "ScraperLoop"); - webViewScrapper.running = true; - } - - @Override - protected void onPostExecute(Void aVoid) { - Log.i("Finished", "ScraperLoop"); - webViewScrapper.running = false; - } - - @Override - protected Void doInBackground(Void... voids) { - while (webViewScrapper.toBeProcessed.size() > 0) { - String url = webViewScrapper.toBeProcessed.get(0); - Log.i("ProcessingURL", url); - webViewScrapper.activity.runOnUiThread(() -> webViewScrapper.webView.loadUrl(url)); - int a = 0; - while (!webViewScrapper.next) { - a++; - Log.i("NextLoop", String.valueOf(a)); - } - } - return null; - } + private void clear() { + activity.runOnUiThread(() -> webView.loadUrl("about:blank")); } + } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java new file mode 100644 index 0000000000..8b8bbf4fef --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java @@ -0,0 +1,63 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.scraper; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.util.Log; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import java.util.concurrent.TimeUnit; + +/** + * shosetsu + * 10 / 11 / 2019 + * + * @author github.com/doomsdayrs + */ +public class WebViewScrapperClient extends WebViewClient { + private WebViewScrapper webViewScrapper; + + WebViewScrapperClient(WebViewScrapper webViewScrapper) { + this.webViewScrapper = webViewScrapper; + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + view.loadUrl(url); + return false; + } + + public void onPageFinished(WebView view, String url) { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + + view.evaluateJavascript( + "(function() { return (''+document.getElementsByTagName('html')[0].innerHTML+''); })();", + html -> { + Log.d("HTML", html); + webViewScrapper.html = html; + webViewScrapper.completed = true; + }); + // view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');"); + + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index b9b9310520..de1c7f3857 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -14,6 +14,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * @@ -84,9 +86,9 @@ protected Boolean doInBackground(Integer... integers) { } // Loads novel list if (integers.length == 0) - novels = catalogueFragment.formatter.parseLatest(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getLatestURL(1))); + novels = catalogueFragment.formatter.parseLatest(docFromURL(catalogueFragment.formatter.getLatestURL(1), catalogueFragment.formatter.hasCloudFlare())); else { - novels = catalogueFragment.formatter.parseLatest(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getLatestURL(integers[0]))); + novels = catalogueFragment.formatter.parseLatest(docFromURL(catalogueFragment.formatter.getLatestURL(integers[0]), catalogueFragment.formatter.hasCloudFlare())); } for (Novel novel : novels) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 627b69ca7a..0d516c8568 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -13,7 +13,7 @@ android:id="@+id/absolute_webview" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="gone" /> + android:visibility="invisible" /> Date: Sun, 10 Nov 2019 15:10:39 -0500 Subject: [PATCH 054/162] Thinking and working --- app/build.gradle | 10 ++++++---- .../apps/shosetsu/backend/scraper/WebViewScrapper.java | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b03bab52fa..356fb8ea73 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,12 +48,12 @@ repositories { dependencies { implementation 'com.google.android.material:material:1.2.0-alpha01' - implementation 'com.graphql-java:graphql-java:2019-09-07T08-08-53-173312e' + implementation 'com.graphql-java:graphql-java:2019-11-07T04-06-09-70d9412' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible implementation 'com.google.android.material:material:1.2.0-alpha01' - testImplementation 'junit:junit:4.13-beta-3' + testImplementation 'junit:junit:4.13-rc-1' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' @@ -63,7 +63,7 @@ dependencies { implementation 'com.squareup.picasso:picasso:2.71828' - implementation 'org.jetbrains:annotations:17.0.0' + implementation 'org.jetbrains:annotations:18.0.0' //TODO GITHUB sign in to save backup data to cloud //implementation 'com.github.kohsuke:github-api:github-api-1.95' @@ -74,10 +74,12 @@ dependencies { implementation 'com.mittsu:markedview:1.0.7' - implementation 'joda-time:joda-time:2.10.3' + implementation 'joda-time:joda-time:2.10.5' implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8' + implementation 'org.mozilla:rhino:1.7.10' + // TODO Implement readerview provided by Mozilla //implementation "org.mozilla.components:feature-readerview:1.0.0" //implementation 'org.mozilla.components:support-base:1.0.0' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index 7adb9d8faa..2e22afb669 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -69,13 +69,15 @@ public WebViewScrapper(WebView webView, Activity activity) { * @param url URL to retrieve; * @return Document of the URL */ - public static Document docFromURL(String url, boolean cloudflare) { + public Document docFromURL(String url, boolean cloudflare) { try { if (!cloudflare) return Jsoup.connect(url).get(); else { - //TODO handle cookies + // Cloudflare cf = new Cloudflare(url); + // cf.setUser_agent(webView.getSettings().getUserAgentString()); + return Jsoup.connect(url).get(); } } catch (IOException e) { From 5b319cc559cc673cf0bb8316099c6971dcc24a96 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Tue, 12 Nov 2019 23:02:01 -0500 Subject: [PATCH 055/162] Completed cloudflare bypass, not to simplify internal coding --- .../shosetsu/backend/Download_Manager.java | 9 +- .../apps/shosetsu/backend/Serialize.java | 2 +- .../apps/shosetsu/backend/Utilities.java | 5 +- .../backend/WebviewCookieHandler.java | 2 +- .../shosetsu/backend/database/Database.java | 27 +- .../backend/database/objects/Update.java | 4 +- .../backend/database/objects/base/Base.java | 2 +- .../database/objects/base/BaseChapter.java | 2 +- .../backend/scraper/WebViewScrapper.java | 85 +++-- .../scraper/WebViewScrapperClient.java | 4 +- .../scraper/aria2/CloudFlareCallback.java | 11 + .../backend/scraper/aria2/Cloudflare.java | 359 ++++++++++++++++++ .../ui/catalogue/CatalogueFragment.java | 9 +- .../ui/catalogue/CataloguesFragment.java | 7 +- .../catalogue/adapters/CatalogueAdapter.java | 2 +- .../catalogue/adapters/CataloguesAdapter.java | 7 +- .../catalogue/async/CataloguePageLoader.java | 1 + .../catalogue/async/CatalogueQuerySearch.java | 6 +- .../catalogue/async/NovelBackgroundAdd.java | 6 +- .../listeners/CatalogueSearchQuery.java | 4 +- .../catalogue/viewHolder/CatalogueHolder.java | 10 +- .../ui/downloads/DownloadsFragment.java | 1 + .../viewHolders/LibraryViewHolder.java | 2 +- .../apps/shosetsu/ui/main/MainActivity.java | 9 +- .../shosetsu/ui/migration/MigrationView.java | 13 +- .../adapters/MigratingMapAdapter.java | 2 +- .../MigrationViewCatalogueAdapter.java | 2 +- .../ui/migration/async/MigrationViewLoad.java | 15 +- .../shosetsu/ui/migration/async/Transfer.java | 72 ++-- .../apps/shosetsu/ui/novel/NovelFragment.java | 7 +- .../ui/novel/async/ChapterLoader.java | 63 ++- .../shosetsu/ui/novel/async/NovelLoader.java | 35 +- .../novel/listeners/NovelFragmentUpdate.java | 2 +- .../ui/novel/pages/NovelFragmentChapters.java | 4 +- .../shosetsu/ui/reader/ChapterReader.java | 43 +-- .../ui/reader/async/ReaderViewLoader.java | 4 +- .../listener/OnSettingsCardClick.java | 4 +- .../settings/subFragments/ViewSettings.java | 3 +- .../backup/async/BackupProcess.java | 1 + .../backup/async/RestoreProcess.java | 9 +- .../viewHolder/SettingsCardViewHolder.java | 6 +- .../shosetsu/ui/updates/UpdateFragment.java | 2 +- .../shosetsu/ui/updates/UpdatesFragment.java | 1 + .../adapters/UpdatedChaptersAdapter.java | 6 +- .../adapters/UpdatedNovelsAdapter.java | 4 +- .../ui/updates/async/ChapterUpdater.java | 60 ++- .../viewHolder/UpdatedChapterHolder.java | 6 +- .../viewHolder/UpdatedNovelHolder.java | 2 +- .../apps/shosetsu/ui/webView/Actions.java | 2 +- .../apps/shosetsu/ui/webView/JSInterface.java | 4 +- .../apps/shosetsu/ui/webView/WebViewApp.java | 4 +- .../shosetsu/variables/DefaultScrapers.java | 2 +- .../apps/shosetsu/variables/DownloadItem.java | 4 +- .../variables/recycleObjects/RecycleCard.java | 2 - .../recycleObjects/SettingsItem.java | 6 +- .../apps/shosetsu/ExampleUnitTest.java | 2 +- 56 files changed, 679 insertions(+), 289 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index a0d58f6501..ede3976c79 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -21,6 +21,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.cleanString; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* * This file is part of Shosetsu. @@ -87,8 +88,10 @@ public static boolean delete(Context context, DownloadItem downloadItem) { Database.DatabaseChapter.removePath(downloadItem.chapterID); if (file.exists()) if (!file.delete()) - if (context != null) + if (context != null) { Toast.makeText(context, "Failed to delete, next download will correct", Toast.LENGTH_LONG).show(); + return false; + } return true; } @@ -122,6 +125,7 @@ public static String getText(String path) { * TODO Skip over paused chapters or move them to the bottom of the list */ static class Downloading extends AsyncTask { + @Override protected Void doInBackground(Void... voids) { while (Database.DatabaseDownloads.getDownloadCount() >= 1 && !Settings.downloadPaused) { @@ -140,8 +144,7 @@ protected Void doInBackground(Void... voids) { throw new IOException("Failed to mkdirs"); } String formattedName = cleanString(downloadItem.chapterName); - - String passage = downloadItem.formatter.getNovelPassage(downloadItem.chapterURL); + String passage = downloadItem.formatter.getNovelPassage(docFromURL(downloadItem.chapterURL, downloadItem.formatter.hasCloudFlare())); FileOutputStream fileOutputStream = new FileOutputStream( (folder.getPath() + "/" + (formattedName) + ".txt") ); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index 6df26cd2bd..58702a8e43 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -235,7 +235,7 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception * @return NovelChapter * @throws Exception If something goes wrong */ - public static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { + private static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { NovelChapter novelChapter = new NovelChapter(); JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); for (String key : NOVELCHAPTERKEYS) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index c8145da434..6f0a5bea7c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -134,8 +134,7 @@ public static Object deserializeString(@NotNull String string) throws IOExceptio byte[] bytes = Base64.decode(string, Base64.NO_WRAP); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); - Object object = objectInputStream.readObject(); - return object; + return objectInputStream.readObject(); } return null; } @@ -431,7 +430,7 @@ public static void openChapter(Activity activity, NovelChapter novelChapter, int openChapter(activity, novelChapter, novelID, formatterID, null); } - public static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { + private static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); Intent intent = new Intent(activity, ChapterReader.class); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java index c86a6f81e2..cfe72bb713 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java @@ -35,7 +35,7 @@ * Provides a synchronization point between the webview cookie store and okhttp3.OkHttpClient cookie store */ public final class WebviewCookieHandler implements CookieJar { - private CookieManager webviewCookieManager = CookieManager.getInstance(); + private final CookieManager webviewCookieManager = CookieManager.getInstance(); @Override public void saveFromResponse(HttpUrl url, List cookies) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 8836eda965..c297b1393c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -143,7 +143,7 @@ public String toString() { public static class DatabaseIdentification { - public static boolean hasChapter(String chapterURL) { + static boolean hasChapter(String chapterURL) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ID + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.URL + " = '" + chapterURL + "'", null); int a = cursor.getCount(); cursor.close(); @@ -256,7 +256,7 @@ public static int getNovelIDFromChapterID(int id) { * @param id Chapter ID * @return Chapter URL */ - public static String getNovelURLFromChapterID(int id) { + static String getNovelURLFromChapterID(int id) { return getNovelURLfromNovelID(getNovelIDFromChapterID(id)); } @@ -292,7 +292,7 @@ public static String getNovelURLfromNovelID(int id) { * @param id Novel ID * @return Formatter ID */ - public static int getFormatterIDFromNovelID(int id) { + static int getFormatterIDFromNovelID(int id) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.FORMATTER_ID + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); if (cursor.getCount() <= 0) { cursor.close(); @@ -330,7 +330,7 @@ public static int getFormatterIDFromNovelURL(String url) { * @param id Chapter ID * @return Formatter ID */ - public static int getFormatterIDFromChapterID(int id) { + static int getFormatterIDFromChapterID(int id) { return getFormatterIDFromNovelID(getNovelIDFromChapterID(id)); } } @@ -381,10 +381,9 @@ public static DownloadItem getFirstDownload() { * Removes download item * * @param downloadItem download item to remove - * @return if removed */ - public static boolean removeDownload(DownloadItem downloadItem) { - return sqLiteDatabase.delete(Tables.DOWNLOADS.toString(), Columns.PARENT_ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null) > 0; + public static void removeDownload(DownloadItem downloadItem) { + sqLiteDatabase.delete(Tables.DOWNLOADS.toString(), Columns.PARENT_ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null); } /** @@ -430,6 +429,7 @@ public static int getDownloadCount() { public static class DatabaseChapter { + /* // TODO This will remove all chapter data public static void purgeCache() { @@ -438,6 +438,7 @@ public static void purgeCache() { //TODO purge not needed cache public static void purgeUneededCache() { } +*/ /** * @param novelID ID of novel @@ -566,7 +567,7 @@ public static void removePath(int chapterID) { * @param chapterID chapter to update * @param chapterPath save path to set */ - public static void addSavedPath(int chapterID, String chapterPath) { + static void addSavedPath(int chapterID, String chapterPath) { sqLiteDatabase.execSQL("update " + Tables.CHAPTERS + " set " + Columns.SAVE_PATH + "='" + chapterPath + "'," + Columns.IS_SAVED + "=1 where " + Columns.ID + "=" + chapterID); } @@ -699,13 +700,7 @@ public static List getChapters(int novelID) { } } cursor.close(); - Collections.sort(novelChapters, (novelChapter, t1) -> { - if (novelChapter.order < t1.order) - return -1; - else if (novelChapter.order > t1.order) - return 1; - else return 0; - }); + Collections.sort(novelChapters, (novelChapter, t1) -> Double.compare(novelChapter.order, t1.order)); return novelChapters; } } @@ -1068,7 +1063,7 @@ public static long getStartingDay() { } } - public static long getLatestDay() { + static long getLatestDay() { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.TIME + " FROM " + Tables.UPDATES + " ORDER BY ROWID DESC LIMIT 1", null); if (cursor.getCount() <= 0) { cursor.close(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java index edb28f19b9..d42892d45b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/Update.java @@ -24,9 +24,9 @@ * @author github.com/doomsdayrs */ public class Update extends BaseChapter { - public final long time; + private final long time; public final int chapterID; - public final int novelID; + private final int novelID; public Update(String novel_url, String chapter_url, long time, int chapterID, int novelID) { super(novel_url, chapter_url); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java index 693517811c..be5049dd56 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java @@ -25,7 +25,7 @@ */public class Base implements Serializable { public final String NOVEL_URL; - public Base(String novel_url) { + Base(String novel_url) { NOVEL_URL = novel_url; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java index 063b12fa39..53ba8b64bf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java @@ -23,7 +23,7 @@ */public class BaseChapter extends Base { public final String CHAPTER_URL; - public BaseChapter(String novel_url, String chapter_url) { + protected BaseChapter(String novel_url, String chapter_url) { super(novel_url); CHAPTER_URL = chapter_url; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index 2e22afb669..aa9f31dd39 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -17,14 +17,19 @@ * ==================================================================== */ -import android.annotation.SuppressLint; -import android.app.Activity; -import android.webkit.WebView; +import android.os.AsyncTask; +import android.util.Log; + +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.CloudFlareCallback; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.Cloudflare; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.IOException; +import java.net.HttpCookie; +import java.util.List; +import java.util.concurrent.ExecutionException; /** @@ -35,19 +40,28 @@ */ public class WebViewScrapper { - private final WebView webView; - private Activity activity; - public boolean completed = false; + private static String ua; String html; - private boolean working = false; + // private final WebView webView; + //private Activity activity; + public boolean completed = false; + private WebViewScrapper() { + } - /** + public static void setUa(String ua) { + WebViewScrapper.ua = ua; + } + //private boolean working = false; + + /* * Constructor * * @param webView Webview to use * @param activity How to handle Scraping */ + /* + @SuppressLint("SetJavaScriptEnabled") public WebViewScrapper(WebView webView, Activity activity) { this.webView = webView; @@ -62,6 +76,7 @@ public WebViewScrapper(WebView webView, Activity activity) { // Log.i("ProcessingHTML", "of latestURL"); // this.html = html; // } +*/ /** * Put this in an async task, or you will have a bad time @@ -69,26 +84,52 @@ public WebViewScrapper(WebView webView, Activity activity) { * @param url URL to retrieve; * @return Document of the URL */ - public Document docFromURL(String url, boolean cloudflare) { - - try { - if (!cloudflare) - return Jsoup.connect(url).get(); - else { - // Cloudflare cf = new Cloudflare(url); - // cf.setUser_agent(webView.getSettings().getUserAgentString()); - - return Jsoup.connect(url).get(); + public static Document docFromURL(String url, boolean cloudflare) { + if (url != null) { + Log.i("URL load", url); + try { + if (cloudflare) { + Cloudflare cf = new Cloudflare(url); + cf.setUser_agent(ua); + return Jsoup.connect(url).cookies(Cloudflare.List2Map(new GetCookies().execute(cf).get())).get(); + } else { + return Jsoup.connect(url).get(); + } + } catch (IOException | InterruptedException | ExecutionException e) { + e.printStackTrace(); } - } catch (IOException e) { - e.printStackTrace(); } - return null; } + static class GetCookies extends AsyncTask> { + List cookies = null; + int status = 0; + + @Override + protected List doInBackground(Cloudflare... cf) { + cf[0].getCookies(new CloudFlareCallback() { + @Override + public void onSuccess(List cookieList) { + cookies = cookieList; + status = 1; + } + + @Override + public void onFail() { + status = -1; + } + }); + int a = 0; + while (status == 0) { + a++; + } + return cookies; + } + } +/* private void clear() { activity.runOnUiThread(() -> webView.loadUrl("about:blank")); } - +*/ } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java index 8b8bbf4fef..163e423f2b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java @@ -29,8 +29,8 @@ * * @author github.com/doomsdayrs */ -public class WebViewScrapperClient extends WebViewClient { - private WebViewScrapper webViewScrapper; +class WebViewScrapperClient extends WebViewClient { + private final WebViewScrapper webViewScrapper; WebViewScrapperClient(WebViewScrapper webViewScrapper) { this.webViewScrapper = webViewScrapper; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java new file mode 100644 index 0000000000..85b907cd47 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java @@ -0,0 +1,11 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2; + +import java.net.HttpCookie; +import java.util.List; + + +public interface CloudFlareCallback { + void onSuccess(List cookieList); + + void onFail(); +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java new file mode 100644 index 0000000000..d1028a5b69 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java @@ -0,0 +1,359 @@ +package com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2; + +import android.net.Uri; +import android.os.Looper; +import android.text.TextUtils; +import android.util.Log; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.HttpCookie; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * author: zhkrb @ https://github.com/zhkrb + */ +public class Cloudflare { + + private static final int MAX_COUNT = 3; + private static final int CONN_TIMEOUT = 60000; + private static final String ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;"; + private final String mUrl; + private String mUser_agent; + private CloudFlareCallback mCallback; + private int mRetry_count; + private URL ConnUrl; + private List mCookieList; + private CookieManager mCookieManager; + private HttpURLConnection mCheckConn; + private HttpURLConnection mGetMainConn; + private HttpURLConnection mGetRedirectionConn; + private boolean canVisit = false; + + public Cloudflare(String url) { + mUrl = url; + } + + public Cloudflare(String url, String user_agent) { + mUrl = url; + mUser_agent = user_agent; + } + + /** + * 转换list为 ; 符号链接的字符串 + * + * @param list + * @return + */ + private static String listToString(List list) { + char separator = ";".charAt(0); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + sb.append(list.get(i)).append(separator); + } + return sb.toString().substring(0, sb.toString().length() - 1); + } + + /** + * 转换为jsoup可用的Hashmap + * + * @param list HttpCookie列表 + * @return Hashmap + */ + public static Map List2Map(List list) { + Map map = new HashMap<>(); + try { + if (list != null) { + for (int i = 0; i < list.size(); i++) { + String[] listStr = list.get(i).toString().split("="); + map.put(listStr[0], listStr[1]); + } + Log.i("List2Map", map.toString()); + } else { + return map; + } + + } catch (IndexOutOfBoundsException e) { + e.printStackTrace(); + } + + return map; + } + + public String getUser_agent() { + return mUser_agent; + } + + public void setUser_agent(String user_agent) { + mUser_agent = user_agent; + } + + public void getCookies(final CloudFlareCallback callback) { + new Thread(() -> urlThread(callback)).start(); + } + + private void urlThread(CloudFlareCallback callback) { + mCookieManager = new CookieManager(); + mCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); //接受所有cookies + CookieHandler.setDefault(mCookieManager); + HttpURLConnection.setFollowRedirects(false); + + while (!canVisit) { + if (mRetry_count > MAX_COUNT) { + break; + } + try { + + int responseCode = checkUrl(); + if (responseCode == 200) { + canVisit = true; + break; + } else { + getVisiteCookie(); + } + } catch (IOException | InterruptedException e) { + if (mCookieList != null) { + mCookieList.clear(); + } + e.printStackTrace(); + } finally { + closeAllConn(); + } + mRetry_count++; + } + if (callback != null) { + Looper.prepare(); + if (canVisit) { + callback.onSuccess(mCookieList); + } else { + e("Get Cookie Failed"); + callback.onFail(); + } + + + } + } + + private void getVisiteCookie() throws IOException, InterruptedException { + ConnUrl = new URL(mUrl); + mGetMainConn = (HttpURLConnection) ConnUrl.openConnection(); + mGetMainConn.setRequestMethod("GET"); + mGetMainConn.setConnectTimeout(CONN_TIMEOUT); + mGetMainConn.setReadTimeout(CONN_TIMEOUT); + if (!TextUtils.isEmpty(mUser_agent)) { + mGetMainConn.setRequestProperty("user-agent", mUser_agent); + } + mGetMainConn.setRequestProperty("accept", ACCEPT); + mGetMainConn.setRequestProperty("referer", mUrl); + if (mCookieList != null && mCookieList.size() > 0) { + mGetMainConn.setRequestProperty("cookie", listToString(mCookieList)); + } + mGetMainConn.setUseCaches(false); + mGetMainConn.connect(); + switch (mGetMainConn.getResponseCode()) { + case HttpURLConnection.HTTP_OK: + e("MainUrl", "visit website success"); + return; + case HttpURLConnection.HTTP_FORBIDDEN: + e("MainUrl", "IP block or cookie err"); + return; + case HttpURLConnection.HTTP_UNAVAILABLE: + InputStream mInputStream = mCheckConn.getErrorStream(); + BufferedReader mBufferedReader = new BufferedReader(new InputStreamReader(mInputStream)); + StringBuilder sb = new StringBuilder(); + String str; + while ((str = mBufferedReader.readLine()) != null) { + sb.append(str); + } + mInputStream.close(); + mBufferedReader.close(); + mCookieList = mCookieManager.getCookieStore().getCookies(); + str = sb.toString(); + getCheckAnswer(str); + break; + default: + + break; + } + } + + /** + * 获取值并跳转获得cookies + * + * @param str + */ + private void getCheckAnswer(String str) throws InterruptedException, IOException { + String s = regex(str, "name=\"s\" value=\"(.+?)\"").get(0); //正则取值 + String jschl_vc = regex(str, "name=\"jschl_vc\" value=\"(.+?)\"").get(0); + String pass = regex(str, "name=\"pass\" value=\"(.+?)\"").get(0); // + double jschl_answer = get_answer(str); + e(String.valueOf(jschl_answer)); + Thread.sleep(3000); + String req = "https://" + ConnUrl.getHost() + "/cdn-cgi/l/chk_jschl?"; + if (!TextUtils.isEmpty(s)) { + s = Uri.encode(s); + req += "s=" + s + "&"; + } + req += "jschl_vc=" + Uri.encode(jschl_vc) + "&pass=" + Uri.encode(pass) + "&jschl_answer=" + jschl_answer; + e("RedirectUrl", req); + getRedirectResponse(req); + } + + private void getRedirectResponse(String req) throws IOException { + HttpURLConnection.setFollowRedirects(false); + mGetRedirectionConn = (HttpURLConnection) new URL(req).openConnection(); + mGetRedirectionConn.setRequestMethod("GET"); + mGetRedirectionConn.setConnectTimeout(CONN_TIMEOUT); + mGetRedirectionConn.setReadTimeout(CONN_TIMEOUT); + if (!TextUtils.isEmpty(mUser_agent)) { + mGetRedirectionConn.setRequestProperty("user-agent", mUser_agent); + } + mGetRedirectionConn.setRequestProperty("accept", ACCEPT); + mGetRedirectionConn.setRequestProperty("referer", req); + if (mCookieList != null && mCookieList.size() > 0) { + mGetRedirectionConn.setRequestProperty("cookie", listToString(mCookieList)); + } + mGetRedirectionConn.setUseCaches(false); + mGetRedirectionConn.connect(); + switch (mGetRedirectionConn.getResponseCode()) { + case HttpURLConnection.HTTP_OK: + case HttpURLConnection.HTTP_MOVED_TEMP: + mCookieList = mCookieManager.getCookieStore().getCookies(); + break; + default: + throw new IOException("getOtherResponse Code: " + + mGetRedirectionConn.getResponseCode()); + } + } + + private int checkUrl() throws IOException { + URL ConnUrl = new URL(mUrl); + mCheckConn = (HttpURLConnection) ConnUrl.openConnection(); + mCheckConn.setRequestMethod("GET"); + mCheckConn.setConnectTimeout(CONN_TIMEOUT); + mCheckConn.setReadTimeout(CONN_TIMEOUT); + if (!TextUtils.isEmpty(mUser_agent)) { + mCheckConn.setRequestProperty("user-agent", mUser_agent); + } + mCheckConn.setRequestProperty("accept", ACCEPT); + mCheckConn.setRequestProperty("referer", mUrl); + if (mCookieList != null && mCookieList.size() > 0) { + mCheckConn.setRequestProperty("cookie", listToString(mCookieList)); + } + mCheckConn.setUseCaches(false); + mCheckConn.connect(); + return mCheckConn.getResponseCode(); + } + + private void closeAllConn() { + if (mCheckConn != null) { + mCheckConn.disconnect(); + } + if (mGetMainConn != null) { + mGetMainConn.disconnect(); + } + if (mGetRedirectionConn != null) { + mGetRedirectionConn.disconnect(); + } + } + + private double get_answer(String str) { //取值 + double a = 0; + + try { + List s = regex(str, "var s,t,o,p,b,r,e,a,k,i,n,g,f, " + + "(.+?)=\\{\"(.+?)\""); + String varA = s.get(0); + String varB = s.get(1); + StringBuilder sb = new StringBuilder(); + sb.append("var t=\"").append(new URL(mUrl).getHost()).append("\";"); + sb.append("var a="); + sb.append(regex(str, varA + "=\\{\"" + varB + "\":(.+?)\\}").get(0)); + sb.append(";"); + List b = regex(str, varA + "\\." + varB + "(.+?)\\;"); + for (int i = 0; i < b.size() - 1; i++) { + sb.append("a"); + sb.append(b.get(i)); + sb.append(";"); + } + + e("add", sb.toString()); + Context rhino = Context.enter(); + rhino.setOptimizationLevel(-1); + try { + Scriptable scope = rhino.initStandardObjects(); + a = Double.parseDouble(rhino.evaluateString(scope, sb.toString(), "JavaScript", 1, null).toString()); + List fixNum = regex(str, "toFixed\\((.+?)\\)"); + if (fixNum != null) { + String script = "String(" + a + ".toFixed(" + fixNum.get(0) + "));"; + a = Double.parseDouble(rhino.evaluateString(scope, script, "JavaScript", 1, null).toString()); + } + if (b.get(b.size() - 1).contains("t.length")) { + a += new URL(mUrl).getHost().length(); + } + } finally { + Context.exit(); + } + } catch (IndexOutOfBoundsException e) { + e("answerErr", "get answer error"); + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return a; + } + + /** + * 正则 + * + * @param text 本体 + * @param pattern 正则式 + * @return List + */ + private List regex(String text, String pattern) { + try { + Pattern pt = Pattern.compile(pattern); + Matcher mt = pt.matcher(text); + List group = new ArrayList<>(); + + while (mt.find()) { + if (mt.groupCount() >= 1) { + if (mt.groupCount() > 1) { + group.add(mt.group(1)); + group.add(mt.group(2)); + } else group.add(mt.group(1)); + } + } + return group; + } catch (NullPointerException e) { + Log.i("MATCH", "null"); + } + return null; + } + + private void e(String tag, String content) { + Log.e(tag, content); + } + + private void e(String content) { + Log.e("cloudflare", content); + } + +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java index 2d85596a15..a09cb33aaa 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java @@ -25,7 +25,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.WebviewCookieHandler; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.adapters.CatalogueAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.async.CataloguePageLoader; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.listeners.CatalogueHitBottom; @@ -66,7 +65,6 @@ */ //TODO fix issue with not loading public class CatalogueFragment extends Fragment { - public WebViewScrapper webViewScrapper; public ArrayList catalogueNovelCards = new ArrayList<>(); public Formatter formatter; public SwipeRefreshLayout swipeRefreshLayout; @@ -82,8 +80,8 @@ public class CatalogueFragment extends Fragment { public boolean isQuery = false; public ConstraintLayout errorView; - public TextView errorMessage; - public Button errorButton; + private TextView errorMessage; + private Button errorButton; public TextView empty; /** @@ -93,9 +91,6 @@ public CatalogueFragment() { setHasOptionsMenu(true); } - public void setWebViewScrapper(WebViewScrapper webViewScrapper) { - this.webViewScrapper = webViewScrapper; - } public void setFormatter(Formatter formatter) { this.formatter = formatter; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java index f988c2c982..5350864dd3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java @@ -16,7 +16,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.adapters.CataloguesAdapter; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; @@ -50,7 +49,6 @@ */ //TODO Searching mechanics here public class CataloguesFragment extends Fragment { - private WebViewScrapper webViewScrapper; private ArrayList cards = null; /** @@ -92,14 +90,11 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (recyclerView != null) { recyclerView.setHasFixedSize(true); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(Objects.requireNonNull(container).getContext()); - RecyclerView.Adapter adapter = new CataloguesAdapter(cards, fragmentManager, webViewScrapper); + RecyclerView.Adapter adapter = new CataloguesAdapter(cards, fragmentManager); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); } return view; } - public void setWebViewScrapper(WebViewScrapper webViewScrapper) { - this.webViewScrapper = webViewScrapper; - } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java index d2d1d530e1..9f205986d9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CatalogueAdapter.java @@ -43,7 +43,7 @@ * @author github.com/doomsdayrs */ public class CatalogueAdapter extends RecyclerView.Adapter { - private List recycleCards; + private final List recycleCards; private final CatalogueFragment catalogueFragment; private final Formatter formatter; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java index e1b3a5ae53..9d757b17c1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/adapters/CataloguesAdapter.java @@ -9,7 +9,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.viewHolder.CatalogueHolder; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueCard; import com.squareup.picasso.Picasso; @@ -38,14 +37,12 @@ * @author github.com/doomsdayrs */ public class CataloguesAdapter extends RecyclerView.Adapter { - private final WebViewScrapper webViewScrapper; private final ArrayList catalogues; private final FragmentManager fragmentManager; - public CataloguesAdapter(ArrayList catalogues, FragmentManager fragmentManager, WebViewScrapper webViewScrapper) { + public CataloguesAdapter(ArrayList catalogues, FragmentManager fragmentManager) { this.catalogues = catalogues; this.fragmentManager = fragmentManager; - this.webViewScrapper = webViewScrapper; } @@ -53,7 +50,7 @@ public CataloguesAdapter(ArrayList catalogues, FragmentManager fr @Override public CatalogueHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.catalogue_item_card, viewGroup, false); - return new CatalogueHolder(view, fragmentManager, webViewScrapper); + return new CatalogueHolder(view, fragmentManager); } @Override diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index de1c7f3857..c3f64b828b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -16,6 +16,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java index e154594233..ad9e90cf8e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java @@ -10,6 +10,8 @@ import java.util.ArrayList; import java.util.List; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * @@ -32,7 +34,7 @@ * @author github.com/doomsdayrs */ public class CatalogueQuerySearch extends AsyncTask> { - private CatalogueFragment catalogueFragment; + private final CatalogueFragment catalogueFragment; public CatalogueQuerySearch(CatalogueFragment catalogueFragment) { this.catalogueFragment = catalogueFragment; @@ -47,7 +49,7 @@ public CatalogueQuerySearch(CatalogueFragment catalogueFragment) { @Override protected ArrayList doInBackground(String... strings) { ArrayList result = new ArrayList<>(); - List novels = catalogueFragment.formatter.parseSearch(catalogueFragment.webViewScrapper.docFromURL(catalogueFragment.formatter.getSearchString(strings[0]))); + List novels = catalogueFragment.formatter.parseSearch(docFromURL(catalogueFragment.formatter.getSearchString(strings[0]), catalogueFragment.formatter.hasCloudFlare())); for (Novel novel : novels) result.add(new CatalogueNovelCard(novel.imageURL, novel.title, Database.DatabaseIdentification.getNovelIDFromNovelURL(novel.link), novel.link)); return result; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index a9089db5ae..05e2f529cf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -8,6 +8,8 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.viewHolder.NovelCardViewHolder; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * @@ -30,7 +32,7 @@ * @author github.com/doomsdayrs */ public class NovelBackgroundAdd extends AsyncTask { - private NovelCardViewHolder novelCardsViewHolder; + private final NovelCardViewHolder novelCardsViewHolder; public NovelBackgroundAdd(NovelCardViewHolder novelCardsViewHolder) { this.novelCardsViewHolder = novelCardsViewHolder; @@ -40,7 +42,7 @@ public NovelBackgroundAdd(NovelCardViewHolder novelCardsViewHolder) { protected Void doInBackground(View... views) { try { if (!Database.DatabaseNovels.inDatabase(novelCardsViewHolder.url)) { - Database.DatabaseNovels.addToLibrary(novelCardsViewHolder.formatter.getID(), novelCardsViewHolder.formatter.parseNovel(novelCardsViewHolder.url), novelCardsViewHolder.url, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); + Database.DatabaseNovels.addToLibrary(novelCardsViewHolder.formatter.getID(), novelCardsViewHolder.formatter.parseNovel(docFromURL(novelCardsViewHolder.url, novelCardsViewHolder.formatter.hasCloudFlare())), novelCardsViewHolder.url, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); if (views[0] != null) views[0].post(() -> Toast.makeText(views[0].getContext(), "Added " + novelCardsViewHolder.library_card_title.getText().toString(), Toast.LENGTH_SHORT).show()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java index 6a9b2c7032..63de35e18e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java @@ -47,9 +47,7 @@ public boolean onQueryTextSubmit(String query) { ArrayList searchResults = new CatalogueQuerySearch(catalogueFragment).execute(query).get(); catalogueFragment.setLibraryCards(searchResults); return true; - } catch (ExecutionException e) { - e.printStackTrace(); - } catch (InterruptedException e) { + } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); } return false; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java index f99a5c909e..5440425be8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java @@ -29,7 +29,6 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isOnline; @@ -41,18 +40,16 @@ * @author github.com/doomsdayrs */ public class CatalogueHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - WebViewScrapper webViewScrapper; public final ImageView library_card_image; public final TextView library_card_title; - final FragmentManager fragmentManager; - Formatter formatter; + private final FragmentManager fragmentManager; + private Formatter formatter; - public CatalogueHolder(@NonNull View itemView, FragmentManager fragmentManager, WebViewScrapper webViewScrapper) { + public CatalogueHolder(@NonNull View itemView, FragmentManager fragmentManager) { super(itemView); library_card_image = itemView.findViewById(R.id.catalogue_item_card_image); library_card_title = itemView.findViewById(R.id.catalogue_item_card_text); this.fragmentManager = fragmentManager; - this.webViewScrapper = webViewScrapper; } public void setFormatter(Formatter formatter) { @@ -67,7 +64,6 @@ public void onClick(View v) { if (isOnline()) { CatalogueFragment catalogueFragment = new CatalogueFragment(); catalogueFragment.setFormatter(formatter); - catalogueFragment.setWebViewScrapper(webViewScrapper); setFormatter(formatter); fragmentManager.beginTransaction() .addToBackStack("tag") diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java index ad87e4c1db..b2bae93ec6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java @@ -56,6 +56,7 @@ public class DownloadsFragment extends Fragment { public static List downloadItems = new ArrayList<>(); + @SuppressLint("StaticFieldLeak") private static RecyclerView recyclerView; private static DownloadAdapter adapter; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index 19180eecce..69d15b8134 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -37,7 +37,7 @@ import com.google.android.material.chip.Chip; public class LibraryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { - public MaterialCardView materialCardView; + public final MaterialCardView materialCardView; public final ImageView library_card_image; public final TextView library_card_title; public final Chip chip; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index 364a4f5a16..d30df01bc4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -65,10 +65,8 @@ public class MainActivity extends AppCompatActivity { public DrawerLayout drawerLayout; public NavigationView navigationView; public final CataloguesFragment cataloguesFragment = new CataloguesFragment(); - private WebView webView; public final LibraryFragment libraryFragment = new LibraryFragment(); - private WebViewScrapper webViewScrapper; public final UpdatesFragment updatesFragment = new UpdatesFragment(); public final SettingsFragment settingsFragment = new SettingsFragment(); public final DownloadsFragment downloadsFragment = new DownloadsFragment(); @@ -175,10 +173,8 @@ public void onFailed(AppUpdaterError error) { drawerLayout.addDrawerListener(toggle); toggle.syncState(); - webView = findViewById(R.id.absolute_webview); - webViewScrapper = new WebViewScrapper(webView, this); - cataloguesFragment.setWebViewScrapper(webViewScrapper); - + WebView webView = findViewById(R.id.absolute_webview); + WebViewScrapper.setUa(webView.getSettings().getUserAgentString()); // Sets up DB DBHelper helper = new DBHelper(this); Database.sqLiteDatabase = helper.getWritableDatabase(); @@ -186,6 +182,7 @@ public void onFailed(AppUpdaterError error) { Download_Manager.init(); //Prevent the frag from changing on rotation + if (savedInstanceState == null) { getSupportFragmentManager() .beginTransaction() diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java index c316a3a129..db987a4021 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java @@ -53,15 +53,13 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.deserializeString; public class MigrationView extends AppCompatActivity { - Transfer t; - + public final ArrayList> novelResults = new ArrayList<>(); private ArrayList catalogues = null; public ArrayList novels = new ArrayList<>(); - public ArrayList> novelResults = new ArrayList<>(); - - private ArrayList confirmedMappings = new ArrayList<>(); + private final ArrayList confirmedMappings = new ArrayList<>(); + private Transfer t; public int target = -1; public int selection = 0; @@ -73,9 +71,8 @@ public class MigrationView extends AppCompatActivity { public ConstraintLayout targetSelection; public ConstraintLayout migration; - - public RecyclerView selectedNovels; - public RecyclerView.Adapter selectedNovelsAdapters; + private RecyclerView selectedNovels; + private RecyclerView.Adapter selectedNovelsAdapters; public SwipeRefreshLayout swipeRefreshLayout; public RecyclerView mappingNovels; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java index 7e7727c476..ec9f34f653 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigratingMapAdapter.java @@ -38,7 +38,7 @@ * @author github.com/doomsdayrs */ public class MigratingMapAdapter extends RecyclerView.Adapter { - private MigrationView migrationView; + private final MigrationView migrationView; public MigratingMapAdapter(MigrationView migrationView) { this.migrationView = migrationView; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java index e20d927337..b61cb7ef9a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java @@ -94,7 +94,7 @@ static class CatalogueHolder extends RecyclerView.ViewHolder implements View.OnC this.migrationView = migrationView; } - public void setFormatter(Formatter formatter) { + void setFormatter(Formatter formatter) { this.formatter = formatter; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java index 6432921ecb..1550ee01e5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java @@ -9,9 +9,10 @@ import com.github.doomsdayrs.apps.shosetsu.ui.migration.MigrationView; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import java.io.IOException; import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * @@ -48,16 +49,12 @@ public MigrationViewLoad(MigrationView migrationView) { protected Void doInBackground(Void... voids) { Log.d("Searching with", targetFormat.getName()); for (int x = 0; x < migrationView.novels.size(); x++) { - try { - // Retrieves search results - ArrayList N = (ArrayList) targetFormat.search(migrationView.novels.get(x).title); + // Retrieves search results + ArrayList N = (ArrayList) targetFormat.parseSearch(docFromURL(targetFormat.getSearchString(migrationView.novels.get(x).title), targetFormat.hasCloudFlare())); - // Sets the results - migrationView.novelResults.set(x, N); + // Sets the results + migrationView.novelResults.set(x, N); - } catch (IOException e) { - e.printStackTrace(); - } } return null; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java index 51f91ae8ee..c6aef0341e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java @@ -14,11 +14,11 @@ import com.github.doomsdayrs.apps.shosetsu.ui.migration.MigrationView; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.TimeUnit; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* * This file is part of Shosetsu. @@ -45,8 +45,7 @@ public class Transfer extends AsyncTask { private final ArrayList strings; private final Formatter formatter; @SuppressLint("StaticFieldLeak") - private - MigrationView migrationView; + private final MigrationView migrationView; private boolean C = true; public Transfer(ArrayList strings, int target, MigrationView migrationView) { @@ -81,51 +80,46 @@ protected Void doInBackground(Void... voids) { String s = strings[0] + "--->" + strings[1]; System.out.println(s); migrationView.output.post(() -> migrationView.output.setText(s)); - try { - NovelPage novelPage = formatter.parseNovel(strings[1]); - if (formatter.isIncrementingChapterList()) { - int mangaCount = 0; - int page = 1; - while (page <= novelPage.maxChapterPage && C) { - String p = "Page: " + page + "/" + novelPage.maxChapterPage; - migrationView.pageCount.post(() -> migrationView.pageCount.setText(p)); + NovelPage novelPage = formatter.parseNovel(docFromURL((strings[1]), formatter.hasCloudFlare())); + if (formatter.isIncrementingChapterList()) { + int mangaCount = 0; + int page = 1; + while (page <= novelPage.maxChapterPage && C) { + String p = "Page: " + page + "/" + novelPage.maxChapterPage; + migrationView.pageCount.post(() -> migrationView.pageCount.setText(p)); - novelPage = formatter.parseNovel(strings[1], page); - int novelID = getNovelIDFromNovelURL(strings[1]); - for (NovelChapter novelChapter : novelPage.novelChapters) - if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { - mangaCount++; - System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); - - Database.DatabaseChapter.addToChapters(novelID, novelChapter); - } - page++; - - try { - TimeUnit.MILLISECONDS.sleep(300); - } catch (InterruptedException e) { - if (e.getMessage() != null) - Log.e("Interrupt", e.getMessage()); - } - } - } else { - int mangaCount = 0; + novelPage = formatter.parseNovel(docFromURL(strings[1], formatter.hasCloudFlare()), page); int novelID = getNovelIDFromNovelURL(strings[1]); for (NovelChapter novelChapter : novelPage.novelChapters) if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); } + page++; + + try { + TimeUnit.MILLISECONDS.sleep(300); + } catch (InterruptedException e) { + if (e.getMessage() != null) + Log.e("Interrupt", e.getMessage()); + } } - if (C) { - migrationView.pageCount.post(() -> migrationView.pageCount.setText("")); - int oldID = getNovelIDFromNovelURL(strings[0]); - Database.DatabaseNovels.migrateNovel(oldID, strings[1], formatter.getID(), novelPage, Database.DatabaseNovels.getStatus(oldID).getA()); - } - } catch (IOException e) { - if (e.getMessage() != null) - Log.e("Interrupt", e.getMessage()); + } else { + int mangaCount = 0; + int novelID = getNovelIDFromNovelURL(strings[1]); + for (NovelChapter novelChapter : novelPage.novelChapters) + if (C && !Database.DatabaseChapter.inChapters(novelChapter.link)) { + mangaCount++; + System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); + Database.DatabaseChapter.addToChapters(novelID, novelChapter); + } + } + if (C) { + migrationView.pageCount.post(() -> migrationView.pageCount.setText("")); + int oldID = getNovelIDFromNovelURL(strings[0]); + Database.DatabaseNovels.migrateNovel(oldID, strings[1], formatter.getID(), novelPage, Database.DatabaseNovels.getStatus(oldID).getA()); } } return null; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index e331ac32b9..1afb94e75b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -59,7 +59,6 @@ */ public class NovelFragment extends Fragment { - public int novelID; public String novelURL; public NovelPage novelPage; @@ -131,7 +130,7 @@ public int lastRead() { public NovelFragmentInfo novelFragmentInfo; - public NovelFragmentChapters novelFragmentChapters; + private NovelFragmentChapters novelFragmentChapters; public ProgressBar progressBar; private TabLayout tabLayout; @@ -146,10 +145,6 @@ public NovelFragment() { setHasOptionsMenu(true); } - @Override - public void onDestroy() { - super.onDestroy(); - } @Override public void onSaveInstanceState(@NonNull Bundle outState) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index bf34e98f11..fc6c7326c8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -12,9 +12,8 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; -import java.io.IOException; - import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* * This file is part of Shosetsu. @@ -44,8 +43,8 @@ */ public class ChapterLoader extends AsyncTask { private NovelPage novelPage; - private String novelURL; - private Formatter formatter; + private final String novelURL; + private final Formatter formatter; private NovelFragmentChapters novelFragmentChapters; @@ -58,7 +57,7 @@ public ChapterLoader(NovelPage novelPage, String novelURL, Formatter formatter) this.formatter = formatter; } - ChapterLoader(ChapterLoader chapterLoader) { + private ChapterLoader(ChapterLoader chapterLoader) { this.novelPage = chapterLoader.novelPage; this.novelURL = chapterLoader.novelURL; this.formatter = chapterLoader.formatter; @@ -82,44 +81,44 @@ protected Boolean doInBackground(Activity... voids) { novelPage = null; Log.d("ChapLoad", novelURL); - if (novelFragmentChapters != null) + if (novelFragmentChapters != null) { if (novelFragmentChapters.getActivity() != null) novelFragmentChapters.getActivity().runOnUiThread(() -> novelFragmentChapters.novelFragment.errorView.setVisibility(View.GONE)); - try { + try { - int page = 1; - if (formatter.isIncrementingChapterList()) { - novelPage = formatter.parseNovel(novelURL, page); - int mangaCount = 0; - while (page <= novelPage.maxChapterPage && !activity.isDestroyed()) { - if (novelFragmentChapters != null) { + int page = 1; + if (formatter.isIncrementingChapterList()) { + novelPage = formatter.parseNovel(docFromURL(novelURL, formatter.hasCloudFlare()), page); + int mangaCount = 0; + while (page <= novelPage.maxChapterPage && !activity.isDestroyed()) { String s = "Page: " + page + "/" + novelPage.maxChapterPage; novelFragmentChapters.pageCount.post(() -> novelFragmentChapters.pageCount.setText(s)); + + novelPage = formatter.parseNovel(docFromURL(novelURL, formatter.hasCloudFlare()), page); + for (NovelChapter novelChapter : novelPage.novelChapters) + add(activity, mangaCount, novelChapter); + page++; + + Utilities.wait(300); } - novelPage = formatter.parseNovel(novelURL, page); + } else { + novelPage = formatter.parseNovel(docFromURL(novelURL, formatter.hasCloudFlare()), page); + int mangaCount = 0; for (NovelChapter novelChapter : novelPage.novelChapters) add(activity, mangaCount, novelChapter); - page++; - - Utilities.wait(300); } - } else { - novelPage = formatter.parseNovel(novelURL, page); - int mangaCount = 0; - for (NovelChapter novelChapter : novelPage.novelChapters) - add(activity, mangaCount, novelChapter); - } - return true; - } catch (IOException e) { - if (novelFragmentChapters != null) - if (novelFragmentChapters.getActivity() != null) - novelFragmentChapters.getActivity().runOnUiThread(() -> { - novelFragmentChapters.novelFragment.errorView.setVisibility(View.VISIBLE); - novelFragmentChapters.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentChapters.novelFragment.errorButton.setOnClickListener(view -> refresh(view, activity)); - }); + return true; + } catch (Exception e) { + if (novelFragmentChapters != null) + if (novelFragmentChapters.getActivity() != null) + novelFragmentChapters.getActivity().runOnUiThread(() -> { + novelFragmentChapters.novelFragment.errorView.setVisibility(View.VISIBLE); + novelFragmentChapters.novelFragment.errorMessage.setText(e.getMessage()); + novelFragmentChapters.novelFragment.errorButton.setOnClickListener(view -> refresh(view, activity)); + }); + } } return false; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index b2b04befd9..9eea878ab3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -13,9 +13,10 @@ import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; -import java.io.IOException; +import org.jsoup.nodes.Document; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* * This file is part of Shosetsu. @@ -54,7 +55,8 @@ public class NovelLoader extends AsyncTask { private final NovelFragment novelFragment; private final NovelFragmentInfo novelFragmentInfo; - private boolean loadAll; + private final boolean loadAll; + /** * Constructor @@ -63,11 +65,19 @@ public class NovelLoader extends AsyncTask { */ public NovelLoader(NovelFragment novelFragment, boolean loadAll) { this.novelFragment = novelFragment; + this.novelURL = novelFragment.novelURL; + this.formatter = novelFragment.formatter; + this.novelID = novelFragment.novelID; + this.novelPage = novelFragment.novelPage; this.loadAll = loadAll; this.novelFragmentInfo = null; } public NovelLoader(NovelFragmentInfo novelFragmentInfo, boolean loadAll) { + this.formatter = novelFragmentInfo.novelFragment.formatter; + this.novelURL = novelFragmentInfo.novelFragment.novelURL; + this.novelID = novelFragmentInfo.novelFragment.novelID; + this.novelPage = novelFragmentInfo.novelFragment.novelPage; this.novelFragment = null; this.loadAll = loadAll; this.novelFragmentInfo = novelFragmentInfo; @@ -75,6 +85,7 @@ public NovelLoader(NovelFragmentInfo novelFragmentInfo, boolean loadAll) { private NovelLoader(NovelLoader novelLoader) { this.novelURL = novelLoader.novelURL; + assert (novelLoader.formatter != null); this.formatter = novelLoader.formatter; this.novelPage = novelLoader.novelPage; this.novelID = novelLoader.novelID; @@ -93,7 +104,7 @@ private NovelLoader(NovelLoader novelLoader) { protected Boolean doInBackground(Activity... voids) { Activity activity = voids[0]; - Log.d("Loading", novelURL); + Log.d("Loading", String.valueOf(novelURL)); if (loadAll) { if (novelFragment != null && novelFragment.getActivity() != null) novelFragment.getActivity().runOnUiThread(() -> novelFragment.errorView.setVisibility(View.GONE)); @@ -103,7 +114,9 @@ protected Boolean doInBackground(Activity... voids) { try { - novelPage = formatter.parseNovel(novelURL); + Document document = docFromURL(novelURL, formatter.hasCloudFlare()); + assert (document != null); + novelPage = formatter.parseNovel(document); if (!activity.isDestroyed() && !Database.DatabaseNovels.inDatabase(novelID)) { Database.DatabaseNovels.addToLibrary(formatter.getID(), novelPage, novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } @@ -116,7 +129,7 @@ protected Boolean doInBackground(Activity... voids) { Log.d("Loaded Novel:", novelPage.title); return true; - } catch (IOException e) { + } catch (Exception e) { if (loadAll) { if (novelFragment != null && novelFragment.getActivity() != null) novelFragment.getActivity().runOnUiThread(() -> { @@ -130,7 +143,7 @@ protected Boolean doInBackground(Activity... voids) { novelFragmentInfo.novelFragment.errorMessage.setText(e.getMessage()); novelFragmentInfo.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); - + e.printStackTrace(); } return false; @@ -146,11 +159,13 @@ private void refresh(Activity activity) { @Override protected void onPreExecute() { if (loadAll) { - assert novelFragment != null; - novelFragment.progressBar.setVisibility(View.VISIBLE); + if (novelFragment != null) { + novelFragment.progressBar.setVisibility(View.VISIBLE); + } } else { - assert novelFragmentInfo != null; - novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); + if (novelFragmentInfo != null) { + novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); + } } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java index 0499d400ff..24a29e75b0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java @@ -28,7 +28,7 @@ */ public class NovelFragmentUpdate implements SwipeRefreshLayout.OnRefreshListener { - private NovelFragmentInfo novelFragmentInfo; + private final NovelFragmentInfo novelFragmentInfo; public NovelFragmentUpdate(NovelFragmentInfo novelFragmentInfo) { this.novelFragmentInfo = novelFragmentInfo; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 06f3d76569..47a15048fb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -168,9 +168,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c pageCount = view.findViewById(R.id.page_count); resumeRead = view.findViewById(R.id.resume); resumeRead.setVisibility(View.GONE); - swipeRefreshLayout.setOnRefreshListener(() -> { - new ChapterLoader(novelFragment.novelPage, novelFragment.novelURL, novelFragment.formatter).setNovelFragmentChapters(this).execute(getActivity()); - }); + swipeRefreshLayout.setOnRefreshListener(() -> new ChapterLoader(novelFragment.novelPage, novelFragment.novelURL, novelFragment.formatter).setNovelFragmentChapters(this).execute(getActivity())); if (savedInstanceState != null) { currentMaxPage = savedInstanceState.getInt("maxPage"); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 585e90426d..de659d64b2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -23,6 +23,7 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; @@ -77,45 +78,41 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { + // Order of values. Small,Medium,Large + private final MenuItem[] textSizes = new MenuItem[3]; public boolean ready = false; - - public TextView textView; - public MarkdownView markdownView; - int readerType; + // Order of values. Non,Small,Medium,Large + private final MenuItem[] paragraphSpaces = new MenuItem[4]; + // Order of values. Non,Small,Medium,Large + private final MenuItem[] indentSpaces = new MenuItem[4]; + // Order of values. Default, Markdown + private final MenuItem[] readers = new MenuItem[2]; public ScrollView scrollView; public ProgressBar progressBar; - public Chip nextChapter; + public WebViewScrapper webViewScrapper; public String title; public Formatter formatter; public int chapterID; - public int novelID; - - public String[] chapters; + private TextView textView; + private MarkdownView markdownView; public String chapterURL; public String unformattedText = null; - public String text = null; + private int readerType; private MenuItem bookmark; private boolean bookmarked; private MenuItem tap_to_scroll; - // Order of values. Small,Medium,Large - private MenuItem[] textSizes = new MenuItem[3]; - - // Order of values. Non,Small,Medium,Large - private MenuItem[] paragraphSpaces = new MenuItem[4]; - - // Order of values. Non,Small,Medium,Large - private MenuItem[] indentSpaces = new MenuItem[4]; - - // Order of values. Default, Markdown - private MenuItem[] readers = new MenuItem[2]; + private Chip nextChapter; + private int novelID; + private String[] chapters; + private String text = null; //Tap to scroll @@ -461,7 +458,7 @@ public void setUpReader() { /** * What to do when scroll hits bottom */ - public void bottom() { + private void bottom() { int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); if (ready) if ((scrollView.getScrollY() / (float) total) < .99) { @@ -491,7 +488,7 @@ public void bottom() { /** * Loads the chapter to be read */ - public void loadChapter() { + private void loadChapter() { ready = false; if (Database.DatabaseChapter.isSaved(chapterID)) { unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterID)); @@ -541,7 +538,7 @@ private void scrollDown() { /** * Sets up the hitting bottom listener */ - public void addBottomListener() { + private void addBottomListener() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> bottom()); } else { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index 5a2b6384f3..b1668195e4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -7,6 +7,8 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; + /* * This file is part of Shosetsu. * @@ -47,7 +49,7 @@ public ReaderViewLoader(ChapterReader chapterReader) { protected String doInBackground(ChapterReader... chapterReaders) { chapterReader.runOnUiThread(() -> chapterReader.errorView.setVisibility(View.GONE)); try { - chapterReader.unformattedText = chapterReader.formatter.getNovelPassage(chapterReader.chapterURL); + chapterReader.unformattedText = chapterReader.formatter.getNovelPassage(docFromURL(chapterReader.chapterURL, chapterReader.formatter.hasCloudFlare())); chapterReader.runOnUiThread(chapterReader::setUpReader); chapterReader.runOnUiThread(() -> chapterReader.scrollView.post(() -> diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/listener/OnSettingsCardClick.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/listener/OnSettingsCardClick.java index f50a2e6a58..19d57c6b06 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/listener/OnSettingsCardClick.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/listener/OnSettingsCardClick.java @@ -34,8 +34,8 @@ import com.github.doomsdayrs.apps.shosetsu.variables.enums.Types; public class OnSettingsCardClick implements View.OnClickListener { - final Types type; - final FragmentManager fragmentManager; + private final Types type; + private final FragmentManager fragmentManager; public OnSettingsCardClick(Types id, FragmentManager fragmentManager) { type = id; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java index 83b4ef6020..1cf5b51b1f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java @@ -101,6 +101,7 @@ private void onClickNIghtMode(View v) { } } + /* private void onClickTextSize(View v) { } @@ -112,7 +113,7 @@ private void onClickParaSpacing(View v) { private void onClickParaIndent(View v) { } - +*/ @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index f03f3f46d5..ee21197e36 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -52,6 +52,7 @@ */ public class BackupProcess extends AsyncTask { @SuppressLint("StaticFieldLeak") + private final Context context; public BackupProcess(Context context) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index fe5dbb038e..787c100c61 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -56,20 +56,25 @@ * @author github.com/doomsdayrs */ public class RestoreProcess extends AsyncTask { - String file_path; + private final String file_path; @SuppressLint("StaticFieldLeak") + private final Context context; @SuppressLint("StaticFieldLeak") + private final Button close; @SuppressLint("StaticFieldLeak") + private final ProgressBar progressBar; @SuppressLint("StaticFieldLeak") + private final ProgressBar progressBar2; @SuppressLint("StaticFieldLeak") + private final TextView textView; - Dialog dialog; + private final Dialog dialog; public RestoreProcess(String file_path, Context context) { this.file_path = file_path; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java index 1fd5e8b29a..aee4324969 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java @@ -34,9 +34,9 @@ import com.github.doomsdayrs.apps.shosetsu.variables.enums.Types; public class SettingsCardViewHolder extends RecyclerView.ViewHolder { - final TextView library_card_title; - final CardView cardView; - final FragmentManager fragmentManager; + private final TextView library_card_title; + private final CardView cardView; + private final FragmentManager fragmentManager; public SettingsCardViewHolder(@NonNull View itemView, FragmentManager fragmentManager) { super(itemView); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java index 447ac38026..a0924ce7c2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java @@ -45,7 +45,7 @@ */ public class UpdateFragment extends Fragment { public long date = -1; - private ArrayList novels = new ArrayList<>(); + private final ArrayList novels = new ArrayList<>(); private ArrayList updates = new ArrayList<>(); private RecyclerView recyclerView; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java index 36ba883a1c..220bdfcfc2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java @@ -58,6 +58,7 @@ public class UpdatesFragment extends Fragment { private TabLayout tabLayout; private ViewPager viewPager; + public UpdatesFragment() { setHasOptionsMenu(true); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index 91c9b92313..b5be6b4e27 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -53,11 +53,11 @@ * @author github.com/doomsdayrs */ public class UpdatedChaptersAdapter extends RecyclerView.Adapter { - public static int DefaultTextColor; + private static int DefaultTextColor; private static boolean set = false; - public final ArrayList updates; - public final Activity activity; + private final ArrayList updates; + private final Activity activity; public UpdatedChaptersAdapter(ArrayList updates, Activity activity) { this.updates = updates; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedNovelsAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedNovelsAdapter.java index cb7cfd534a..73f89827c3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedNovelsAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedNovelsAdapter.java @@ -30,8 +30,8 @@ * * @author github.com/doomsdayrs */ -public class UpdatedNovelsAdapter extends RecyclerView.Adapter { - public ArrayList novelURLs = new ArrayList<>(); +class UpdatedNovelsAdapter extends RecyclerView.Adapter { + private ArrayList novelURLs = new ArrayList<>(); UpdatedNovelsAdapter(ArrayList novelURLs) { this.novelURLs = novelURLs; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java index ce26253f70..f0d9f723b2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java @@ -18,10 +18,10 @@ import org.jetbrains.annotations.NotNull; -import java.io.IOException; import java.util.ArrayList; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* * This file is part of Shosetsu. @@ -48,11 +48,13 @@ public class ChapterUpdater extends AsyncTask { private static final int ID = 1917; private static final String channel_ID = "shosetsu_updater"; - private ArrayList novelCards; + private final ArrayList novelCards; private boolean continueProcesss = true; - private NotificationManager notificationManager; + private final NotificationManager notificationManager; private Notification.Builder builder; - private ArrayList updatedNovels = new ArrayList<>(); + private final ArrayList updatedNovels = new ArrayList<>(); + + public ChapterUpdater(@NotNull ArrayList novelCards, Context context) { this.novelCards = novelCards; @@ -85,38 +87,34 @@ protected void onPreExecute() { @Override protected Void doInBackground(Void... voids) { - try { - for (int x = 0; x < novelCards.size(); x++) { - NovelCard novelCard = novelCards.get(x); - builder.setContentText(novelCard.title); - builder.setProgress(novelCards.size(), x + 1, false); - notificationManager.notify(ID, builder.build()); - - Formatter formatter = DefaultScrapers.getByID(novelCard.formatterID); - if (formatter != null) { - int page = 1; - NovelPage tempPage; - if (formatter.isIncrementingChapterList()) { - tempPage = formatter.parseNovel(novelCard.novelURL, page); - int mangaCount = 0; - while (page <= tempPage.maxChapterPage && continueProcesss) { - tempPage = formatter.parseNovel(novelCard.novelURL, page); - for (NovelChapter novelChapter : tempPage.novelChapters) - add(mangaCount, novelChapter, novelCard); - page++; - Utilities.wait(300); - } - } else { - tempPage = formatter.parseNovel(novelCard.novelURL, page); - int mangaCount = 0; + for (int x = 0; x < novelCards.size(); x++) { + NovelCard novelCard = novelCards.get(x); + builder.setContentText(novelCard.title); + builder.setProgress(novelCards.size(), x + 1, false); + notificationManager.notify(ID, builder.build()); + + Formatter formatter = DefaultScrapers.getByID(novelCard.formatterID); + if (formatter != null) { + int page = 1; + NovelPage tempPage; + if (formatter.isIncrementingChapterList()) { + tempPage = formatter.parseNovel(docFromURL(novelCard.novelURL, formatter.hasCloudFlare()), page); + int mangaCount = 0; + while (page <= tempPage.maxChapterPage && continueProcesss) { + tempPage = formatter.parseNovel(docFromURL(novelCard.novelURL, formatter.hasCloudFlare()), page); for (NovelChapter novelChapter : tempPage.novelChapters) add(mangaCount, novelChapter, novelCard); + page++; + Utilities.wait(300); } + } else { + tempPage = formatter.parseNovel(docFromURL(novelCard.novelURL, formatter.hasCloudFlare()), page); + int mangaCount = 0; + for (NovelChapter novelChapter : tempPage.novelChapters) + add(mangaCount, novelChapter, novelCard); } - Utilities.wait(1000); } - } catch (IOException e) { - e.printStackTrace(); + Utilities.wait(1000); } return null; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 67ae7414b4..7955e6ccbe 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -47,10 +47,10 @@ */ public class UpdatedChapterHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public final ImageView moreOptions; - public ImageView image; + public final TextView downloadTag; public NovelChapter novelChapter; - public TextView downloadTag; - public TextView title; + public final TextView title; + private final ImageView image; public PopupMenu popupMenu; public UpdatedChapterHolder(@NonNull View itemView) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedNovelHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedNovelHolder.java index b025e0e7b4..9edf0ff470 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedNovelHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedNovelHolder.java @@ -23,5 +23,5 @@ * * @author github.com/doomsdayrs */ -public class UpdatedNovelHolder { +class UpdatedNovelHolder { } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/Actions.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/Actions.java index 77eea392a3..ea939524d6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/Actions.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/Actions.java @@ -33,7 +33,7 @@ public enum Actions { actions.add(Actions.CLOUD_FLARE); } - public final int action; + private final int action; Actions(int action) { this.action = action; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/JSInterface.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/JSInterface.java index 50d7b3e3c3..edebb7bbaa 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/JSInterface.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/JSInterface.java @@ -25,8 +25,8 @@ * * @author github.com/doomsdayrs */ -public class JSInterface { - private Context ctx; +class JSInterface { + private final Context ctx; JSInterface(Context ctx) { this.ctx = ctx; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java index f7d2c3c8c5..b0edf8842a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/webView/WebViewApp.java @@ -35,8 +35,8 @@ public class WebViewApp extends AppCompatActivity { - WebView webView; - Actions action = Actions.VIEW; + private WebView webView; + private Actions action = Actions.VIEW; @SuppressLint("SetJavaScriptEnabled") @Override diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java index 75bd3aab0d..ad276b764e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java @@ -55,7 +55,7 @@ public enum DefaultScrapers implements Formatter { //NOVELPLANENT(new NovelPlanet(4)), BESTLIGHTNOVEL(new BestLightNovel()); - public static final ArrayList formatters = new ArrayList<>(); + private static final ArrayList formatters = new ArrayList<>(); public static Formatter getByID(int ID) { for (Formatter formatter : formatters) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java index f2813c02bd..3b4069a3a4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java @@ -37,9 +37,9 @@ public class DownloadItem { public final Formatter formatter; public final String novelName; public final String chapterName; - public final String novelURL; + private final String novelURL; public final String chapterURL; - public final int novelID; + private final int novelID; public final int chapterID; //Variables only for download manager diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java index 34cf2c5fe4..98adbdf209 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/RecycleCard.java @@ -2,8 +2,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; -import java.io.Serializable; - /* * This file is part of Shosetsu. * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java index 15a0e670d0..9bb97900c7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java @@ -30,9 +30,9 @@ import com.github.doomsdayrs.apps.shosetsu.R; public class SettingsItem { - protected View itemView; - protected TextView itemTitle; - protected TextView itemDesc; + private final View itemView; + private final TextView itemTitle; + private final TextView itemDesc; public SettingsItem(@NonNull View view) { itemView = view; diff --git a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java index 1f9c360f59..556b79d6e1 100644 --- a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java +++ b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java @@ -5,7 +5,7 @@ * * @see Testing documentation */ -public class ExampleUnitTest { +class ExampleUnitTest { From 80873cace32b70aa5d661d8be993c7d822fafefb Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Tue, 12 Nov 2019 23:08:19 -0500 Subject: [PATCH 056/162] Working on this messy code in NovelLoader --- .../apps/shosetsu/backend/ErrorView.java | 44 +++++++++++++++++ .../shosetsu/ui/novel/async/NovelLoader.java | 47 ++++--------------- 2 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/ErrorView.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/ErrorView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/ErrorView.java new file mode 100644 index 0000000000..84ea968ad4 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/ErrorView.java @@ -0,0 +1,44 @@ +package com.github.doomsdayrs.apps.shosetsu.backend; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.app.Activity; +import android.widget.Button; +import android.widget.TextView; + +import androidx.constraintlayout.widget.ConstraintLayout; + +/** + * shosetsu + * 12 / 11 / 2019 + * + * @author github.com/doomsdayrs + */ +public class ErrorView { + public final Activity activity; + public final ConstraintLayout errorView; + public final TextView errorMessage; + public final Button errorButton; + + public ErrorView(Activity activity, ConstraintLayout errorView, TextView errorMessage, Button errorButton) { + this.activity = activity; + this.errorView = errorView; + this.errorMessage = errorMessage; + this.errorButton = errorButton; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 9eea878ab3..39e3385b02 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -8,9 +8,9 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; +import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import org.jsoup.nodes.Document; @@ -51,9 +51,7 @@ public class NovelLoader extends AsyncTask { private NovelPage novelPage; private int novelID; - // References - private final NovelFragment novelFragment; - private final NovelFragmentInfo novelFragmentInfo; + ErrorView errorView; private final boolean loadAll; @@ -63,25 +61,15 @@ public class NovelLoader extends AsyncTask { * * @param novelFragment reference to the fragment */ - public NovelLoader(NovelFragment novelFragment, boolean loadAll) { - this.novelFragment = novelFragment; + public NovelLoader(NovelFragment novelFragment, ErrorView errorView, boolean loadAll) { this.novelURL = novelFragment.novelURL; this.formatter = novelFragment.formatter; this.novelID = novelFragment.novelID; this.novelPage = novelFragment.novelPage; this.loadAll = loadAll; - this.novelFragmentInfo = null; + this.errorView = errorView; } - public NovelLoader(NovelFragmentInfo novelFragmentInfo, boolean loadAll) { - this.formatter = novelFragmentInfo.novelFragment.formatter; - this.novelURL = novelFragmentInfo.novelFragment.novelURL; - this.novelID = novelFragmentInfo.novelFragment.novelID; - this.novelPage = novelFragmentInfo.novelFragment.novelPage; - this.novelFragment = null; - this.loadAll = loadAll; - this.novelFragmentInfo = novelFragmentInfo; - } private NovelLoader(NovelLoader novelLoader) { this.novelURL = novelLoader.novelURL; @@ -89,9 +77,8 @@ private NovelLoader(NovelLoader novelLoader) { this.formatter = novelLoader.formatter; this.novelPage = novelLoader.novelPage; this.novelID = novelLoader.novelID; - this.novelFragment = novelLoader.novelFragment; this.loadAll = novelLoader.loadAll; - this.novelFragmentInfo = novelLoader.novelFragmentInfo; + this.errorView = novelLoader.errorView; } /** @@ -105,13 +92,7 @@ private NovelLoader(NovelLoader novelLoader) { protected Boolean doInBackground(Activity... voids) { Activity activity = voids[0]; Log.d("Loading", String.valueOf(novelURL)); - if (loadAll) { - if (novelFragment != null && novelFragment.getActivity() != null) - novelFragment.getActivity().runOnUiThread(() -> novelFragment.errorView.setVisibility(View.GONE)); - - } else if (novelFragmentInfo != null && novelFragmentInfo.getActivity() != null) - novelFragmentInfo.getActivity().runOnUiThread(() -> novelFragmentInfo.novelFragment.errorView.setVisibility(View.GONE)); - + errorView.activity.runOnUiThread(() -> errorView.errorView.setVisibility(View.GONE)); try { Document document = docFromURL(novelURL, formatter.hasCloudFlare()); @@ -130,19 +111,9 @@ protected Boolean doInBackground(Activity... voids) { Log.d("Loaded Novel:", novelPage.title); return true; } catch (Exception e) { - if (loadAll) { - if (novelFragment != null && novelFragment.getActivity() != null) - novelFragment.getActivity().runOnUiThread(() -> { - novelFragment.errorView.setVisibility(View.VISIBLE); - novelFragment.errorMessage.setText(e.getMessage()); - novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); - }); - } else if (novelFragmentInfo != null && novelFragmentInfo.getActivity() != null) - novelFragmentInfo.getActivity().runOnUiThread(() -> { - novelFragmentInfo.novelFragment.errorView.setVisibility(View.VISIBLE); - novelFragmentInfo.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentInfo.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); - }); + errorView.activity.runOnUiThread(() -> errorView.errorView.setVisibility(View.VISIBLE)); + errorView.activity.runOnUiThread(() -> errorView.errorMessage.setText(e.getMessage())); + errorView.activity.runOnUiThread(() -> errorView.errorButton.setOnClickListener(view -> refresh(activity))); e.printStackTrace(); } From f76d06d532d5ca0733fd8633218e1855ebb1436d Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Wed, 13 Nov 2019 15:20:05 -0500 Subject: [PATCH 057/162] Working on rewriting loader --- .../shosetsu/ui/novel/async/NovelLoader.java | 70 +----------- .../ui/novel/async/NovelLoaderHolder.java | 107 ++++++++++++++++++ 2 files changed, 110 insertions(+), 67 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 39e3385b02..1560ad9c6c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -1,7 +1,6 @@ package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; import android.app.Activity; -import android.os.AsyncTask; import android.util.Log; import android.view.View; @@ -11,7 +10,6 @@ import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import org.jsoup.nodes.Document; @@ -45,7 +43,7 @@ * This task loads a novel for the novel fragment *

*/ -public class NovelLoader extends AsyncTask { +public class NovelLoader extends NovelLoaderHolder { private String novelURL; private Formatter formatter; private NovelPage novelPage; @@ -62,6 +60,7 @@ public class NovelLoader extends AsyncTask { * @param novelFragment reference to the fragment */ public NovelLoader(NovelFragment novelFragment, ErrorView errorView, boolean loadAll) { + super(novelFragment, null); this.novelURL = novelFragment.novelURL; this.formatter = novelFragment.formatter; this.novelID = novelFragment.novelID; @@ -72,6 +71,7 @@ public NovelLoader(NovelFragment novelFragment, ErrorView errorView, boolean loa private NovelLoader(NovelLoader novelLoader) { + super(novelLoader.novelFragment, novelLoader.novelFragmentInfo); this.novelURL = novelLoader.novelURL; assert (novelLoader.formatter != null); this.formatter = novelLoader.formatter; @@ -124,74 +124,10 @@ private void refresh(Activity activity) { new NovelLoader(this).execute(activity); } - /** - * Show progress bar - */ - @Override - protected void onPreExecute() { - if (loadAll) { - if (novelFragment != null) { - novelFragment.progressBar.setVisibility(View.VISIBLE); - } - } else { - if (novelFragmentInfo != null) { - novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); - } - } - } - @Override protected void onCancelled() { onPostExecute(false); } - /** - * Hides progress and sets data - * - * @param aBoolean if completed - */ - @Override - protected void onPostExecute(Boolean aBoolean) { - Activity activity = null; - if (novelFragmentInfo != null) - activity = novelFragmentInfo.getActivity(); - else if (novelFragment != null) { - activity = novelFragment.getActivity(); - } - - if (activity != null) { - if (loadAll) { - if (novelFragment != null) { - novelFragment.progressBar.setVisibility(View.GONE); - } - } else { - if (novelFragmentInfo != null) { - novelFragmentInfo.swipeRefreshLayout.setRefreshing(false); - } - if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { - try { - Database.DatabaseNovels.updateData(novelURL, novelPage); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - if (aBoolean) { - Statics.mainActionBar.setTitle(novelPage.title); - activity.runOnUiThread(() -> { - if (loadAll) - if (novelFragment != null) { - novelFragment.novelFragmentInfo.setData(); - } else { - novelFragmentInfo.setData(); - } - }); - if (loadAll) { - activity.runOnUiThread(() -> new ChapterLoader(novelPage, novelURL, formatter).execute()); - } - } - } - - } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java new file mode 100644 index 0000000000..5a09ceedeb --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java @@ -0,0 +1,107 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.app.Activity; +import android.os.AsyncTask; +import android.util.Log; +import android.view.View; + +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; +import com.github.doomsdayrs.apps.shosetsu.variables.Statics; + +/** + * shosetsu + * 13 / 11 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NovelLoaderHolder extends AsyncTask { + final NovelFragment novelFragment; + final NovelFragmentInfo novelFragmentInfo; + + public NovelLoaderHolder(NovelFragment novelFragment, NovelFragmentInfo novelFragmentInfo) { + this.novelFragment = novelFragment; + this.novelFragmentInfo = novelFragmentInfo; + if ((novelFragment == null && novelFragmentInfo == null) || (novelFragment != null && novelFragmentInfo != null)) { + Log.e("NovelLoaderHolder", "Dual used/null"); + throw new NullPointerException("Dual used/null"); + } + } + + + @Override + protected void onPreExecute() { + if (novelFragment != null) { + novelFragment.progressBar.setVisibility(View.VISIBLE); + } + if (novelFragmentInfo != null) { + novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); + } + } + + @Override + protected Boolean doInBackground(Activity... activities) { + return null; + } + + @Override + protected void onPostExecute(Boolean aBoolean) { + Activity activity = null; + if (novelFragmentInfo != null) + activity = novelFragmentInfo.getActivity(); + if (novelFragment != null) + activity = novelFragment.getActivity(); + + + if (loadAll) { + if (novelFragment != null) { + novelFragment.progressBar.setVisibility(View.GONE); + } + } else { + if (novelFragmentInfo != null) { + novelFragmentInfo.swipeRefreshLayout.setRefreshing(false); + } + if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + try { + Database.DatabaseNovels.updateData(novelURL, novelPage); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (aBoolean) { + Statics.mainActionBar.setTitle(novelPage.title); + activity.runOnUiThread(() -> { + if (loadAll) + if (novelFragment != null) { + novelFragment.novelFragmentInfo.setData(); + } else { + novelFragmentInfo.setData(); + } + }); + if (loadAll) { + activity.runOnUiThread(() -> new ChapterLoader(novelPage, novelURL, formatter).execute()); + } + } + } + + } +} From aebeaf366ffef41dd114c4c158f6f42a4dc03837 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Wed, 13 Nov 2019 20:48:08 -0500 Subject: [PATCH 058/162] Working out the kinks of the code --- .../apps/shosetsu/ui/novel/NovelFragment.java | 6 +- .../ui/novel/async/ChapterLoader.java | 24 ++-- .../shosetsu/ui/novel/async/NovelLoader.java | 93 ++++++++------- .../ui/novel/async/NovelLoaderHolder.java | 107 ------------------ .../novel/listeners/NovelFragmentUpdate.java | 11 +- .../ui/novel/pages/NovelFragmentInfo.java | 105 +++++++++-------- app/src/main/res/layout/fragment_novel.xml | 17 --- 7 files changed, 133 insertions(+), 230 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 1afb94e75b..bb19aa7fb7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -6,7 +6,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; -import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; @@ -19,6 +18,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.NovelPagerAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; @@ -131,7 +131,6 @@ public int lastRead() { public NovelFragmentInfo novelFragmentInfo; private NovelFragmentChapters novelFragmentChapters; - public ProgressBar progressBar; private TabLayout tabLayout; private ViewPager viewPager; @@ -162,7 +161,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c View view = inflater.inflate(R.layout.fragment_novel, container, false); // Attach UI to program { - progressBar = view.findViewById(R.id.fragment_novel_progress); viewPager = view.findViewById(R.id.fragment_novel_viewpager); tabLayout = view.findViewById(R.id.fragment_novel_tabLayout); errorView = view.findViewById(R.id.network_error); @@ -183,7 +181,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (savedInstanceState == null) { if (isOnline() && !Database.DatabaseNovels.inDatabase(novelID)) { setViewPager(); - new NovelLoader(this, false).execute(getActivity()); + tabLayout.post(() -> new NovelLoader(this, new ErrorView(getActivity(), errorView, errorMessage, errorButton), false).execute()); } else { novelPage = Database.DatabaseNovels.getNovelPage(novelID); status = Database.DatabaseNovels.getStatus(novelID); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index fc6c7326c8..4d84641b8c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -141,12 +141,10 @@ private void refresh(View view, Activity activity) { */ @Override protected void onPreExecute() { - - if (novelFragmentChapters != null) { - novelFragmentChapters.swipeRefreshLayout.setRefreshing(true); - if (formatter.isIncrementingChapterList()) - novelFragmentChapters.pageCount.setVisibility(View.VISIBLE); - } + assert novelFragmentChapters != null; + novelFragmentChapters.swipeRefreshLayout.setRefreshing(true); + if (formatter.isIncrementingChapterList()) + novelFragmentChapters.pageCount.setVisibility(View.VISIBLE); } @Override @@ -164,19 +162,21 @@ protected void onCancelled() { /** * Hides progress and sets data * - * @param aBoolean if completed + * @param result if completed */ @Override - protected void onPostExecute(Boolean aBoolean) { - if (novelFragmentChapters != null) { + protected void onPostExecute(Boolean result) { + assert novelFragmentChapters != null; + assert novelFragmentChapters.novelFragment.getView() != null; + + novelFragmentChapters.novelFragment.getView().post(() -> { novelFragmentChapters.swipeRefreshLayout.setRefreshing(false); if (formatter.isIncrementingChapterList()) novelFragmentChapters.pageCount.setVisibility(View.GONE); - if (aBoolean) + if (result) if (novelFragmentChapters.getActivity() != null) novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setNovels); novelFragmentChapters.resumeRead.setVisibility(View.VISIBLE); - } - + }); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 1560ad9c6c..6f06b5f74c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -1,15 +1,14 @@ package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; -import android.app.Activity; +import android.os.AsyncTask; import android.util.Log; import android.view.View; -import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; +import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import org.jsoup.nodes.Document; @@ -43,85 +42,76 @@ * This task loads a novel for the novel fragment *

*/ -public class NovelLoader extends NovelLoaderHolder { - private String novelURL; - private Formatter formatter; - private NovelPage novelPage; - private int novelID; - - ErrorView errorView; - - private final boolean loadAll; +public class NovelLoader extends AsyncTask { + private NovelFragment novelFragment; + private boolean loadAll; + private ErrorView errorView; /** * Constructor * * @param novelFragment reference to the fragment + * @param errorView Holder that contains error view and needed code; */ public NovelLoader(NovelFragment novelFragment, ErrorView errorView, boolean loadAll) { - super(novelFragment, null); - this.novelURL = novelFragment.novelURL; - this.formatter = novelFragment.formatter; - this.novelID = novelFragment.novelID; - this.novelPage = novelFragment.novelPage; + this.novelFragment = novelFragment; this.loadAll = loadAll; this.errorView = errorView; } private NovelLoader(NovelLoader novelLoader) { - super(novelLoader.novelFragment, novelLoader.novelFragmentInfo); - this.novelURL = novelLoader.novelURL; - assert (novelLoader.formatter != null); - this.formatter = novelLoader.formatter; - this.novelPage = novelLoader.novelPage; - this.novelID = novelLoader.novelID; + this.novelFragment = novelLoader.novelFragment; this.loadAll = novelLoader.loadAll; this.errorView = novelLoader.errorView; } + + @Override + protected void onPreExecute() { + novelFragment.novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); + } + /** * Background process * - * @param voids activity to work with + * @param voids voided * @return if completed */ @Override - - protected Boolean doInBackground(Activity... voids) { - Activity activity = voids[0]; - Log.d("Loading", String.valueOf(novelURL)); + protected Boolean doInBackground(Void... voids) { + Log.d("Loading", String.valueOf(novelFragment.novelURL)); errorView.activity.runOnUiThread(() -> errorView.errorView.setVisibility(View.GONE)); try { - Document document = docFromURL(novelURL, formatter.hasCloudFlare()); + Document document = docFromURL(novelFragment.novelURL, novelFragment.formatter.hasCloudFlare()); assert (document != null); - novelPage = formatter.parseNovel(document); - if (!activity.isDestroyed() && !Database.DatabaseNovels.inDatabase(novelID)) { - Database.DatabaseNovels.addToLibrary(formatter.getID(), novelPage, novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); + novelFragment.novelPage = novelFragment.formatter.parseNovel(document); + if (!errorView.activity.isDestroyed() && !Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + Database.DatabaseNovels.addToLibrary(novelFragment.formatter.getID(), novelFragment.novelPage, novelFragment.novelURL, com.github.doomsdayrs.apps.shosetsu.variables.enums.Status.UNREAD.getA()); } //TODO The getNovelID in this method likely will cause slowdowns due to IO - int novelID = getNovelIDFromNovelURL(novelURL); - for (NovelChapter novelChapter : novelPage.novelChapters) - if (!activity.isDestroyed() && !Database.DatabaseChapter.inChapters(novelChapter.link)) + int novelID = getNovelIDFromNovelURL(novelFragment.novelURL); + for (NovelChapter novelChapter : novelFragment.novelPage.novelChapters) + if (!errorView.activity.isDestroyed() && !Database.DatabaseChapter.inChapters(novelChapter.link)) Database.DatabaseChapter.addToChapters(novelID, novelChapter); - Log.d("Loaded Novel:", novelPage.title); + Log.d("Loaded Novel:", novelFragment.novelPage.title); return true; } catch (Exception e) { errorView.activity.runOnUiThread(() -> errorView.errorView.setVisibility(View.VISIBLE)); errorView.activity.runOnUiThread(() -> errorView.errorMessage.setText(e.getMessage())); - errorView.activity.runOnUiThread(() -> errorView.errorButton.setOnClickListener(view -> refresh(activity))); + errorView.activity.runOnUiThread(() -> errorView.errorButton.setOnClickListener(view -> refresh())); e.printStackTrace(); } return false; } - private void refresh(Activity activity) { - new NovelLoader(this).execute(activity); + private void refresh() { + new NovelLoader(this).execute(); } @Override @@ -129,5 +119,30 @@ protected void onCancelled() { onPostExecute(false); } + private void setData() { + novelFragment.novelFragmentInfo.setData(); + } + + @Override + protected void onPostExecute(Boolean result) { + assert (novelFragment != null); + + + novelFragment.novelFragmentInfo.swipeRefreshLayout.setRefreshing(false); + if (Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + try { + Database.DatabaseNovels.updateData(novelFragment.novelURL, novelFragment.novelPage); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (result) { + assert novelFragment != null; + Statics.mainActionBar.setTitle(novelFragment.novelPage.title); + if (loadAll) + errorView.activity.runOnUiThread(() -> new ChapterLoader(novelFragment.novelPage, novelFragment.novelURL, novelFragment.formatter).execute()); + errorView.activity.runOnUiThread(this::setData); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java deleted file mode 100644 index 5a09ceedeb..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoaderHolder.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.ui.novel.async; -/* - * This file is part of shosetsu. - * - * shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with shosetsu. If not, see . - * ==================================================================== - */ - -import android.app.Activity; -import android.os.AsyncTask; -import android.util.Log; -import android.view.View; - -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; - -/** - * shosetsu - * 13 / 11 / 2019 - * - * @author github.com/doomsdayrs - */ -public class NovelLoaderHolder extends AsyncTask { - final NovelFragment novelFragment; - final NovelFragmentInfo novelFragmentInfo; - - public NovelLoaderHolder(NovelFragment novelFragment, NovelFragmentInfo novelFragmentInfo) { - this.novelFragment = novelFragment; - this.novelFragmentInfo = novelFragmentInfo; - if ((novelFragment == null && novelFragmentInfo == null) || (novelFragment != null && novelFragmentInfo != null)) { - Log.e("NovelLoaderHolder", "Dual used/null"); - throw new NullPointerException("Dual used/null"); - } - } - - - @Override - protected void onPreExecute() { - if (novelFragment != null) { - novelFragment.progressBar.setVisibility(View.VISIBLE); - } - if (novelFragmentInfo != null) { - novelFragmentInfo.swipeRefreshLayout.setRefreshing(true); - } - } - - @Override - protected Boolean doInBackground(Activity... activities) { - return null; - } - - @Override - protected void onPostExecute(Boolean aBoolean) { - Activity activity = null; - if (novelFragmentInfo != null) - activity = novelFragmentInfo.getActivity(); - if (novelFragment != null) - activity = novelFragment.getActivity(); - - - if (loadAll) { - if (novelFragment != null) { - novelFragment.progressBar.setVisibility(View.GONE); - } - } else { - if (novelFragmentInfo != null) { - novelFragmentInfo.swipeRefreshLayout.setRefreshing(false); - } - if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { - try { - Database.DatabaseNovels.updateData(novelURL, novelPage); - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (aBoolean) { - Statics.mainActionBar.setTitle(novelPage.title); - activity.runOnUiThread(() -> { - if (loadAll) - if (novelFragment != null) { - novelFragment.novelFragmentInfo.setData(); - } else { - novelFragmentInfo.setData(); - } - }); - if (loadAll) { - activity.runOnUiThread(() -> new ChapterLoader(novelPage, novelURL, formatter).execute()); - } - } - } - - } -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java index 24a29e75b0..a9829b8b2c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/listeners/NovelFragmentUpdate.java @@ -2,6 +2,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.ui.novel.async.NovelLoader; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; @@ -36,6 +37,14 @@ public NovelFragmentUpdate(NovelFragmentInfo novelFragmentInfo) { @Override public void onRefresh() { - new NovelLoader(novelFragmentInfo, false).execute(novelFragmentInfo.getActivity()); + new NovelLoader( + novelFragmentInfo.novelFragment, + new ErrorView( + novelFragmentInfo.novelFragment.getActivity(), + novelFragmentInfo.novelFragment.errorView, + novelFragmentInfo.novelFragment.errorMessage, + novelFragmentInfo.novelFragment.errorButton), + false) + .execute(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java index 45daa832a8..e6b57749d4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java @@ -192,59 +192,64 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c * Sets the data of this page */ public void setData() { - if (novelFragment.novelPage == null) { - Log.e("NULL", "Invalid novel page"); - return; - } + assert novelFragment.getView() != null; + + novelFragment.getView().post(() -> { - title.setText(novelFragment.novelPage.title); - - if (novelFragment.novelPage.authors != null && novelFragment.novelPage.authors.length > 0) - authors.setText(Arrays.toString(novelFragment.novelPage.authors)); - - description.setText(novelFragment.novelPage.description); - - if (novelFragment.novelPage.artists != null && novelFragment.novelPage.artists.length > 0) - artists.setText(Arrays.toString(novelFragment.novelPage.artists)); - - status.setText(novelFragment.status.getStatus()); - if (novelFragment.novelPage.status != null) { - String s = "unknown"; - switch (novelFragment.novelPage.status) { - case PAUSED: - pStat.setText(R.string.paused); - s = "Paused"; - break; - case COMPLETED: - pStat.setText(R.string.completed); - s = "Completed"; - break; - case PUBLISHING: - pStat.setText(R.string.publishing); - s = "Publishing"; - break; - default: - pStat.setText(R.string.unknown); + if (novelFragment.novelPage == null) { + Log.e("NULL", "Invalid novel page"); + return; } - System.out.println("PS: " + s); - } - if (novelFragment.novelPage.genres != null && getContext() != null) { - LayoutInflater layoutInflater = LayoutInflater.from(getContext()); - for (String string : novelFragment.novelPage.genres) { - Chip chip = (Chip) layoutInflater.inflate(R.layout.genre_chip, null, false); - chip.setText(string); - genres.addView(chip); + + title.setText(novelFragment.novelPage.title); + + if (novelFragment.novelPage.authors != null && novelFragment.novelPage.authors.length > 0) + authors.setText(Arrays.toString(novelFragment.novelPage.authors)); + + description.setText(novelFragment.novelPage.description); + + if (novelFragment.novelPage.artists != null && novelFragment.novelPage.artists.length > 0) + artists.setText(Arrays.toString(novelFragment.novelPage.artists)); + + status.setText(novelFragment.status.getStatus()); + if (novelFragment.novelPage.status != null) { + String s = "unknown"; + switch (novelFragment.novelPage.status) { + case PAUSED: + pStat.setText(R.string.paused); + s = "Paused"; + break; + case COMPLETED: + pStat.setText(R.string.completed); + s = "Completed"; + break; + case PUBLISHING: + pStat.setText(R.string.publishing); + s = "Publishing"; + break; + default: + pStat.setText(R.string.unknown); + } + System.out.println("PS: " + s); } - } else genres.setVisibility(View.GONE); - - Picasso.get() - .load(novelFragment.novelPage.imageURL) - .into(imageView); - Picasso.get() - .load(novelFragment.novelPage.imageURL) - .into(imageView_background); - floatingActionButton.show(); - formatterName.setText(novelFragment.formatter.getName()); + if (novelFragment.novelPage.genres != null && getContext() != null) { + LayoutInflater layoutInflater = LayoutInflater.from(getContext()); + for (String string : novelFragment.novelPage.genres) { + Chip chip = (Chip) layoutInflater.inflate(R.layout.genre_chip, null, false); + chip.setText(string); + genres.addView(chip); + } + } else genres.setVisibility(View.GONE); + + Picasso.get() + .load(novelFragment.novelPage.imageURL) + .into(imageView); + Picasso.get() + .load(novelFragment.novelPage.imageURL) + .into(imageView_background); + floatingActionButton.show(); + formatterName.setText(novelFragment.formatter.getName()); + }); } } diff --git a/app/src/main/res/layout/fragment_novel.xml b/app/src/main/res/layout/fragment_novel.xml index 3128b16740..dba257d1df 100644 --- a/app/src/main/res/layout/fragment_novel.xml +++ b/app/src/main/res/layout/fragment_novel.xml @@ -1,26 +1,9 @@ - - Date: Thu, 14 Nov 2019 09:04:57 -0500 Subject: [PATCH 059/162] Working on a new reader design Using ViewPager to swipe between chapters Using framelayout(?) to implement dynamic readers Button bar to say what chapter number you are at / progress in novel --- .../ui/novel/async/ChapterLoader.java | 2 +- .../ui/novel/pages/NovelFragmentChapters.java | 30 +---- .../main/res/layout/chapter_reader_new.xml | 115 ++++++++++++++++++ 3 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 app/src/main/res/layout/chapter_reader_new.xml diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 4d84641b8c..a6de467c9e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -175,7 +175,7 @@ protected void onPostExecute(Boolean result) { novelFragmentChapters.pageCount.setVisibility(View.GONE); if (result) if (novelFragmentChapters.getActivity() != null) - novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setNovels); + novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setChapters); novelFragmentChapters.resumeRead.setVisibility(View.VISIBLE); }); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 47a15048fb..0bff0eb885 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -116,14 +116,6 @@ public void setNovelFragment(NovelFragment novelFragment) { this.novelFragment = novelFragment; } - - @Override - public void onResume() { - super.onResume(); - adapter.notifyDataSetChanged(); - } - - @Override public void onDestroy() { super.onDestroy(); @@ -173,7 +165,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (savedInstanceState != null) { currentMaxPage = savedInstanceState.getInt("maxPage"); } - setNovels(); + setChapters(); onResume(); resumeRead.setOnClickListener(view1 -> { int i = novelFragment.lastRead(); @@ -188,11 +180,10 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c /** * Sets the novel chapters down */ - public void setNovels() { - if (recyclerView != null) { + public void setChapters() { + recyclerView.post(() -> { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); - if (Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { novelFragment.novelChapters = Database.DatabaseChapter.getChapters(novelFragment.novelID); if (novelFragment.novelChapters != null && novelFragment.novelChapters.size() != 0) @@ -201,21 +192,8 @@ public void setNovels() { adapter = new ChaptersAdapter(this); adapter.setHasStableIds(true); recyclerView.setLayoutManager(layoutManager); - - // if (novelFragment.formatter.isIncrementingChapterList()) { - // if (SettingsController.isOnline()) - // recyclerView.addOnScrollListener(new NovelFragmentChaptersHitBottom(this)); - - // else recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - // @Override - // public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - // if (!recyclerView.canScrollVertically(1)) - // Toast.makeText(getContext(), "You are offline, impossible to load more", Toast.LENGTH_SHORT).show(); - // } - // }); - // } recyclerView.setAdapter(adapter); - } + }); } public Menu menu; diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml new file mode 100644 index 0000000000..bcb4ad97bf --- /dev/null +++ b/app/src/main/res/layout/chapter_reader_new.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b6609391a2f55d51ecefc0893572d4d5c93acc53 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 14 Nov 2019 14:52:23 -0500 Subject: [PATCH 060/162] Alright, a view pager in a view pager. This is going to be insane --- app/src/main/res/layout/chapter_reader_new.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml index bcb4ad97bf..cc07d7bb2d 100644 --- a/app/src/main/res/layout/chapter_reader_new.xml +++ b/app/src/main/res/layout/chapter_reader_new.xml @@ -35,7 +35,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> - @@ -53,7 +53,7 @@ android:layout_height="wrap_content" android:padding="5dp" android:visibility="gone" /> - + From 022d9e76e07b995385f12fcc14e8ecc6b631872e Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 14 Nov 2019 19:03:13 -0500 Subject: [PATCH 061/162] Working on new reader design. - DemarkActions split to their own folder in reader - ReaderTypeAdapter created - Readers dir created in reader - Readers dir filled with Reader abstract that defines a 'reader', all viewPager fragments are children of said class --- .../shosetsu/ui/reader/ChapterReader.java | 100 ++++++++---------- .../ui/reader/adapters/ReaderTypeAdapter.java | 32 ++++++ .../ui/reader/demarkActions/IndentChange.java | 20 ++++ .../demarkActions/ParaSpacingChange.java | 21 ++++ .../ui/reader/demarkActions/ReaderChange.java | 22 ++++ .../reader/demarkActions/TextSizeChange.java | 22 ++++ .../ui/reader/readers/MarkdownViewReader.java | 24 +++++ .../shosetsu/ui/reader/readers/Reader.java | 9 ++ .../ui/reader/readers/TextViewReader.java | 24 +++++ .../main/res/layout/chapter_reader_new.xml | 3 +- 10 files changed, 218 insertions(+), 59 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ReaderTypeAdapter.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index de659d64b2..1fd80c57df 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -17,28 +17,37 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper; +import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.NovelPagerAdapter; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ParaSpacingChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ReaderChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.TextSizeChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.chip.Chip; +import com.google.android.material.tabs.TabLayout; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import us.feras.mdv.MarkdownView; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeIndentSize; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeParagraphSpacing; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isReaderNightMode; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; @@ -49,7 +58,6 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; /* @@ -78,6 +86,9 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { + private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; + private final ArrayList fragments = new ArrayList<>(); + // Order of values. Small,Medium,Large private final MenuItem[] textSizes = new MenuItem[3]; public boolean ready = false; @@ -92,25 +103,26 @@ public class ChapterReader extends AppCompatActivity { public ProgressBar progressBar; - public WebViewScrapper webViewScrapper; public String title; public Formatter formatter; public int chapterID; + + private ViewPager readerViewPager; private TextView textView; private MarkdownView markdownView; public String chapterURL; public String unformattedText = null; - private int readerType; + public int readerType; private MenuItem bookmark; private boolean bookmarked; private MenuItem tap_to_scroll; private Chip nextChapter; - private int novelID; + public int novelID; private String[] chapters; private String text = null; @@ -267,39 +279,39 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { return true; case R.id.chapter_view_textSize_small: - demarkMenuItems(indentSpaces, 0, new TextSizeChange()); + demarkMenuItems(indentSpaces, 0, demarkActions[0]); return true; case R.id.chapter_view_textSize_medium: - demarkMenuItems(textSizes, 1, new TextSizeChange()); + demarkMenuItems(textSizes, 1, demarkActions[0]); return true; case R.id.chapter_view_textSize_large: - demarkMenuItems(textSizes, 2, new TextSizeChange()); + demarkMenuItems(textSizes, 2, demarkActions[0]); return true; case R.id.chapter_view_paragraphSpace_none: - demarkMenuItems(paragraphSpaces, 0, new ParaSpacingChange()); + demarkMenuItems(paragraphSpaces, 0, demarkActions[1]); return true; case R.id.chapter_view_paragraphSpace_small: - demarkMenuItems(paragraphSpaces, 1, new ParaSpacingChange()); + demarkMenuItems(paragraphSpaces, 1, demarkActions[1]); return true; case R.id.chapter_view_paragraphSpace_medium: - demarkMenuItems(paragraphSpaces, 2, new ParaSpacingChange()); + demarkMenuItems(paragraphSpaces, 2, demarkActions[1]); return true; case R.id.chapter_view_paragraphSpace_large: - demarkMenuItems(paragraphSpaces, 3, new ParaSpacingChange()); + demarkMenuItems(paragraphSpaces, 3, demarkActions[1]); return true; case R.id.chapter_view_indent_none: - demarkMenuItems(indentSpaces, 0, new IndentChange()); + demarkMenuItems(indentSpaces, 0, demarkActions[2]); return true; case R.id.chapter_view_indent_small: - demarkMenuItems(indentSpaces, 1, new IndentChange()); + demarkMenuItems(indentSpaces, 1, demarkActions[2]); return true; case R.id.chapter_view_indent_medium: - demarkMenuItems(indentSpaces, 2, new IndentChange()); + demarkMenuItems(indentSpaces, 2, demarkActions[2]); return true; case R.id.chapter_view_indent_large: - demarkMenuItems(indentSpaces, 3, new IndentChange()); + demarkMenuItems(indentSpaces, 3, demarkActions[2]); return true; case R.id.browser: @@ -309,10 +321,10 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { openInWebview(this, chapterURL); return true; case R.id.reader_0: - demarkMenuItems(readers, 0, new ReaderChange()); + demarkMenuItems(readers, 0, demarkActions[3]); return true; case R.id.reader_1: - demarkMenuItems(readers, 1, new ReaderChange()); + demarkMenuItems(readers, 1, demarkActions[3]); return true; } @@ -370,14 +382,16 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); + readerViewPager = findViewById(R.id.readerPager); + markdownView = findViewById(R.id.fragment_novel_chapter_view_markdown); + textView = findViewById(R.id.fragment_novel_chapter_view_text); + switch (readerType) { case 1: - markdownView = findViewById(R.id.fragment_novel_chapter_view_markdown); markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); break; case 0: case -1: - textView = findViewById(R.id.fragment_novel_chapter_view_text); textView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); break; case -2: @@ -455,6 +469,12 @@ public void setUpReader() { } } + private void setViewPager() { + ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getSupportFragmentManager(), fragments); + readerViewPager.setAdapter(pagerAdapter); + } + + /** * What to do when scroll hits bottom */ @@ -484,7 +504,6 @@ private void bottom() { } } - /** * Loads the chapter to be read */ @@ -546,39 +565,4 @@ private void addBottomListener() { } } - - private class TextSizeChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - int[] a = {14, 17, 20}; - setTextSize(a[spared]); - setUpReader(); - } - } - - private class ParaSpacingChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - changeParagraphSpacing(spared); - setUpReader(); - } - } - - private class IndentChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - changeIndentSize(spared); - setUpReader(); - } - } - - private class ReaderChange implements Utilities.DemarkAction { - @Override - public void action(int spared) { - readerType = spared; - setReaderType(novelID, spared); - setUpReader(); - } - } - } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ReaderTypeAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ReaderTypeAdapter.java new file mode 100644 index 0000000000..ba11ec4247 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ReaderTypeAdapter.java @@ -0,0 +1,32 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; + +import java.util.ArrayList; +import java.util.List; + +public class ReaderTypeAdapter extends FragmentPagerAdapter { + private final List fragments; + + public ReaderTypeAdapter(@NonNull FragmentManager fm, ArrayList fragments) { + super(fm, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + this.fragments = fragments; + + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragments.get(position); + } + + @Override + public int getCount() { + return fragments.size(); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java new file mode 100644 index 0000000000..73311bbd76 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java @@ -0,0 +1,20 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; + +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeIndentSize; + +public class IndentChange implements Utilities.DemarkAction { + private final ChapterReader chapterReader; + + public IndentChange(ChapterReader chapterReader) { + this.chapterReader = chapterReader; + } + + @Override + public void action(int spared) { + changeIndentSize(spared); + chapterReader.setUpReader(); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java new file mode 100644 index 0000000000..73b1ad2ebc --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java @@ -0,0 +1,21 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; + +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeParagraphSpacing; + +public class ParaSpacingChange implements Utilities.DemarkAction { + private final ChapterReader chapterReader; + + public ParaSpacingChange(ChapterReader chapterReader) { + this.chapterReader = chapterReader; + } + + @Override + public void action(int spared) { + changeParagraphSpacing(spared); + chapterReader. setUpReader(); + } + +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java new file mode 100644 index 0000000000..1e5a3e7177 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java @@ -0,0 +1,22 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; + +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; + +public class ReaderChange implements Utilities.DemarkAction { + private final ChapterReader chapterReader; + + public ReaderChange(ChapterReader chapterReader) { + this.chapterReader = chapterReader; + } + + @Override + public void action(int spared) { + chapterReader.readerType = spared; + setReaderType(chapterReader.novelID, spared); + chapterReader.setUpReader(); + } + +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java new file mode 100644 index 0000000000..f1e44cf23f --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java @@ -0,0 +1,22 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; + +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setTextSize; + +public class TextSizeChange implements Utilities.DemarkAction { + private final ChapterReader chapterReader; + + public TextSizeChange(ChapterReader chapterReader) { + this.chapterReader = chapterReader; + } + + + @Override + public void action(int spared) { + int[] a = {14, 17, 20}; + setTextSize(a[spared]); + chapterReader.setUpReader(); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java new file mode 100644 index 0000000000..bdaa9adde2 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -0,0 +1,24 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import org.jetbrains.annotations.NotNull; + +import us.feras.mdv.MarkdownView; + +public class MarkdownViewReader extends Reader { + MarkdownView markdownView; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void setText(@NotNull String text) { + markdownView.loadMarkdown(text); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java new file mode 100644 index 0000000000..5163c41cf0 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java @@ -0,0 +1,9 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; + +import androidx.fragment.app.Fragment; + +import org.jetbrains.annotations.NotNull; + +public abstract class Reader extends Fragment { + public abstract void setText(@NotNull String text); +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java new file mode 100644 index 0000000000..9a05665de1 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -0,0 +1,24 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; + +import android.os.Bundle; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import org.jetbrains.annotations.NotNull; + +public class TextViewReader extends Reader { + TextView textView; + + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void setText(@NotNull String text) { + textView.setText(text); + } +} diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml index cc07d7bb2d..22e438773b 100644 --- a/app/src/main/res/layout/chapter_reader_new.xml +++ b/app/src/main/res/layout/chapter_reader_new.xml @@ -17,7 +17,7 @@ From 7476480a3eb147f3688084963ff49e9af1565194 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 14 Nov 2019 19:26:38 -0500 Subject: [PATCH 062/162] Changed a header --- .../apps/shosetsu/ui/main/listener/NavigationSwapListener.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java index 4fe77fd556..31e8e42001 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/listener/NavigationSwapListener.java @@ -26,6 +26,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 18 / 06 / 2019 * From 560b9e226bc299c2fc0dd87682ec0e99de66c5f1 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 14 Nov 2019 19:44:07 -0500 Subject: [PATCH 063/162] Updated things --- app/build.gradle | 5 +++-- build.gradle | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 356fb8ea73..28e8ea7253 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,7 +30,7 @@ android { android.applicationVariants.all { variant -> variant.outputs.all { def appName = "shosetsu" - outputFileName = appName+"-${variant.versionName}.apk" + outputFileName = appName + "-${variant.versionName}.apk" } } android { @@ -54,6 +54,7 @@ dependencies { //noinspection GradleCompatible implementation 'com.google.android.material:material:1.2.0-alpha01' testImplementation 'junit:junit:4.13-rc-1' + testImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' @@ -78,7 +79,7 @@ dependencies { implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8' - implementation 'org.mozilla:rhino:1.7.10' + implementation 'org.mozilla:rhino:1.7.11' // TODO Implement readerview provided by Mozilla //implementation "org.mozilla.components:feature-readerview:1.0.0" diff --git a/build.gradle b/build.gradle index 8134fe7012..fbe43270e0 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.6.0-alpha09' - // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From b04bc4c3c94ed1be5aa7b2c98d1e40bf5e303021 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 14 Nov 2019 19:59:59 -0500 Subject: [PATCH 064/162] Refactoring things --- app/build.gradle | 1 + .../shosetsu/backend/Download_Manager.java | 12 +- .../apps/shosetsu/backend/Serialize.java | 15 +- .../apps/shosetsu/backend/Update_Manager.java | 6 +- .../apps/shosetsu/backend/Utilities.java | 33 ++- .../backend/WebviewCookieHandler.java | 7 +- .../shosetsu/backend/database/DBHelper.java | 6 +- .../shosetsu/backend/database/Database.java | 36 +++- .../backend/database/objects/base/Base.java | 3 + .../database/objects/base/BaseChapter.java | 3 + .../backend/scraper/WebViewScrapper.java | 10 +- .../scraper/WebViewScrapperClient.java | 6 +- .../backend/scraper/aria2/Cloudflare.java | 25 ++- .../shosetsu/backend/tracking/Trackers.java | 4 + .../ui/catalogue/CatalogueFragment.java | 5 +- .../ui/catalogue/CataloguesFragment.java | 3 +- .../catalogue/async/CataloguePageLoader.java | 7 +- .../catalogue/async/CatalogueQuerySearch.java | 3 + .../catalogue/async/NovelBackgroundAdd.java | 3 + .../listeners/CatalogueSearchQuery.java | 6 +- .../catalogue/viewHolder/CatalogueHolder.java | 4 +- .../ui/downloads/DownloadsFragment.java | 11 +- .../shosetsu/ui/library/LibraryFragment.java | 5 +- .../library/listener/LibrarySearchQuery.java | 4 +- .../viewHolders/LibraryViewHolder.java | 2 + .../apps/shosetsu/ui/main/MainActivity.java | 6 +- .../shosetsu/ui/migration/MigrationView.java | 6 +- .../MigrationViewCatalogueAdapter.java | 2 +- .../ui/migration/async/MigrationViewLoad.java | 8 +- .../shosetsu/ui/migration/async/Transfer.java | 4 + .../apps/shosetsu/ui/novel/NovelFragment.java | 10 +- .../ui/novel/adapters/NovelPagerAdapter.java | 7 +- .../ui/novel/async/ChapterLoader.java | 10 +- .../shosetsu/ui/novel/async/NovelLoader.java | 5 +- .../ui/novel/pages/NovelFragmentChapters.java | 6 +- .../shosetsu/ui/reader/ChapterReader.java | 9 +- .../ui/reader/async/ReaderViewLoader.java | 3 + .../subFragments/AdvancedSettings.java | 2 +- .../subFragments/DownloadSettings.java | 2 +- .../settings/subFragments/InfoSettings.java | 10 +- .../settings/subFragments/ViewSettings.java | 8 +- .../backup/async/BackupProcess.java | 6 +- .../backup/async/RestoreProcess.java | 9 +- .../viewHolder/SettingsCardViewHolder.java | 2 +- .../shosetsu/ui/updates/UpdateFragment.java | 1 + .../shosetsu/ui/updates/UpdatesFragment.java | 2 +- .../ui/updates/async/ChapterUpdater.java | 10 +- .../viewHolder/UpdatedChapterHolder.java | 2 +- .../shosetsu/variables/DefaultScrapers.java | 5 + .../apps/shosetsu/variables/DownloadItem.java | 7 + .../apps/shosetsu/variables/Settings.java | 3 + .../apps/shosetsu/variables/Statics.java | 2 + .../apps/shosetsu/variables/enums/Status.java | 4 + .../recycleObjects/CatalogueCard.java | 5 +- .../recycleObjects/CatalogueNovelCard.java | 2 +- .../variables/recycleObjects/NovelCard.java | 2 +- .../recycleObjects/SettingsItem.java | 1 + .../drawable-v24/ic_launcher_foreground.xml | 34 --- .../ic_arrow_drop_down_circle_black_24dp.xml | 9 - .../main/res/drawable/ic_error_black_24dp.xml | 9 - app/src/main/res/drawable/ic_folder.xml | 9 - .../res/drawable/ic_launcher_background.xml | 170 --------------- ...ic_outline_arrow_drop_down_circle_24px.xml | 9 - .../main/res/layout/chapter_reader_new.xml | 116 ---------- .../res/layout/fragment_catalogues_search.xml | 6 - app/src/main/res/layout/switch_item.xml | 10 - .../main/res/layout/updated_novel_card.xml | 53 ----- app/src/main/res/menu/toolbar_catalogue.xml | 6 - app/src/main/res/raw/disclaimer | 23 -- app/src/main/res/raw/license | 201 ------------------ app/src/main/res/values/colors.xml | 16 -- app/src/main/res/values/strings.xml | 11 - app/src/main/res/values/styles.xml | 14 -- .../apps/shosetsu/ExampleUnitTest.java | 3 +- 74 files changed, 289 insertions(+), 791 deletions(-) delete mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 app/src/main/res/drawable/ic_arrow_drop_down_circle_black_24dp.xml delete mode 100644 app/src/main/res/drawable/ic_error_black_24dp.xml delete mode 100644 app/src/main/res/drawable/ic_folder.xml delete mode 100644 app/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 app/src/main/res/drawable/ic_outline_arrow_drop_down_circle_24px.xml delete mode 100644 app/src/main/res/layout/chapter_reader_new.xml delete mode 100644 app/src/main/res/layout/fragment_catalogues_search.xml delete mode 100644 app/src/main/res/layout/switch_item.xml delete mode 100644 app/src/main/res/layout/updated_novel_card.xml delete mode 100644 app/src/main/res/menu/toolbar_catalogue.xml delete mode 100644 app/src/main/res/raw/disclaimer delete mode 100644 app/src/main/res/raw/license diff --git a/app/build.gradle b/app/build.gradle index 28e8ea7253..bde083d313 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,6 +80,7 @@ dependencies { implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8' implementation 'org.mozilla:rhino:1.7.11' + implementation 'androidx.annotation:annotation:1.1.0' // TODO Implement readerview provided by Mozilla //implementation "org.mozilla.components:feature-readerview:1.0.0" diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index ede3976c79..d15a0791a5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -5,6 +5,9 @@ import android.util.Log; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.downloads.DownloadsFragment; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; @@ -47,6 +50,7 @@ public class Download_Manager { + @NonNull private static Downloading download = new Downloading(); /** @@ -64,7 +68,7 @@ public static void init() { * * @param downloadItem download item to add */ - public static void addToDownload(DownloadItem downloadItem) { + public static void addToDownload(@NonNull DownloadItem downloadItem) { if (!Database.DatabaseDownloads.inDownloads(downloadItem)) { Database.DatabaseDownloads.addToDownloads(downloadItem); if (download.isCancelled()) @@ -82,7 +86,7 @@ public static void addToDownload(DownloadItem downloadItem) { * @param downloadItem download item to remove * @return if downloaded */ - public static boolean delete(Context context, DownloadItem downloadItem) { + public static boolean delete(@Nullable Context context, @NonNull DownloadItem downloadItem) { Log.d("DeletingChapter", downloadItem.toString()); File file = new File(shoDir + "/download/" + downloadItem.formatter.getID() + "/" + downloadItem.novelName + "/" + downloadItem.chapterName + ".txt"); Database.DatabaseChapter.removePath(downloadItem.chapterID); @@ -101,7 +105,8 @@ public static boolean delete(Context context, DownloadItem downloadItem) { * @param path path of saved chapter * @return Passage of saved chapter */ - public static String getText(String path) { + @Nullable + public static String getText(@NonNull String path) { try (BufferedReader br = new BufferedReader(new FileReader(path))) { StringBuilder sb = new StringBuilder(); String line = br.readLine(); @@ -126,6 +131,7 @@ public static String getText(String path) { */ static class Downloading extends AsyncTask { + @Nullable @Override protected Void doInBackground(Void... voids) { while (Database.DatabaseDownloads.getDownloadCount() >= 1 && !Settings.downloadPaused) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java index 58702a8e43..456221403e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Serialize.java @@ -1,5 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.backend; +import androidx.annotation.NonNull; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; @@ -50,7 +52,8 @@ public static void toggleDebug() { * @param object NovelPage or NovelChapter * @return Serialized JSON */ - public static String serializeOBJECT(Object object) throws Exception { + @NonNull + public static String serializeOBJECT(@NonNull Object object) throws Exception { if (object.getClass().equals(NovelChapter.class)) { NovelChapter novelChapter = (NovelChapter) object; return serializeToString(novelChapterToJSON(novelChapter).toString()); @@ -129,7 +132,8 @@ public static String serializeOBJECT(Object object) throws Exception { * @return NovelPage * @throws Exception If something goes wrong */ - public static NovelPage deserializeNovelPageJSON(String serial) throws Exception { + @NonNull + public static NovelPage deserializeNovelPageJSON(@NonNull String serial) throws Exception { NovelPage novelPage = new NovelPage(); JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); if (debug) @@ -235,7 +239,8 @@ public static NovelPage deserializeNovelPageJSON(String serial) throws Exception * @return NovelChapter * @throws Exception If something goes wrong */ - private static NovelChapter deserializeNovelChapterJSON(String serial) throws Exception { + @NonNull + private static NovelChapter deserializeNovelChapterJSON(@NonNull String serial) throws Exception { NovelChapter novelChapter = new NovelChapter(); JSONObject jsonObject = new JSONObject((String) deserializeString(serial)); for (String key : NOVELCHAPTERKEYS) { @@ -272,7 +277,8 @@ private static NovelChapter deserializeNovelChapterJSON(String serial) throws Ex * @throws IOException EXCEPTION * @throws JSONException EXCEPTION */ - private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws IOException, JSONException { + @NonNull + private static JSONObject novelChapterToJSON(@NonNull NovelChapter novelChapter) throws IOException, JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("release", serializeToString(novelChapter.release)); jsonObject.put("chapterNum", serializeToString(novelChapter.title)); @@ -287,6 +293,7 @@ private static JSONObject novelChapterToJSON(NovelChapter novelChapter) throws I * @throws JSONException EXCEPTION * @throws IOException EXCEPTION IN SERIALIZING */ + @NonNull public static JSONObject getSettingsInJSON() throws JSONException, IOException { JSONObject settings = new JSONObject(); settings.put("reader_text_color", Settings.ReaderTextColor); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java index b4ae81d2d0..59ceb91b6b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java @@ -3,6 +3,9 @@ import android.content.Context; import android.os.AsyncTask; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.ui.updates.async.ChapterUpdater; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; @@ -30,9 +33,10 @@ * @author github.com/doomsdayrs */ public class Update_Manager { + @Nullable private static ChapterUpdater chapterUpdater = null; - public static void init(ArrayList novelCards, Context context) { + public static void init(@NonNull ArrayList novelCards, @NonNull Context context) { if (chapterUpdater == null) { chapterUpdater = new ChapterUpdater(novelCards, context); chapterUpdater.execute(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 6f0a5bea7c..93178a848a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -13,6 +13,8 @@ import android.util.Log; import android.view.MenuItem; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; @@ -68,7 +70,7 @@ public class Utilities { * @param positionSpared Item to set checked * @param demarkAction Any action to proceed with */ - public static void demarkMenuItems(@NotNull MenuItem[] menuItems, int positionSpared, DemarkAction demarkAction) { + public static void demarkMenuItems(@NotNull MenuItem[] menuItems, int positionSpared, @Nullable DemarkAction demarkAction) { for (int x = 0; x < menuItems.length; x++) if (x != positionSpared) menuItems[x].setChecked(false); @@ -91,14 +93,16 @@ public interface DemarkAction { * @param input String to clean * @return string without specials */ - public static String cleanString(String input) { + @NonNull + public static String cleanString(@NonNull String input) { return input.replaceAll("[^A-Za-z0-9]", "_"); } public static final int SELECTED_STROKE_WIDTH = 8; + @Nullable public static String shoDir = "/Shosetsu/"; - public static int calculateNoOfColumns(Context context, float columnWidthDp) { // For example columnWidthdp=180 + public static int calculateNoOfColumns(@NonNull Context context, float columnWidthDp) { // For example columnWidthdp=180 DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density; return (int) (screenWidthDp / columnWidthDp + 0.5); @@ -111,6 +115,7 @@ public static int calculateNoOfColumns(Context context, float columnWidthDp) { / * @return Serialised string * @throws IOException exception */ + @NonNull public static String serializeToString(@NotNull Object object) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); @@ -127,6 +132,7 @@ public static String serializeToString(@NotNull Object object) throws IOExceptio * @throws IOException exception * @throws ClassNotFoundException exception */ + @Nullable public static Object deserializeString(@NotNull String string) throws IOException, ClassNotFoundException { if (!string.equals("null")) { string = string.substring(7); @@ -146,13 +152,14 @@ public static Object deserializeString(@NotNull String string) throws IOExceptio * @param string String to be checked * @return Completed String */ - public static String checkStringDeserialize(String string) { + @Nullable + public static String checkStringDeserialize(@Nullable String string) { if (string == null || string.isEmpty()) { return ""; } else { try { return (String) deserializeString(string); - } catch (IOException | ClassNotFoundException e) { + } catch (@NonNull IOException | ClassNotFoundException e) { e.printStackTrace(); } } @@ -166,7 +173,8 @@ public static String checkStringDeserialize(String string) { * @param string String to be checked * @return Completed String */ - public static String checkStringSerialize(String string) { + @NonNull + public static String checkStringSerialize(@Nullable String string) { if (string == null || string.isEmpty()) { return ""; } else { @@ -186,7 +194,8 @@ public static String checkStringSerialize(String string) { * @param s String title * @return Stati */ - public static Stati convertStringToStati(String s) { + @NonNull + public static Stati convertStringToStati(@NonNull String s) { switch (s) { case "Publishing": return Stati.PUBLISHING; @@ -207,6 +216,7 @@ public static Stati convertStringToStati(String s) { * @param a array of strings * @return String Array */ + @NonNull public static String convertArrayToString(@NotNull String[] a) { if (a != null && a.length != 0) { for (int x = 0; x < a.length; x++) { @@ -224,6 +234,7 @@ public static String convertArrayToString(@NotNull String[] a) { * @param s String array * @return Array of Strings */ + @NonNull public static String[] convertStringToArray(@NotNull String s) { String[] a = s.substring(1, s.length() - 1).split(", "); @@ -247,7 +258,7 @@ public static String[] convertStringToArray(@NotNull String s) { * * @param */ - public static void initPreferences(AppCompatActivity mainActivity) { + public static void initPreferences(@NonNull AppCompatActivity mainActivity) { Settings.ReaderTextColor = view.getInt("ReaderTextColor", Color.BLACK); Settings.ReaderTextBackgroundColor = view.getInt("ReaderBackgroundColor", Color.WHITE); String dir = mainActivity.getExternalFilesDir(null).getAbsolutePath(); @@ -292,7 +303,7 @@ public static void changeParagraphSpacing(int newSpacing) { } - public static void changeMode(Activity activity, int newMode) { + public static void changeMode(@NonNull Activity activity, int newMode) { if (!(newMode >= 0 && newMode <= 2)) throw new IndexOutOfBoundsException("Non valid int passed"); Settings.themeMode = newMode; @@ -426,11 +437,11 @@ public static void setTextSize(int size) { * @param novelID * @param formatterID */ - public static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID) { + public static void openChapter(@NonNull Activity activity, @NonNull NovelChapter novelChapter, int novelID, int formatterID) { openChapter(activity, novelChapter, novelID, formatterID, null); } - private static void openChapter(Activity activity, NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { + private static void openChapter(@NonNull Activity activity, @NonNull NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); Intent intent = new Intent(activity, ChapterReader.class); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java index cfe72bb713..0dc1200435 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/WebviewCookieHandler.java @@ -2,6 +2,8 @@ import android.webkit.CookieManager; +import androidx.annotation.NonNull; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -38,15 +40,16 @@ public final class WebviewCookieHandler implements CookieJar { private final CookieManager webviewCookieManager = CookieManager.getInstance(); @Override - public void saveFromResponse(HttpUrl url, List cookies) { + public void saveFromResponse(@NonNull HttpUrl url, @NonNull List cookies) { String urlString = url.toString(); for (Cookie cookie : cookies) { webviewCookieManager.setCookie(urlString, cookie.toString()); } } + @NonNull @Override - public List loadForRequest(HttpUrl url) { + public List loadForRequest(@NonNull HttpUrl url) { String urlString = url.toString(); String cookiesString = webviewCookieManager.getCookie(urlString); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java index 3d3d8873dc..434731f909 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/DBHelper.java @@ -4,6 +4,8 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import androidx.annotation.NonNull; + import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Tables; @@ -131,7 +133,7 @@ public DBHelper(Context context) { * @param db db to fill */ @Override - public void onCreate(SQLiteDatabase db) { + public void onCreate(@NonNull SQLiteDatabase db) { db.execSQL(NOVEL_IDENTIFICATION_CREATE); db.execSQL(CHAPTER_IDENTIFICATION_CREATE); db.execSQL(NOVELS); @@ -149,7 +151,7 @@ public void onCreate(SQLiteDatabase db) { * @param newVersion new version ID */ @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + public void onUpgrade(@NonNull SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 9) { //TODO Convert tables db.execSQL("DROP TABLE IF EXISTS " + Tables.CHAPTERS); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index c297b1393c..b3cce34a7b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -4,6 +4,9 @@ import android.database.sqlite.SQLiteDatabase; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; import com.github.doomsdayrs.apps.shosetsu.backend.Download_Manager; @@ -222,6 +225,7 @@ public static int getChapterIDFromChapterURL(String url) { * @param id ChapterID * @return ChapterURL */ + @Nullable public static String getChapterURLFromChapterID(int id) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.URL + " from " + Tables.CHAPTER_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); if (cursor.getCount() <= 0) { @@ -256,6 +260,7 @@ public static int getNovelIDFromChapterID(int id) { * @param id Chapter ID * @return Chapter URL */ + @Nullable static String getNovelURLFromChapterID(int id) { return getNovelURLfromNovelID(getNovelIDFromChapterID(id)); } @@ -264,6 +269,7 @@ static String getNovelURLFromChapterID(int id) { * @param url Chapter url * @return Novel URL */ + @Nullable public static String getNovelURLFromChapterURL(String url) { return getNovelURLFromChapterID(getChapterIDFromChapterURL(url)); } @@ -272,6 +278,7 @@ public static String getNovelURLFromChapterURL(String url) { * @param id NovelID * @return NovelURL */ + @Nullable public static String getNovelURLfromNovelID(int id) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.URL + " from " + Tables.NOVEL_IDENTIFICATION + " where " + Columns.ID + " = " + id + "", null); if (cursor.getCount() <= 0) { @@ -341,6 +348,7 @@ public static class DatabaseDownloads { * * @return DownloadItems to download */ + @NonNull public static List getDownloadList() { ArrayList downloadItems = new ArrayList<>(); Cursor cursor = sqLiteDatabase.rawQuery("SELECT * from " + Tables.DOWNLOADS + ";", null); @@ -361,6 +369,7 @@ public static List getDownloadList() { * * @return DownloadItem to download */ + @Nullable public static DownloadItem getFirstDownload() { Cursor cursor = sqLiteDatabase.rawQuery("SELECT * from " + Tables.DOWNLOADS + " LIMIT 1;", null); if (cursor.getCount() <= 0) { @@ -382,7 +391,7 @@ public static DownloadItem getFirstDownload() { * * @param downloadItem download item to remove */ - public static void removeDownload(DownloadItem downloadItem) { + public static void removeDownload(@NonNull DownloadItem downloadItem) { sqLiteDatabase.delete(Tables.DOWNLOADS.toString(), Columns.PARENT_ID + "=" + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null); } @@ -391,7 +400,7 @@ public static void removeDownload(DownloadItem downloadItem) { * * @param downloadItem Download item to add */ - public static void addToDownloads(DownloadItem downloadItem) { + public static void addToDownloads(@NonNull DownloadItem downloadItem) { sqLiteDatabase.execSQL("insert into " + Tables.DOWNLOADS + " (" + Columns.PARENT_ID + "," + Columns.NOVEL_NAME + "," + @@ -409,7 +418,7 @@ public static void addToDownloads(DownloadItem downloadItem) { * @param downloadItem download item to check * @return if is in list */ - public static boolean inDownloads(DownloadItem downloadItem) { + public static boolean inDownloads(@NonNull DownloadItem downloadItem) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.PARENT_ID + " from " + Tables.DOWNLOADS + " where " + Columns.PARENT_ID + " = " + DatabaseIdentification.getChapterIDFromChapterURL(downloadItem.chapterURL) + "", null); int a = cursor.getCount(); cursor.close(); @@ -493,6 +502,7 @@ public static int getY(int chapterID) { * @param chapterID chapter to check * @return returns chapter status */ + @NonNull public static Status getStatus(int chapterID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READ_CHAPTER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { @@ -535,7 +545,7 @@ public static void setBookMark(int chapterID, int b) { /** * is this chapter bookmarked? * - * @param chapterID + * @param chapterID id of chapter * @return if bookmarked? */ public static boolean isBookMarked(int chapterID) { @@ -605,6 +615,7 @@ public static boolean isSaved(int chapterID) { * @param chapterID novelURL of the chapter * @return String of passage */ + @Nullable public static String getSavedNovelPassage(int chapterID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.SAVE_PATH + " from " + Tables.CHAPTERS + " where " + Columns.ID + "=" + chapterID, null); if (cursor.getCount() <= 0) { @@ -638,7 +649,7 @@ public static boolean inChapters(String chapterURL) { * @param novelID ID of novel * @param novelChapter chapterURL */ - public static void addToChapters(int novelID, NovelChapter novelChapter) { + public static void addToChapters(int novelID, @NonNull NovelChapter novelChapter) { if (!hasChapter(novelChapter.link)) DatabaseIdentification.addChapter(novelID, novelChapter.link); @@ -678,6 +689,7 @@ public static void addToChapters(int novelID, NovelChapter novelChapter) { * @param novelID ID to retrieve from * @return List of chapters saved of novel */ + @Nullable public static List getChapters(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.TITLE + ", " + Columns.RELEASE_DATE + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { @@ -708,9 +720,10 @@ public static List getChapters(int novelID) { /** * Gets a chapter by it's URL * - * @param chapterID - * @return + * @param chapterID id of chapter + * @return NovelChapter of said chapter */ + @Nullable public static NovelChapter getChapter(int chapterID) { Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.TITLE + "," + Columns.ID + "," + Columns.RELEASE_DATE + "," + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); if (cursor.getCount() <= 0) { @@ -753,7 +766,6 @@ public static void bookMark(int novelID) { * UnBookmarks the novel * * @param novelID id - * @return if removed successfully */ public static void unBookmark(int novelID) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.BOOKMARKED + "=0 where " + Columns.PARENT_ID + "=" + novelID); @@ -876,6 +888,7 @@ public static boolean inDatabase(String novelURL) { * * @return the library */ + @NonNull public static ArrayList getLibrary() { Log.d("DL", "Getting"); Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), @@ -905,6 +918,7 @@ public static ArrayList getLibrary() { } } + @Nullable public static NovelCard getNovel(int novelID) { Log.d("DL", "Getting"); @@ -939,6 +953,7 @@ novelID, getNovelURLfromNovelID(novelID), * @param novelID novel to retrieve * @return Saved novelPage */ + @Nullable public static NovelPage getNovelPage(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.TITLE + "," + @@ -982,6 +997,7 @@ public static void setStatus(int novelID, @NotNull Status status) { sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READING_STATUS + "=" + status + " where " + Columns.PARENT_ID + "=" + novelID); } + @NonNull public static Status getStatus(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.READING_STATUS + " from " + Tables.NOVELS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { @@ -1033,7 +1049,8 @@ public static void migrateNovel(int oldID, String newURL, int formatterID, @NotN public static class DatabaseUpdates { - public static DateTime trimDate(DateTime date) { + @NonNull + public static DateTime trimDate(@NonNull DateTime date) { Calendar cal = Calendar.getInstance(); cal.clear(); // as per BalusC comment. cal.setTime(date.toDate()); @@ -1123,6 +1140,7 @@ public static int getCountBetween(long date1, long date2) throws Exception { * @param date1 first * @param date2 second */ + @NonNull public static ArrayList getTimeBetween(long date1, long date2) throws Exception { if (date2 <= date1) throw new Exception("Dates implemented wrongly"); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java index be5049dd56..2a483883d9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/Base.java @@ -1,5 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; +import androidx.annotation.NonNull; + import java.io.Serializable; /* @@ -29,6 +31,7 @@ NOVEL_URL = novel_url; } + @NonNull @Override public String toString() { return "Base{" + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java index 53ba8b64bf..e8bee712aa 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/objects/base/BaseChapter.java @@ -1,5 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.backend.database.objects.base; +import androidx.annotation.NonNull; + /* * This file is part of Shosetsu. * @@ -28,6 +30,7 @@ protected BaseChapter(String novel_url, String chapter_url) { CHAPTER_URL = chapter_url; } + @NonNull @Override public String toString() { return "BaseChapter{" + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index aa9f31dd39..fae07d7eb7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -20,6 +20,9 @@ import android.os.AsyncTask; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.CloudFlareCallback; import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.Cloudflare; @@ -84,7 +87,8 @@ public WebViewScrapper(WebView webView, Activity activity) { * @param url URL to retrieve; * @return Document of the URL */ - public static Document docFromURL(String url, boolean cloudflare) { + @Nullable + public static Document docFromURL(@Nullable String url, boolean cloudflare) { if (url != null) { Log.i("URL load", url); try { @@ -95,7 +99,7 @@ public static Document docFromURL(String url, boolean cloudflare) { } else { return Jsoup.connect(url).get(); } - } catch (IOException | InterruptedException | ExecutionException e) { + } catch (@NonNull IOException | InterruptedException | ExecutionException e) { e.printStackTrace(); } } @@ -103,9 +107,11 @@ public static Document docFromURL(String url, boolean cloudflare) { } static class GetCookies extends AsyncTask> { + @Nullable List cookies = null; int status = 0; + @Nullable @Override protected List doInBackground(Cloudflare... cf) { cf[0].getCookies(new CloudFlareCallback() { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java index 163e423f2b..6b1937e114 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapperClient.java @@ -21,6 +21,8 @@ import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.annotation.NonNull; + import java.util.concurrent.TimeUnit; /** @@ -37,12 +39,12 @@ class WebViewScrapperClient extends WebViewClient { } @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { + public boolean shouldOverrideUrlLoading(@NonNull WebView view, String url) { view.loadUrl(url); return false; } - public void onPageFinished(WebView view, String url) { + public void onPageFinished(@NonNull WebView view, String url) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java index d1028a5b69..c4e6fc5118 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java @@ -5,6 +5,9 @@ import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import org.mozilla.javascript.Context; import org.mozilla.javascript.Scriptable; @@ -30,6 +33,7 @@ /** * author: zhkrb @ https://github.com/zhkrb */ +@SuppressWarnings("JavaDoc") public class Cloudflare { private static final int MAX_COUNT = 3; @@ -62,7 +66,8 @@ public Cloudflare(String url, String user_agent) { * @param list * @return */ - private static String listToString(List list) { + @NonNull + private static String listToString(@NonNull List list) { char separator = ";".charAt(0); StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.size(); i++) { @@ -77,7 +82,8 @@ private static String listToString(List list) { * @param list HttpCookie列表 * @return Hashmap */ - public static Map List2Map(List list) { + @NonNull + public static Map List2Map(@Nullable List list) { Map map = new HashMap<>(); try { if (list != null) { @@ -109,7 +115,7 @@ public void getCookies(final CloudFlareCallback callback) { new Thread(() -> urlThread(callback)).start(); } - private void urlThread(CloudFlareCallback callback) { + private void urlThread(@Nullable CloudFlareCallback callback) { mCookieManager = new CookieManager(); mCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); //接受所有cookies CookieHandler.setDefault(mCookieManager); @@ -128,7 +134,7 @@ private void urlThread(CloudFlareCallback callback) { } else { getVisiteCookie(); } - } catch (IOException | InterruptedException e) { + } catch (@NonNull IOException | InterruptedException e) { if (mCookieList != null) { mCookieList.clear(); } @@ -199,7 +205,7 @@ private void getVisiteCookie() throws IOException, InterruptedException { * * @param str */ - private void getCheckAnswer(String str) throws InterruptedException, IOException { + private void getCheckAnswer(@NonNull String str) throws InterruptedException, IOException { String s = regex(str, "name=\"s\" value=\"(.+?)\"").get(0); //正则取值 String jschl_vc = regex(str, "name=\"jschl_vc\" value=\"(.+?)\"").get(0); String pass = regex(str, "name=\"pass\" value=\"(.+?)\"").get(0); // @@ -274,7 +280,7 @@ private void closeAllConn() { } } - private double get_answer(String str) { //取值 + private double get_answer(@NonNull String str) { //取值 double a = 0; try { @@ -327,7 +333,8 @@ private double get_answer(String str) { //取值 * @param pattern 正则式 * @return List */ - private List regex(String text, String pattern) { + @Nullable + private List regex(@NonNull String text, @NonNull String pattern) { try { Pattern pt = Pattern.compile(pattern); Matcher mt = pt.matcher(text); @@ -348,11 +355,11 @@ private List regex(String text, String pattern) { return null; } - private void e(String tag, String content) { + private void e(String tag, @NonNull String content) { Log.e(tag, content); } - private void e(String content) { + private void e(@NonNull String content) { Log.e("cloudflare", content); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Trackers.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Trackers.java index 91ec98107a..09eaeed9cf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Trackers.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/tracking/Trackers.java @@ -2,6 +2,8 @@ import android.content.res.Resources; +import androidx.annotation.NonNull; + import com.github.doomsdayrs.apps.shosetsu.R; /* @@ -37,6 +39,7 @@ public enum Trackers { this.id = id; } + @NonNull private static String getString(int id) { return Resources.getSystem().getString(id); } @@ -45,6 +48,7 @@ public int getId() { return id; } + @NonNull @Override public String toString() { return "Trackers{" + diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java index a09cb33aaa..502cbb1691 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java @@ -65,7 +65,9 @@ */ //TODO fix issue with not loading public class CatalogueFragment extends Fragment { + @NonNull public ArrayList catalogueNovelCards = new ArrayList<>(); + @Nullable public Formatter formatter; public SwipeRefreshLayout swipeRefreshLayout; public RecyclerView library_view; @@ -73,6 +75,7 @@ public class CatalogueFragment extends Fragment { public boolean isInSearch = false; private Context context; + @Nullable public CatalogueAdapter catalogueAdapter; public ProgressBar bottomProgressBar; @@ -192,7 +195,7 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d } @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { menu.clear(); inflater.inflate(R.menu.toolbar_library, menu); SearchView searchView = (SearchView) menu.findItem(R.id.library_search).getActionView(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java index 5350864dd3..d583f7814f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java @@ -49,6 +49,7 @@ */ //TODO Searching mechanics here public class CataloguesFragment extends Fragment { + @Nullable private ArrayList cards = null; /** @@ -59,7 +60,7 @@ public CataloguesFragment() { } @Override - public void onCreateOptionsMenu(@NotNull Menu menu, MenuInflater inflater) { + public void onCreateOptionsMenu(@NotNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.toolbar_catalogues, menu); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java index c3f64b828b..afbd44b0ac 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CataloguePageLoader.java @@ -5,6 +5,9 @@ import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; @@ -41,6 +44,7 @@ public class CataloguePageLoader extends AsyncTask { // References to objects private final CatalogueFragment catalogueFragment; + @Nullable private final CatalogueHitBottom catalogueHitBottom; /** @@ -68,8 +72,9 @@ public CataloguePageLoader(CatalogueFragment catalogueFragment, CatalogueHitBott * @param integers if length = 0, loads first page otherwise loads the page # correlated to the integer * @return if this was completed or not */ + @NonNull @Override - protected Boolean doInBackground(Integer... integers) { + protected Boolean doInBackground(@NonNull Integer... integers) { Log.d("Loading", "Catalogue"); catalogueFragment.library_view.post(() -> catalogueFragment.errorView.setVisibility(View.GONE)); if (catalogueFragment.formatter.hasCloudFlare()) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java index ad9e90cf8e..718f510e49 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/CatalogueQuerySearch.java @@ -2,6 +2,8 @@ import android.os.AsyncTask; +import androidx.annotation.NonNull; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; @@ -46,6 +48,7 @@ public CatalogueQuerySearch(CatalogueFragment catalogueFragment) { * @param strings ignored * @return List of results */ + @NonNull @Override protected ArrayList doInBackground(String... strings) { ArrayList result = new ArrayList<>(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java index 05e2f529cf..e4f57d884d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/async/NovelBackgroundAdd.java @@ -5,6 +5,8 @@ import android.view.View; import android.widget.Toast; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.viewHolder.NovelCardViewHolder; @@ -38,6 +40,7 @@ public NovelBackgroundAdd(NovelCardViewHolder novelCardsViewHolder) { this.novelCardsViewHolder = novelCardsViewHolder; } + @Nullable @Override protected Void doInBackground(View... views) { try { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java index 63de35e18e..b46560d6e1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/listeners/CatalogueSearchQuery.java @@ -4,6 +4,8 @@ import android.util.Log; import android.widget.SearchView; +import androidx.annotation.NonNull; + import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.CatalogueFragment; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.async.CatalogueQuerySearch; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; @@ -47,14 +49,14 @@ public boolean onQueryTextSubmit(String query) { ArrayList searchResults = new CatalogueQuerySearch(catalogueFragment).execute(query).get(); catalogueFragment.setLibraryCards(searchResults); return true; - } catch (ExecutionException | InterruptedException e) { + } catch (@NonNull ExecutionException | InterruptedException e) { e.printStackTrace(); } return false; } @Override - public boolean onQueryTextChange(String newText) { + public boolean onQueryTextChange(@NonNull String newText) { Log.d("Library search", newText); catalogueFragment.isQuery = true; ArrayList recycleCards = new ArrayList<>(catalogueFragment.catalogueNovelCards); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java index 5440425be8..44ded1a03c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/viewHolder/CatalogueHolder.java @@ -52,14 +52,14 @@ public CatalogueHolder(@NonNull View itemView, FragmentManager fragmentManager) this.fragmentManager = fragmentManager; } - public void setFormatter(Formatter formatter) { + public void setFormatter(@NonNull Formatter formatter) { this.formatter = formatter; Log.d("FormatterSet", formatter.getName()); itemView.setOnClickListener(this); } @Override - public void onClick(View v) { + public void onClick(@NonNull View v) { Log.d("FormatterSelection", formatter.getName()); if (isOnline()) { CatalogueFragment catalogueFragment = new CatalogueFragment(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java index b2bae93ec6..e9b6676268 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java @@ -54,11 +54,14 @@ */ //TODO selection mechanic with options to delete, pause, and more public class DownloadsFragment extends Fragment { + @NonNull public static List downloadItems = new ArrayList<>(); + @Nullable @SuppressLint("StaticFieldLeak") private static RecyclerView recyclerView; + @Nullable private static DownloadAdapter adapter; /** @@ -76,7 +79,7 @@ private static void refreshList() { DownloadsFragment.adapter.downloadsFragment.getActivity().runOnUiThread(() -> adapter.notifyDataSetChanged()); } - public static void removeDownloads(DownloadItem downloadItem) { + public static void removeDownloads(@NonNull DownloadItem downloadItem) { for (int x = 0; x < downloadItems.size(); x++) if (downloadItems.get(x).chapterURL.equals(downloadItem.chapterURL)) { downloadItems.remove(x); @@ -86,14 +89,14 @@ public static void removeDownloads(DownloadItem downloadItem) { refreshList(); } - public static void markError(DownloadItem d) { + public static void markError(@NonNull DownloadItem d) { for (DownloadItem downloadItem : downloadItems) if (downloadItem.chapterURL.equals(d.chapterURL)) d.setStatus("Error"); refreshList(); } - public static void toggleProcess(DownloadItem d) { + public static void toggleProcess(@NonNull DownloadItem d) { for (DownloadItem downloadItem : downloadItems) if (downloadItem.chapterURL.equals(d.chapterURL)) if (downloadItem.getStatus().equals("Pending") || downloadItem.getStatus().equals("Error")) @@ -165,7 +168,7 @@ private void setDownloads() { * @param inflater Object to inflate the menu */ @Override - public void onCreateOptionsMenu(@NotNull Menu menu, MenuInflater inflater) { + public void onCreateOptionsMenu(@NotNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.toolbar_downloads, menu); MenuItem menuItem = menu.findItem(R.id.toolbar_downloads_pause); if (Settings.downloadPaused) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 33f0bac760..81db759d39 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -59,12 +59,14 @@ * @author github.com/doomsdayrs */ public class LibraryFragment extends Fragment { + @NonNull public ArrayList libraryNovelCards = new ArrayList<>(); + @Nullable public ArrayList selectedNovels = new ArrayList<>(); public static boolean changedData = false; - public boolean contains(NovelCard novelCard) { + public boolean contains(@NonNull NovelCard novelCard) { for (NovelCard n : selectedNovels) if (n.novelURL.equalsIgnoreCase(novelCard.novelURL)) return true; @@ -123,6 +125,7 @@ public void setLibraryCards(ArrayList novelCards) { } } + @Nullable public MenuInflater getInflater() { return new MenuInflater(getContext()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java index f2f0705db0..f5a813da69 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java @@ -4,6 +4,8 @@ import android.util.Log; import android.widget.SearchView; +import androidx.annotation.NonNull; + import com.github.doomsdayrs.apps.shosetsu.ui.library.LibraryFragment; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; @@ -43,7 +45,7 @@ public boolean onQueryTextSubmit(String query) { } @Override - public boolean onQueryTextChange(String newText) { + public boolean onQueryTextChange(@NonNull String newText) { Log.d("Library search", newText); ArrayList recycleCards = new ArrayList<>(libraryFragment.libraryNovelCards); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java index 69d15b8134..3803071107 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java @@ -26,6 +26,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; @@ -43,6 +44,7 @@ public class LibraryViewHolder extends RecyclerView.ViewHolder implements View.O public final Chip chip; public LibraryFragment libraryFragment; + @Nullable public Formatter formatter; public NovelCard novelCard; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index d30df01bc4..e909b3e3b5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -8,6 +8,8 @@ import android.util.Log; import android.webkit.WebView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -77,7 +79,7 @@ public class MainActivity extends AppCompatActivity { * @param savedInstanceState savedData from destruction */ @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); @@ -137,7 +139,7 @@ protected void onCreate(Bundle savedInstanceState) { .setUpdateFrom(UpdateFrom.XML).setUpdateXML("https://raw.githubusercontent.com/Doomsdayrs/shosetsu/master/app/update.xml") .withListener(new AppUpdaterUtils.UpdateListener() { @Override - public void onSuccess(Update update, Boolean isUpdateAvailable) { + public void onSuccess(@NonNull Update update, Boolean isUpdateAvailable) { Log.d("Latest Version", String.valueOf(isUpdateAvailable)); Log.d("Latest Version", update.getLatestVersion()); Log.d("Latest Version", String.valueOf(update.getLatestVersionCode())); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java index db987a4021..fe6fb913ec 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/MigrationView.java @@ -29,6 +29,7 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.constraintlayout.widget.ConstraintLayout; @@ -54,9 +55,11 @@ public class MigrationView extends AppCompatActivity { public final ArrayList> novelResults = new ArrayList<>(); + @Nullable private ArrayList catalogues = null; + @Nullable public ArrayList novels = new ArrayList<>(); private final ArrayList confirmedMappings = new ArrayList<>(); private Transfer t; @@ -82,6 +85,7 @@ public class MigrationView extends AppCompatActivity { private Button confirm; + @Nullable private MigrationViewLoad load = null; public MigrationView() { @@ -102,7 +106,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Intent intent = getIntent(); try { novels = (ArrayList) deserializeString(intent.getStringExtra("selected")); - } catch (IOException | ClassNotFoundException e) { + } catch (@NonNull IOException | ClassNotFoundException e) { e.printStackTrace(); } setContentView(R.layout.migrate_source_view); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java index b61cb7ef9a..cefa078cf0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/adapters/MigrationViewCatalogueAdapter.java @@ -99,7 +99,7 @@ void setFormatter(Formatter formatter) { } @Override - public void onClick(View v) { + public void onClick(@NonNull View v) { Log.d("FormatterSelection", formatter.getName()); if (isOnline()) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java index 1550ee01e5..2399c6da0a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/MigrationViewLoad.java @@ -4,6 +4,9 @@ import android.os.AsyncTask; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Novel; import com.github.doomsdayrs.apps.shosetsu.ui.migration.MigrationView; @@ -36,15 +39,18 @@ */ public class MigrationViewLoad extends AsyncTask { + @NonNull @SuppressLint("StaticFieldLeak") private final MigrationView migrationView; + @Nullable private final Formatter targetFormat; - public MigrationViewLoad(MigrationView migrationView) { + public MigrationViewLoad(@NonNull MigrationView migrationView) { this.migrationView = migrationView; this.targetFormat = DefaultScrapers.getByID(migrationView.target); } + @Nullable @Override protected Void doInBackground(Void... voids) { Log.d("Searching with", targetFormat.getName()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java index c6aef0341e..9f10b7273b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/migration/async/Transfer.java @@ -5,6 +5,8 @@ import android.util.Log; import android.view.View; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; @@ -43,6 +45,7 @@ */ public class Transfer extends AsyncTask { private final ArrayList strings; + @Nullable private final Formatter formatter; @SuppressLint("StaticFieldLeak") private final MigrationView migrationView; @@ -73,6 +76,7 @@ protected void onPreExecute() { migrationView.pageCount.setVisibility(View.VISIBLE); } + @Nullable @Override protected Void doInBackground(Void... voids) { for (String[] strings : strings) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index bb19aa7fb7..9b71c580f3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -60,11 +60,16 @@ public class NovelFragment extends Fragment { public int novelID; + @Nullable public String novelURL; + @Nullable public NovelPage novelPage; + @Nullable public Formatter formatter; + @NonNull public Status status = Status.UNREAD; + @Nullable public List novelChapters = new ArrayList<>(); @@ -72,7 +77,8 @@ public class NovelFragment extends Fragment { * @param chapterURL Current chapter URL * @return chapter after the input, returns the current chapter if no more */ - public static NovelChapter getNextChapter(@NotNull String chapterURL, String[] novelChapters) { + @Nullable + public static NovelChapter getNextChapter(@NotNull String chapterURL, @Nullable String[] novelChapters) { if (novelChapters != null && novelChapters.length != 0) for (int x = 0; x < novelChapters.length; x++) { if (novelChapters[x].equalsIgnoreCase(chapterURL)) { @@ -214,7 +220,7 @@ private void setViewPager() { viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override - public void onTabSelected(TabLayout.Tab tab) { + public void onTabSelected(@NonNull TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/NovelPagerAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/NovelPagerAdapter.java index e70fceef38..85886b013d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/NovelPagerAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/NovelPagerAdapter.java @@ -2,6 +2,7 @@ import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -32,20 +33,22 @@ */ public class NovelPagerAdapter extends FragmentPagerAdapter { private final List fragments; + @NonNull private String[] titles = {"Info", "Chapters"}; - public NovelPagerAdapter(FragmentManager fm, List fragments) { + public NovelPagerAdapter(@NonNull FragmentManager fm, List fragments) { super(fm); this.fragments = fragments; } //TODO with tracker use this instead the of the above - public NovelPagerAdapter(FragmentManager fm, List fragments, boolean ignored) { + public NovelPagerAdapter(@NonNull FragmentManager fm, List fragments, boolean ignored) { super(fm); this.fragments = fragments; titles = new String[]{titles[0], titles[1], "Tracker"}; } + @NonNull @Override public Fragment getItem(int i) { Log.d("SwapScreen", fragments.get(i).toString()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index a6de467c9e..816e140024 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -5,6 +5,9 @@ import android.util.Log; import android.view.View; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; @@ -42,6 +45,7 @@ * This task loads a novel for the novel fragment */ public class ChapterLoader extends AsyncTask { + @Nullable private NovelPage novelPage; private final String novelURL; private final Formatter formatter; @@ -57,13 +61,14 @@ public ChapterLoader(NovelPage novelPage, String novelURL, Formatter formatter) this.formatter = formatter; } - private ChapterLoader(ChapterLoader chapterLoader) { + private ChapterLoader(@NonNull ChapterLoader chapterLoader) { this.novelPage = chapterLoader.novelPage; this.novelURL = chapterLoader.novelURL; this.formatter = chapterLoader.formatter; this.novelFragmentChapters = chapterLoader.novelFragmentChapters; } + @NonNull public ChapterLoader setNovelFragmentChapters(NovelFragmentChapters novelFragmentChapters) { this.novelFragmentChapters = novelFragmentChapters; return this; @@ -75,6 +80,7 @@ public ChapterLoader setNovelFragmentChapters(NovelFragmentChapters novelFragmen * @param voids activity to work with * @return if completed */ + @NonNull @Override protected Boolean doInBackground(Activity... voids) { Activity activity = voids[0]; @@ -123,7 +129,7 @@ protected Boolean doInBackground(Activity... voids) { return false; } - private void add(Activity activity, int mangaCount, NovelChapter novelChapter) { + private void add(@NonNull Activity activity, int mangaCount, @NonNull NovelChapter novelChapter) { //TODO The getNovelID in this method likely will cause slowdowns due to IO if (!activity.isDestroyed() && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 6f06b5f74c..79032f39d6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -4,6 +4,8 @@ import android.util.Log; import android.view.View; +import androidx.annotation.NonNull; + import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; @@ -61,7 +63,7 @@ public NovelLoader(NovelFragment novelFragment, ErrorView errorView, boolean loa } - private NovelLoader(NovelLoader novelLoader) { + private NovelLoader(@NonNull NovelLoader novelLoader) { this.novelFragment = novelLoader.novelFragment; this.loadAll = novelLoader.loadAll; this.errorView = novelLoader.errorView; @@ -79,6 +81,7 @@ protected void onPreExecute() { * @param voids voided * @return if completed */ + @NonNull @Override protected Boolean doInBackground(Void... voids) { Log.d("Loading", String.valueOf(novelFragment.novelURL)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 0bff0eb885..aaf4e41ba2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -66,9 +66,10 @@ */ public class NovelFragmentChapters extends Fragment { + @NonNull public ArrayList selectedChapters = new ArrayList<>(); - public boolean contains(NovelChapter novelChapter) { + public boolean contains(@NonNull NovelChapter novelChapter) { for (NovelChapter n : selectedChapters) if (n.link.equalsIgnoreCase(novelChapter.link)) return true; @@ -87,6 +88,7 @@ private int findMinPosition() { } public static boolean reversed; + @Nullable @SuppressLint("StaticFieldLeak") public static RecyclerView recyclerView; @@ -99,6 +101,7 @@ private int findMaxPosition() { return max; } + @Nullable public static ChaptersAdapter adapter; public SwipeRefreshLayout swipeRefreshLayout; public NovelFragment novelFragment; @@ -198,6 +201,7 @@ public void setChapters() { public Menu menu; + @Nullable public MenuInflater getInflater() { return new MenuInflater(getContext()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 1fd80c57df..bfd0061be1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -13,6 +13,7 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -104,7 +105,9 @@ public class ChapterReader extends AppCompatActivity { public ProgressBar progressBar; + @Nullable public String title; + @Nullable public Formatter formatter; public int chapterID; @@ -113,7 +116,9 @@ public class ChapterReader extends AppCompatActivity { private TextView textView; private MarkdownView markdownView; + @Nullable public String chapterURL; + @Nullable public String unformattedText = null; public int readerType; @@ -123,7 +128,9 @@ public class ChapterReader extends AppCompatActivity { private MenuItem tap_to_scroll; private Chip nextChapter; public int novelID; + @Nullable private String[] chapters; + @Nullable private String text = null; @@ -161,7 +168,7 @@ protected void onSaveInstanceState(@NotNull Bundle outState) { * @return if made */ @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(@NonNull Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.toolbar_chapter_view, menu); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index b1668195e4..a4edea2973 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -4,6 +4,8 @@ import android.os.AsyncTask; import android.view.View; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; @@ -45,6 +47,7 @@ public ReaderViewLoader(ChapterReader chapterReader) { this.chapterReader = chapterReader; } + @Nullable @Override protected String doInBackground(ChapterReader... chapterReaders) { chapterReader.runOnUiThread(() -> chapterReader.errorView.setVisibility(View.GONE)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/AdvancedSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/AdvancedSettings.java index c75c5ca288..c4cc436db0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/AdvancedSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/AdvancedSettings.java @@ -71,7 +71,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + public void onItemSelected(@NonNull AdapterView adapterView, View view, int i, long l) { if (i >= 0 && i <= 2) { changeMode(getActivity(), i); adapterView.setSelection(i); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java index 80c517a017..cdf53429fd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java @@ -74,7 +74,7 @@ private void performFileSearch() { } @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 42 && resultCode == Activity.RESULT_OK) { if (data != null) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java index a9889b4d82..c609527d29 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/InfoSettings.java @@ -40,31 +40,31 @@ public class InfoSettings extends Fragment { - private void onClickAppVer(View v) { + private void onClickAppVer(@NonNull View v) { // TODO: Add the app version number after consultation Toast.makeText(v.getContext(), "AppVer", Toast.LENGTH_SHORT).show(); } - private void onClickReportBug(View v) { + private void onClickReportBug(@NonNull View v) { Toast.makeText(v.getContext(), "ReportBug", Toast.LENGTH_SHORT).show(); String bugReportLink = getString(R.string.report_bug_link); Intent bugReportingIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(bugReportLink)); startActivity(bugReportingIntent); } - private void onClickAuthor(View v) { + private void onClickAuthor(@NonNull View v) { Toast.makeText(v.getContext(), "Author", Toast.LENGTH_SHORT).show(); String authorGitHubLink = getString(R.string.author_github); Intent authorGitHubIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authorGitHubLink)); startActivity(authorGitHubIntent); } - private void onClickDisclaimer(View v) { + private void onClickDisclaimer(@NonNull View v) { // TODO: Show full disclaimer on click Toast.makeText(v.getContext(), "Disclaimer", Toast.LENGTH_SHORT).show(); } - private void onClickLicense(View v) { + private void onClickLicense(@NonNull View v) { // TODO: Show full license on click Toast.makeText(v.getContext(), "License", Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java index 1cf5b51b1f..3688dd311d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/ViewSettings.java @@ -80,7 +80,7 @@ public class ViewSettings extends Fragment { private Switch tap_to_scroll; //TODO remove this abomination of code. We just need to make a simple old switch - private void onClickNIghtMode(View v) { + private void onClickNIghtMode(@NonNull View v) { if (this.getContext() != null) { SettingsItem nightMOdeItem = new SettingsItem(v); AlertDialog.Builder builder = new AlertDialog.Builder(this.getContext()); @@ -168,7 +168,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c textSize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void onItemSelected(AdapterView adapterView, android.view.View view, int i, long l) { + public void onItemSelected(@NonNull AdapterView adapterView, android.view.View view, int i, long l) { if (i >= 0 && i <= 2) { int size = 14; switch (i) { @@ -214,7 +214,7 @@ public void onNothingSelected(AdapterView adapterView) { paragraphSpacing.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void onItemSelected(AdapterView adapterView, android.view.View view, int i, long l) { + public void onItemSelected(@NonNull AdapterView adapterView, android.view.View view, int i, long l) { if (i >= 0 && i <= 3) { changeParagraphSpacing(i); adapterView.setSelection(i); @@ -252,7 +252,7 @@ public void onNothingSelected(AdapterView adapterView) { indentSize.setAdapter(dataAdapter); indentSize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void onItemSelected(AdapterView adapterView, android.view.View view, int i, long l) { + public void onItemSelected(@NonNull AdapterView adapterView, android.view.View view, int i, long l) { if (i >= 0 && i <= 3) { changeIndentSize(i); adapterView.setSelection(i); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java index ee21197e36..18ac50c513 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/BackupProcess.java @@ -23,6 +23,9 @@ import android.os.AsyncTask; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.doomsdayrs.apps.shosetsu.backend.Serialize; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels; @@ -70,6 +73,7 @@ protected void onPostExecute(Void aVoid) { Log.i("Progress", "Finished backup"); } + @Nullable @Override protected Void doInBackground(Void... voids) { try { @@ -165,7 +169,7 @@ protected Void doInBackground(Void... voids) { ); fileOutputStream.write(("JSON+-=" + BACKUP.toString()).getBytes()); fileOutputStream.close(); - } catch (IOException | JSONException e) { + } catch (@NonNull IOException | JSONException e) { e.printStackTrace(); } return null; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java index 787c100c61..dc62833f6e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/backup/async/RestoreProcess.java @@ -28,6 +28,8 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; + import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database.Columns; @@ -58,6 +60,7 @@ public class RestoreProcess extends AsyncTask { private final String file_path; + @NonNull @SuppressLint("StaticFieldLeak") private final Context context; @@ -74,9 +77,10 @@ public class RestoreProcess extends AsyncTask { private final TextView textView; + @NonNull private final Dialog dialog; - public RestoreProcess(String file_path, Context context) { + public RestoreProcess(String file_path, @NonNull Context context) { this.file_path = file_path; this.context = context; @@ -107,6 +111,7 @@ protected void onPostExecute(Boolean b) { } } + @NonNull @SuppressLint("SetTextI18n") @Override protected Boolean doInBackground(Void... voids) { @@ -247,7 +252,7 @@ protected Boolean doInBackground(Void... voids) { //TODO Settings progressBar.post(() -> progressBar.incrementProgressBy(1)); return true; - } catch (IOException | JSONException e) { + } catch (@NonNull IOException | JSONException e) { e.printStackTrace(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java index aee4324969..7ff48ada0c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/viewHolder/SettingsCardViewHolder.java @@ -45,7 +45,7 @@ public SettingsCardViewHolder(@NonNull View itemView, FragmentManager fragmentMa this.fragmentManager = fragmentManager; } - public void setType(Types type) { + public void setType(@NonNull Types type) { cardView.setOnClickListener(new OnSettingsCardClick(type, fragmentManager)); library_card_title.setText(type.toString()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java index a0924ce7c2..b0188002d6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdateFragment.java @@ -47,6 +47,7 @@ public class UpdateFragment extends Fragment { public long date = -1; private final ArrayList novels = new ArrayList<>(); + @NonNull private ArrayList updates = new ArrayList<>(); private RecyclerView recyclerView; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java index 220bdfcfc2..5b5cc61032 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java @@ -131,7 +131,7 @@ private void setViewPager() { viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override - public void onTabSelected(TabLayout.Tab tab) { + public void onTabSelected(@NonNull TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java index f0d9f723b2..fc022f251a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java @@ -7,6 +7,9 @@ import android.os.AsyncTask; import android.os.Build; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelPage; @@ -48,15 +51,17 @@ public class ChapterUpdater extends AsyncTask { private static final int ID = 1917; private static final String channel_ID = "shosetsu_updater"; + @NonNull private final ArrayList novelCards; private boolean continueProcesss = true; + @Nullable private final NotificationManager notificationManager; private Notification.Builder builder; private final ArrayList updatedNovels = new ArrayList<>(); - public ChapterUpdater(@NotNull ArrayList novelCards, Context context) { + public ChapterUpdater(@NotNull ArrayList novelCards, @NonNull Context context) { this.novelCards = novelCards; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); @@ -85,6 +90,7 @@ protected void onPreExecute() { notificationManager.notify(ID, builder.build()); } + @Nullable @Override protected Void doInBackground(Void... voids) { for (int x = 0; x < novelCards.size(); x++) { @@ -137,7 +143,7 @@ protected void onPostExecute(Void aVoid) { } - private void add(int mangaCount, NovelChapter novelChapter, NovelCard novelCard) { + private void add(int mangaCount, @NonNull NovelChapter novelChapter, @NonNull NovelCard novelCard) { if (continueProcesss && !Database.DatabaseChapter.inChapters(novelChapter.link)) { mangaCount++; System.out.println("Adding #" + mangaCount + ": " + novelChapter.link); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java index 7955e6ccbe..8a9ca683ac 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/viewHolder/UpdatedChapterHolder.java @@ -68,7 +68,7 @@ public UpdatedChapterHolder(@NonNull View itemView) { } - public void setNovelChapter(NovelChapter novelChapter) { + public void setNovelChapter(@NonNull NovelChapter novelChapter) { this.novelChapter = novelChapter; title.setText(novelChapter.title); //TODO fix this disgust diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java index ad276b764e..56f1213e13 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DefaultScrapers.java @@ -1,5 +1,8 @@ package com.github.doomsdayrs.apps.shosetsu.variables; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.extensions.lang.en.bestlightnovel.BestLightNovel; import com.github.Doomsdayrs.api.shosetsu.extensions.lang.en.box_novel.BoxNovel; import com.github.Doomsdayrs.api.shosetsu.extensions.lang.en.novel_full.NovelFull; @@ -57,6 +60,7 @@ public enum DefaultScrapers implements Formatter { private static final ArrayList formatters = new ArrayList<>(); + @Nullable public static Formatter getByID(int ID) { for (Formatter formatter : formatters) { if (formatter.getID() == ID) @@ -65,6 +69,7 @@ public static Formatter getByID(int ID) { return null; } + @NonNull public static ArrayList getAsCatalogue() { ArrayList catalogueCards = new ArrayList<>(); for (Formatter formatter : DefaultScrapers.formatters) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java index 3b4069a3a4..fa4c58928e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/DownloadItem.java @@ -1,5 +1,8 @@ package com.github.doomsdayrs.apps.shosetsu.variables; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; @@ -35,9 +38,13 @@ public class DownloadItem { public final Formatter formatter; + @NonNull public final String novelName; + @NonNull public final String chapterName; + @Nullable private final String novelURL; + @Nullable public final String chapterURL; private final int novelID; public final int chapterID; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java index 3effa57e57..9de1c6f803 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java @@ -3,6 +3,8 @@ import android.graphics.Color; import android.net.ConnectivityManager; +import androidx.annotation.Nullable; + /* * This file is part of Shosetsu. * @@ -48,6 +50,7 @@ public class Settings { /** * global connectivity manager variable */ + @Nullable public static ConnectivityManager connectivityManager; /** diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java index ab6e122cb9..bc0ab59114 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java @@ -1,5 +1,6 @@ package com.github.doomsdayrs.apps.shosetsu.variables; +import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; /* @@ -28,5 +29,6 @@ * Static variables to work with */ public class Statics { + @Nullable public static ActionBar mainActionBar; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java index 3f40035051..dd891dbbe6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/enums/Status.java @@ -22,6 +22,8 @@ * @author github.com/doomsdayrs */ +import androidx.annotation.NonNull; + /** * Status of novel/Chapter */ @@ -52,11 +54,13 @@ public String getStatus() { return status; } + @NonNull @Override public String toString() { return "" + a; } + @NonNull public static Status getStatus(int a) { switch (a) { case 0: diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueCard.java index 880c1c3bb9..a1f6aa4a4a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueCard.java @@ -1,5 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects; +import androidx.annotation.NonNull; + import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; /* @@ -27,6 +29,7 @@ public class CatalogueCard extends RecycleCard { /** * Formatter */ + @NonNull public final Formatter formatter; /** @@ -34,7 +37,7 @@ public class CatalogueCard extends RecycleCard { * * @param formatter the formatter */ - public CatalogueCard(Formatter formatter) { + public CatalogueCard(@NonNull Formatter formatter) { super(formatter.getName()); this.formatter = formatter; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java index ec495ca0ef..ea4468a169 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/CatalogueNovelCard.java @@ -39,7 +39,7 @@ public class CatalogueNovelCard extends RecycleCard implements Serializable { * Constructor * @param imageURL image chapterURL * @param title title - * @param novelID + * @param novelID id of novel * @param novelURL novelURL */ public CatalogueNovelCard(String imageURL, String title, int novelID, String novelURL) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java index 74ec7c705e..bf3e6e3c61 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/NovelCard.java @@ -44,7 +44,7 @@ public class NovelCard extends RecycleCard { * Constructor * * @param title title - * @param novelID + * @param novelID novel ID * @param novelURL novelURL * @param imageURL imageURL * @param formatterID id of formatter diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java index 9bb97900c7..68eb049d74 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/recycleObjects/SettingsItem.java @@ -30,6 +30,7 @@ import com.github.doomsdayrs.apps.shosetsu.R; public class SettingsItem { + @NonNull private final View itemView; private final TextView itemTitle; private final TextView itemDesc; diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb29060..0000000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_circle_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_circle_black_24dp.xml deleted file mode 100644 index 81a31397b3..0000000000 --- a/app/src/main/res/drawable/ic_arrow_drop_down_circle_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_error_black_24dp.xml b/app/src/main/res/drawable/ic_error_black_24dp.xml deleted file mode 100644 index 3d98979adf..0000000000 --- a/app/src/main/res/drawable/ic_error_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_folder.xml b/app/src/main/res/drawable/ic_folder.xml deleted file mode 100644 index d7c6145c60..0000000000 --- a/app/src/main/res/drawable/ic_folder.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9bf6..0000000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_outline_arrow_drop_down_circle_24px.xml b/app/src/main/res/drawable/ic_outline_arrow_drop_down_circle_24px.xml deleted file mode 100644 index b88918de84..0000000000 --- a/app/src/main/res/drawable/ic_outline_arrow_drop_down_circle_24px.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml deleted file mode 100644 index 22e438773b..0000000000 --- a/app/src/main/res/layout/chapter_reader_new.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_catalogues_search.xml b/app/src/main/res/layout/fragment_catalogues_search.xml deleted file mode 100644 index 3509b84116..0000000000 --- a/app/src/main/res/layout/fragment_catalogues_search.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/switch_item.xml b/app/src/main/res/layout/switch_item.xml deleted file mode 100644 index 06b0f249fb..0000000000 --- a/app/src/main/res/layout/switch_item.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/app/src/main/res/layout/updated_novel_card.xml b/app/src/main/res/layout/updated_novel_card.xml deleted file mode 100644 index 79924d8bf4..0000000000 --- a/app/src/main/res/layout/updated_novel_card.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/toolbar_catalogue.xml b/app/src/main/res/menu/toolbar_catalogue.xml deleted file mode 100644 index 05af8f0718..0000000000 --- a/app/src/main/res/menu/toolbar_catalogue.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/raw/disclaimer b/app/src/main/res/raw/disclaimer deleted file mode 100644 index 8d4331dbaa..0000000000 --- a/app/src/main/res/raw/disclaimer +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * Shosetsu - * 9 / June / 2019 - * - * @author github.com/doomsdayrs - */ \ No newline at end of file diff --git a/app/src/main/res/raw/license b/app/src/main/res/raw/license deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/app/src/main/res/raw/license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 70b3e8d6a4..68ecfab3e8 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,29 +1,13 @@ - #000 - #FFFFFF - #000000 #0078FF #CCFFFFFF #CC000000 - #80FFEB3B - #00A0B6 #0096AC - #FFFFFF - - #80FFEB3B - #4B4B4B - #646464 - #4B4B4B - - #80FFEB3B - #000 - #191919 - #000 #00A2FF diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a8a5c74304..ae82bb3c76 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,5 @@ Shosetsu - Library Catalogue Settings https://github.com/Doomsdayrs/shosetsu @@ -13,8 +12,6 @@ Search configure_parsers filter - Background Color - Text Color Night mode @@ -28,29 +25,22 @@ Novel Author(s): Novel Description Anilist - more Download Myanimelist Download directory Position: Backup Now Pending - Error occurred - Downloading Downloaded Bookmark Large Medium Small Select All - Download All - Delete All Delete Selected Deselect All Download Selected Retry - Mark All Read - Mark All Unread Mark As READ UNREAD @@ -85,7 +75,6 @@ Selection Map to Migrate source - This will be released in beta Site: Artist(s): Reading Status diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2cad5f3408..01671879f7 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -2,20 +2,6 @@ - - - - - - diff --git a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java index 556b79d6e1..d873006301 100644 --- a/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java +++ b/app/src/test/java/com/github/doomsdayrs/apps/shosetsu/ExampleUnitTest.java @@ -5,7 +5,8 @@ * * @see Testing documentation */ -class ExampleUnitTest { +class +ExampleUnitTest { From 538d6d4fcefd31adbff47f9482bf2a312adbe1db Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 15 Nov 2019 08:39:30 -0500 Subject: [PATCH 065/162] Minor punchout --- .../shosetsu/ui/reader/ChapterReader.java | 4 +- .../ui/reader/readers/MarkdownViewReader.java | 15 ++- .../ui/reader/readers/TextViewReader.java | 15 ++- .../res/layout/chapter_reader_mark_down.xml | 7 ++ .../main/res/layout/chapter_reader_new.xml | 116 ++++++++++++++++++ .../res/layout/chapter_reader_text_view.xml | 7 ++ 6 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/layout/chapter_reader_mark_down.xml create mode 100644 app/src/main/res/layout/chapter_reader_new.xml create mode 100644 app/src/main/res/layout/chapter_reader_text_view.xml diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index bfd0061be1..80b0885b5b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -88,6 +88,8 @@ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; + + private Reader selectedReader = null; private final ArrayList fragments = new ArrayList<>(); // Order of values. Small,Medium,Large @@ -477,7 +479,7 @@ public void setUpReader() { } private void setViewPager() { - ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getSupportFragmentManager(), fragments); + ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getSupportFragmentManager(), fragments); readerViewPager.setAdapter(pagerAdapter); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java index bdaa9adde2..00f03dccf0 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -1,20 +1,29 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.github.doomsdayrs.apps.shosetsu.R; + import org.jetbrains.annotations.NotNull; import us.feras.mdv.MarkdownView; public class MarkdownViewReader extends Reader { - MarkdownView markdownView; + private MarkdownView markdownView; + @Nullable @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.chapter_reader_mark_down, container); + markdownView = view.findViewById(R.id.markdown_view); + return super.onCreateView(inflater, container, savedInstanceState); } @Override diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java index 9a05665de1..d4c69cf841 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -1,20 +1,29 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.github.doomsdayrs.apps.shosetsu.R; + import org.jetbrains.annotations.NotNull; public class TextViewReader extends Reader { - TextView textView; + private TextView textView; + @Nullable @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.chapter_reader_text_view, container); + textView = view.findViewById(R.id.textview); + return view; } @Override diff --git a/app/src/main/res/layout/chapter_reader_mark_down.xml b/app/src/main/res/layout/chapter_reader_mark_down.xml new file mode 100644 index 0000000000..e8b63f5f2f --- /dev/null +++ b/app/src/main/res/layout/chapter_reader_mark_down.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml new file mode 100644 index 0000000000..22e438773b --- /dev/null +++ b/app/src/main/res/layout/chapter_reader_new.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_text_view.xml b/app/src/main/res/layout/chapter_reader_text_view.xml new file mode 100644 index 0000000000..368b7ec13c --- /dev/null +++ b/app/src/main/res/layout/chapter_reader_text_view.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file From dd2e8c2f44dd31a3595afdbc2046ca6c2eae95bc Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 15 Nov 2019 08:51:56 -0500 Subject: [PATCH 066/162] Thinking about this carefully --- .../shosetsu/ui/reader/ChapterReader.java | 42 ++----- .../ui/reader/readers/MarkdownViewReader.java | 8 +- .../shosetsu/ui/reader/readers/Reader.java | 8 ++ .../ui/reader/readers/TextViewReader.java | 12 +- app/src/main/res/layout/chapter_reader.xml | 20 +-- .../main/res/layout/chapter_reader_new.xml | 116 ------------------ 6 files changed, 45 insertions(+), 161 deletions(-) delete mode 100644 app/src/main/res/layout/chapter_reader_new.xml diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 80b0885b5b..0c13c6afcd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -104,6 +104,7 @@ public class ChapterReader extends AppCompatActivity { public ScrollView scrollView; + public Toolbar toolbar; public ProgressBar progressBar; @@ -115,8 +116,6 @@ public class ChapterReader extends AppCompatActivity { public int chapterID; private ViewPager readerViewPager; - private TextView textView; - private MarkdownView markdownView; @Nullable public String chapterURL; @@ -378,7 +377,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } - Log.i("Reading", chapterURL); + assert chapterURL != null; + Log.i("Reading", String.valueOf(chapterURL)); errorView = findViewById(R.id.network_error); errorMessage = findViewById(R.id.error_message); @@ -388,26 +388,23 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { scrollView = findViewById(R.id.fragment_novel_scroll); addBottomListener(); - Toolbar toolbar = findViewById(R.id.toolbar); + toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); readerViewPager = findViewById(R.id.readerPager); - markdownView = findViewById(R.id.fragment_novel_chapter_view_markdown); - textView = findViewById(R.id.fragment_novel_chapter_view_text); - switch (readerType) { case 1: - markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); + selectedReader = fragments.get(1); break; case 0: case -1: - textView.setOnClickListener(new NovelFragmentChapterViewHideBar(toolbar)); + selectedReader = fragments.get(0); break; case -2: default: throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); } - + setViewPager(); // Scroll up listener scroll_up = findViewById(R.id.scroll_up); @@ -433,9 +430,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Toast.makeText(getApplicationContext(), "Cannot move to next chapter, Please exit reader", Toast.LENGTH_LONG).show(); } nextChapter.setVisibility(View.GONE); - }); - loadChapter(); } @@ -445,18 +440,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { */ public void setUpReader() { scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); - textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); - switch (readerType) { - case -1: - case 0: - textView.setTextColor(Settings.ReaderTextColor); - textView.setTextSize(Settings.ReaderTextSize); - break; - default: - break; - } - - if (unformattedText != null) { StringBuilder replaceSpacing = new StringBuilder("\n"); for (int x = 0; x < Settings.paragraphSpacing; x++) @@ -466,15 +449,8 @@ public void setUpReader() { replaceSpacing.append("\t"); text = unformattedText.replaceAll("\n", replaceSpacing.toString()); - - switch (readerType) { - case -1: - case 0: - textView.setText(text); - break; - case 1: - markdownView.loadMarkdown(text); - } + assert selectedReader.getView() != null; + selectedReader.getView().post(() -> selectedReader.setText(text)); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java index 00f03dccf0..9a3d8ada72 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -7,9 +7,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; import org.jetbrains.annotations.NotNull; @@ -18,11 +19,16 @@ public class MarkdownViewReader extends Reader { private MarkdownView markdownView; + public MarkdownViewReader(ChapterReader chapterReader) { + super(chapterReader); + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.chapter_reader_mark_down, container); markdownView = view.findViewById(R.id.markdown_view); + markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(chapterReader.toolbar)); return super.onCreateView(inflater, container, savedInstanceState); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java index 5163c41cf0..75cbdb9882 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java @@ -2,8 +2,16 @@ import androidx.fragment.app.Fragment; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + import org.jetbrains.annotations.NotNull; public abstract class Reader extends Fragment { + protected final ChapterReader chapterReader; + + protected Reader(ChapterReader chapterReader) { + this.chapterReader = chapterReader; + } + public abstract void setText(@NotNull String text); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java index d4c69cf841..1d560434b6 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -8,21 +8,31 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import org.jetbrains.annotations.NotNull; public class TextViewReader extends Reader { private TextView textView; + public TextViewReader(ChapterReader chapterReader) { + super(chapterReader); + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.chapter_reader_text_view, container); textView = view.findViewById(R.id.textview); + textView.setOnClickListener(new NovelFragmentChapterViewHideBar(chapterReader.toolbar)); + textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + textView.setTextColor(Settings.ReaderTextColor); + textView.setTextSize(Settings.ReaderTextSize); return view; } diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 440af63f4f..22e438773b 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -2,10 +2,9 @@ + android:layout_height="match_parent"> + - - + - @@ -54,7 +54,7 @@ android:layout_height="wrap_content" android:padding="5dp" android:visibility="gone" /> - + @@ -90,7 +90,8 @@ app:layout_constraintStart_toStartOf="parent" tools:visibility="gone" /> - + + - \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_new.xml b/app/src/main/res/layout/chapter_reader_new.xml deleted file mode 100644 index 22e438773b..0000000000 --- a/app/src/main/res/layout/chapter_reader_new.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From a5760c905f86126cb0140bec070e4215d35a82fc Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Wed, 27 Nov 2019 16:50:32 -0500 Subject: [PATCH 067/162] Removed outdated class --- .../scraper/aria2/CloudFlareCallback.java | 11 - .../backend/scraper/aria2/Cloudflare.java | 366 ------------------ 2 files changed, 377 deletions(-) delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java deleted file mode 100644 index 85b907cd47..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/CloudFlareCallback.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2; - -import java.net.HttpCookie; -import java.util.List; - - -public interface CloudFlareCallback { - void onSuccess(List cookieList); - - void onFail(); -} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java deleted file mode 100644 index c4e6fc5118..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/aria2/Cloudflare.java +++ /dev/null @@ -1,366 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2; - -import android.net.Uri; -import android.os.Looper; -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Scriptable; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.CookieHandler; -import java.net.CookieManager; -import java.net.CookiePolicy; -import java.net.HttpCookie; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -/** - * author: zhkrb @ https://github.com/zhkrb - */ -@SuppressWarnings("JavaDoc") -public class Cloudflare { - - private static final int MAX_COUNT = 3; - private static final int CONN_TIMEOUT = 60000; - private static final String ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;"; - private final String mUrl; - private String mUser_agent; - private CloudFlareCallback mCallback; - private int mRetry_count; - private URL ConnUrl; - private List mCookieList; - private CookieManager mCookieManager; - private HttpURLConnection mCheckConn; - private HttpURLConnection mGetMainConn; - private HttpURLConnection mGetRedirectionConn; - private boolean canVisit = false; - - public Cloudflare(String url) { - mUrl = url; - } - - public Cloudflare(String url, String user_agent) { - mUrl = url; - mUser_agent = user_agent; - } - - /** - * 转换list为 ; 符号链接的字符串 - * - * @param list - * @return - */ - @NonNull - private static String listToString(@NonNull List list) { - char separator = ";".charAt(0); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < list.size(); i++) { - sb.append(list.get(i)).append(separator); - } - return sb.toString().substring(0, sb.toString().length() - 1); - } - - /** - * 转换为jsoup可用的Hashmap - * - * @param list HttpCookie列表 - * @return Hashmap - */ - @NonNull - public static Map List2Map(@Nullable List list) { - Map map = new HashMap<>(); - try { - if (list != null) { - for (int i = 0; i < list.size(); i++) { - String[] listStr = list.get(i).toString().split("="); - map.put(listStr[0], listStr[1]); - } - Log.i("List2Map", map.toString()); - } else { - return map; - } - - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - } - - return map; - } - - public String getUser_agent() { - return mUser_agent; - } - - public void setUser_agent(String user_agent) { - mUser_agent = user_agent; - } - - public void getCookies(final CloudFlareCallback callback) { - new Thread(() -> urlThread(callback)).start(); - } - - private void urlThread(@Nullable CloudFlareCallback callback) { - mCookieManager = new CookieManager(); - mCookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); //接受所有cookies - CookieHandler.setDefault(mCookieManager); - HttpURLConnection.setFollowRedirects(false); - - while (!canVisit) { - if (mRetry_count > MAX_COUNT) { - break; - } - try { - - int responseCode = checkUrl(); - if (responseCode == 200) { - canVisit = true; - break; - } else { - getVisiteCookie(); - } - } catch (@NonNull IOException | InterruptedException e) { - if (mCookieList != null) { - mCookieList.clear(); - } - e.printStackTrace(); - } finally { - closeAllConn(); - } - mRetry_count++; - } - if (callback != null) { - Looper.prepare(); - if (canVisit) { - callback.onSuccess(mCookieList); - } else { - e("Get Cookie Failed"); - callback.onFail(); - } - - - } - } - - private void getVisiteCookie() throws IOException, InterruptedException { - ConnUrl = new URL(mUrl); - mGetMainConn = (HttpURLConnection) ConnUrl.openConnection(); - mGetMainConn.setRequestMethod("GET"); - mGetMainConn.setConnectTimeout(CONN_TIMEOUT); - mGetMainConn.setReadTimeout(CONN_TIMEOUT); - if (!TextUtils.isEmpty(mUser_agent)) { - mGetMainConn.setRequestProperty("user-agent", mUser_agent); - } - mGetMainConn.setRequestProperty("accept", ACCEPT); - mGetMainConn.setRequestProperty("referer", mUrl); - if (mCookieList != null && mCookieList.size() > 0) { - mGetMainConn.setRequestProperty("cookie", listToString(mCookieList)); - } - mGetMainConn.setUseCaches(false); - mGetMainConn.connect(); - switch (mGetMainConn.getResponseCode()) { - case HttpURLConnection.HTTP_OK: - e("MainUrl", "visit website success"); - return; - case HttpURLConnection.HTTP_FORBIDDEN: - e("MainUrl", "IP block or cookie err"); - return; - case HttpURLConnection.HTTP_UNAVAILABLE: - InputStream mInputStream = mCheckConn.getErrorStream(); - BufferedReader mBufferedReader = new BufferedReader(new InputStreamReader(mInputStream)); - StringBuilder sb = new StringBuilder(); - String str; - while ((str = mBufferedReader.readLine()) != null) { - sb.append(str); - } - mInputStream.close(); - mBufferedReader.close(); - mCookieList = mCookieManager.getCookieStore().getCookies(); - str = sb.toString(); - getCheckAnswer(str); - break; - default: - - break; - } - } - - /** - * 获取值并跳转获得cookies - * - * @param str - */ - private void getCheckAnswer(@NonNull String str) throws InterruptedException, IOException { - String s = regex(str, "name=\"s\" value=\"(.+?)\"").get(0); //正则取值 - String jschl_vc = regex(str, "name=\"jschl_vc\" value=\"(.+?)\"").get(0); - String pass = regex(str, "name=\"pass\" value=\"(.+?)\"").get(0); // - double jschl_answer = get_answer(str); - e(String.valueOf(jschl_answer)); - Thread.sleep(3000); - String req = "https://" + ConnUrl.getHost() + "/cdn-cgi/l/chk_jschl?"; - if (!TextUtils.isEmpty(s)) { - s = Uri.encode(s); - req += "s=" + s + "&"; - } - req += "jschl_vc=" + Uri.encode(jschl_vc) + "&pass=" + Uri.encode(pass) + "&jschl_answer=" + jschl_answer; - e("RedirectUrl", req); - getRedirectResponse(req); - } - - private void getRedirectResponse(String req) throws IOException { - HttpURLConnection.setFollowRedirects(false); - mGetRedirectionConn = (HttpURLConnection) new URL(req).openConnection(); - mGetRedirectionConn.setRequestMethod("GET"); - mGetRedirectionConn.setConnectTimeout(CONN_TIMEOUT); - mGetRedirectionConn.setReadTimeout(CONN_TIMEOUT); - if (!TextUtils.isEmpty(mUser_agent)) { - mGetRedirectionConn.setRequestProperty("user-agent", mUser_agent); - } - mGetRedirectionConn.setRequestProperty("accept", ACCEPT); - mGetRedirectionConn.setRequestProperty("referer", req); - if (mCookieList != null && mCookieList.size() > 0) { - mGetRedirectionConn.setRequestProperty("cookie", listToString(mCookieList)); - } - mGetRedirectionConn.setUseCaches(false); - mGetRedirectionConn.connect(); - switch (mGetRedirectionConn.getResponseCode()) { - case HttpURLConnection.HTTP_OK: - case HttpURLConnection.HTTP_MOVED_TEMP: - mCookieList = mCookieManager.getCookieStore().getCookies(); - break; - default: - throw new IOException("getOtherResponse Code: " + - mGetRedirectionConn.getResponseCode()); - } - } - - private int checkUrl() throws IOException { - URL ConnUrl = new URL(mUrl); - mCheckConn = (HttpURLConnection) ConnUrl.openConnection(); - mCheckConn.setRequestMethod("GET"); - mCheckConn.setConnectTimeout(CONN_TIMEOUT); - mCheckConn.setReadTimeout(CONN_TIMEOUT); - if (!TextUtils.isEmpty(mUser_agent)) { - mCheckConn.setRequestProperty("user-agent", mUser_agent); - } - mCheckConn.setRequestProperty("accept", ACCEPT); - mCheckConn.setRequestProperty("referer", mUrl); - if (mCookieList != null && mCookieList.size() > 0) { - mCheckConn.setRequestProperty("cookie", listToString(mCookieList)); - } - mCheckConn.setUseCaches(false); - mCheckConn.connect(); - return mCheckConn.getResponseCode(); - } - - private void closeAllConn() { - if (mCheckConn != null) { - mCheckConn.disconnect(); - } - if (mGetMainConn != null) { - mGetMainConn.disconnect(); - } - if (mGetRedirectionConn != null) { - mGetRedirectionConn.disconnect(); - } - } - - private double get_answer(@NonNull String str) { //取值 - double a = 0; - - try { - List s = regex(str, "var s,t,o,p,b,r,e,a,k,i,n,g,f, " + - "(.+?)=\\{\"(.+?)\""); - String varA = s.get(0); - String varB = s.get(1); - StringBuilder sb = new StringBuilder(); - sb.append("var t=\"").append(new URL(mUrl).getHost()).append("\";"); - sb.append("var a="); - sb.append(regex(str, varA + "=\\{\"" + varB + "\":(.+?)\\}").get(0)); - sb.append(";"); - List b = regex(str, varA + "\\." + varB + "(.+?)\\;"); - for (int i = 0; i < b.size() - 1; i++) { - sb.append("a"); - sb.append(b.get(i)); - sb.append(";"); - } - - e("add", sb.toString()); - Context rhino = Context.enter(); - rhino.setOptimizationLevel(-1); - try { - Scriptable scope = rhino.initStandardObjects(); - a = Double.parseDouble(rhino.evaluateString(scope, sb.toString(), "JavaScript", 1, null).toString()); - List fixNum = regex(str, "toFixed\\((.+?)\\)"); - if (fixNum != null) { - String script = "String(" + a + ".toFixed(" + fixNum.get(0) + "));"; - a = Double.parseDouble(rhino.evaluateString(scope, script, "JavaScript", 1, null).toString()); - } - if (b.get(b.size() - 1).contains("t.length")) { - a += new URL(mUrl).getHost().length(); - } - } finally { - Context.exit(); - } - } catch (IndexOutOfBoundsException e) { - e("answerErr", "get answer error"); - e.printStackTrace(); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - return a; - } - - /** - * 正则 - * - * @param text 本体 - * @param pattern 正则式 - * @return List - */ - @Nullable - private List regex(@NonNull String text, @NonNull String pattern) { - try { - Pattern pt = Pattern.compile(pattern); - Matcher mt = pt.matcher(text); - List group = new ArrayList<>(); - - while (mt.find()) { - if (mt.groupCount() >= 1) { - if (mt.groupCount() > 1) { - group.add(mt.group(1)); - group.add(mt.group(2)); - } else group.add(mt.group(1)); - } - } - return group; - } catch (NullPointerException e) { - Log.i("MATCH", "null"); - } - return null; - } - - private void e(String tag, @NonNull String content) { - Log.e(tag, content); - } - - private void e(@NonNull String content) { - Log.e("cloudflare", content); - } - -} From 6b1fc7f0b2ab9e3c1fd5e4a5b2ee28a552c060af Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 28 Nov 2019 21:33:32 -0500 Subject: [PATCH 068/162] Added submodle for scraper --- .gitmodules | 3 +++ app/build.gradle | 4 ++-- .../apps/shosetsu/backend/scraper/WebViewScrapper.java | 8 ++++---- .../apps/shosetsu/backend/scraper/cloudflareScrape | 1 + build.gradle | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 .gitmodules create mode 160000 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..0163440f50 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape"] + path = app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape + url = https://github.com/zhkrb/cloudflare-scrape-Android.git diff --git a/app/build.gradle b/app/build.gradle index bde083d313..0255fc1bf8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,12 +47,12 @@ repositories { } dependencies { - implementation 'com.google.android.material:material:1.2.0-alpha01' + implementation 'com.google.android.material:material:1.2.0-alpha02' implementation 'com.graphql-java:graphql-java:2019-11-07T04-06-09-70d9412' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible - implementation 'com.google.android.material:material:1.2.0-alpha01' + implementation 'com.google.android.material:material:1.2.0-alpha02' testImplementation 'junit:junit:4.13-rc-1' testImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:runner:1.2.0' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index fae07d7eb7..5e0a288668 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -23,8 +23,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.CloudFlareCallback; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.aria2.Cloudflare; +import com.github.doomsdayrs.apps.shosetsu.backend.scraper.cloudflareScrape.Cloudflare; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -114,9 +113,10 @@ static class GetCookies extends AsyncTask> { @Nullable @Override protected List doInBackground(Cloudflare... cf) { - cf[0].getCookies(new CloudFlareCallback() { + cf[0].getCookies(new Cloudflare.cfCallback() { + @Override - public void onSuccess(List cookieList) { + public void onSuccess(List cookieList, boolean hasNewUrl, String newUrl) { cookies = cookieList; status = 1; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape new file mode 160000 index 0000000000..4658bb4dd4 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape @@ -0,0 +1 @@ +Subproject commit 4658bb4dd424868b0d6a0f0c6300e9f696f510cf diff --git a/build.gradle b/build.gradle index fbe43270e0..27366f5668 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.6.0-alpha09' + classpath 'com.android.tools.build:gradle:3.6.0-beta04' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From 24942e2f59febb9b55766f48b16f6aa5e2841a49 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 29 Nov 2019 10:54:52 -0500 Subject: [PATCH 069/162] Changes --- .gitmodules | 4 +--- app/build.gradle | 4 +++- .../apps/shosetsu/backend/scraper/WebViewScrapper.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 0163440f50..e94e423407 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1 @@ -[submodule "app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape"] - path = app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape - url = https://github.com/zhkrb/cloudflare-scrape-Android.git +ike \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 0255fc1bf8..a55a47c16f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,10 +79,12 @@ dependencies { implementation 'com.vincent.filepicker:MultiTypeFilePicker:1.0.8' - implementation 'org.mozilla:rhino:1.7.11' + //implementation 'org.mozilla:rhino:1.7.11' implementation 'androidx.annotation:annotation:1.1.0' // TODO Implement readerview provided by Mozilla //implementation "org.mozilla.components:feature-readerview:1.0.0" //implementation 'org.mozilla.components:support-base:1.0.0' + + implementation 'com.zhkrb.cloudflare-scrape-android:scrape-rhino:0.1.1' } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java index 5e0a288668..5d9756578f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/WebViewScrapper.java @@ -23,7 +23,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.github.doomsdayrs.apps.shosetsu.backend.scraper.cloudflareScrape.Cloudflare; +import com.zhkrb.cloudflare_scrape_android.Cloudflare; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; From 742bed989c31ee509cf8df652f1229895ac9a2bb Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 29 Nov 2019 10:56:59 -0500 Subject: [PATCH 070/162] Fixed modules --- .gitmodules | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index e94e423407..e69de29bb2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1 +0,0 @@ -ike \ No newline at end of file From cd6f9eb1b9a4ac097863a6c9ffff3929e6714719 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 29 Nov 2019 12:05:57 -0500 Subject: [PATCH 071/162] Figuring out rework of ChapterReader --- .../apps/shosetsu/backend/Utilities.java | 16 +++ .../apps/shosetsu/ui/main/MainActivity.java | 12 +- .../ui/novel/async/ChapterLoader.java | 4 +- .../shosetsu/ui/reader/ChapterReader.java | 109 ++++++------------ .../ui/reader/async/ReaderViewLoader.java | 8 +- .../apps/shosetsu/variables/Settings.java | 1 + 6 files changed, 62 insertions(+), 88 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 93178a848a..bebe81fbc7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -19,6 +19,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.Stati; +import com.github.doomsdayrs.apps.shosetsu.BuildConfig; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; @@ -56,6 +57,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * shosetsu * 26 / 07 / 2019 * @@ -63,6 +67,15 @@ */ public class Utilities { + public static void ASSERT(boolean b) { + Log.e("ASSERT, D", String.valueOf(BuildConfig.DEBUG)); + Log.e("ASSERT, B", String.valueOf(b)); + + if (BuildConfig.DEBUG && !b) + throw new RuntimeException(); + } + + /** * Demarks a list of items, setting only one to be checked. * @@ -310,7 +323,10 @@ public static void changeMode(@NonNull Activity activity, int newMode) { advanced.edit() .putInt("themeMode", newMode) .apply(); + setupTheme(activity); + } + public static void setupTheme(Activity activity) { switch (Settings.themeMode) { case 0: activity.setTheme(R.style.Theme_MaterialComponents_Light_NoActionBar); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index e909b3e3b5..e4604b2ef4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -40,6 +40,7 @@ import com.google.android.material.navigation.NavigationView; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.initPreferences; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setupTheme; /* * This file is part of Shosetsu. @@ -99,16 +100,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { Utilities.backup = getSharedPreferences("backup", 0); initPreferences(this); - switch (Settings.themeMode) { - case 0: - setTheme(R.style.Theme_MaterialComponents_Light_NoActionBar); - break; - case 1: - setTheme(R.style.Theme_MaterialComponents_NoActionBar); - break; - case 2: - setTheme(R.style.ThemeOverlay_MaterialComponents_Dark); - } + setupTheme(this); // getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES); Log.d("Updater", "Start"); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 816e140024..8aef20c9f5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -121,7 +121,7 @@ protected Boolean doInBackground(Activity... voids) { novelFragmentChapters.getActivity().runOnUiThread(() -> { novelFragmentChapters.novelFragment.errorView.setVisibility(View.VISIBLE); novelFragmentChapters.novelFragment.errorMessage.setText(e.getMessage()); - novelFragmentChapters.novelFragment.errorButton.setOnClickListener(view -> refresh(view, activity)); + novelFragmentChapters.novelFragment.errorButton.setOnClickListener(view -> refresh(activity)); }); } @@ -138,7 +138,7 @@ private void add(@NonNull Activity activity, int mangaCount, @NonNull NovelChapt } } - private void refresh(View view, Activity activity) { + private void refresh(Activity activity) { new ChapterLoader(this).execute(activity); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 0c13c6afcd..f4804526bb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -7,54 +7,49 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.Button; import android.widget.ProgressBar; import android.widget.ScrollView; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.fragment.app.Fragment; import androidx.viewpager.widget.ViewPager; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.novel.adapters.NovelPagerAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ParaSpacingChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ReaderChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.TextSizeChange; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.MarkdownViewReader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.TextViewReader; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.chip.Chip; -import com.google.android.material.tabs.TabLayout; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.List; import java.util.Objects; -import us.feras.mdv.MarkdownView; - +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.ASSERT; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isReaderNightMode; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setTextSize; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setupTheme; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.swapReaderColor; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; @@ -88,13 +83,9 @@ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; - - private Reader selectedReader = null; private final ArrayList fragments = new ArrayList<>(); - // Order of values. Small,Medium,Large private final MenuItem[] textSizes = new MenuItem[3]; - public boolean ready = false; // Order of values. Non,Small,Medium,Large private final MenuItem[] paragraphSpaces = new MenuItem[4]; // Order of values. Non,Small,Medium,Large @@ -103,47 +94,29 @@ public class ChapterReader extends AppCompatActivity { private final MenuItem[] readers = new MenuItem[2]; public ScrollView scrollView; - public Toolbar toolbar; - public ProgressBar progressBar; - - @Nullable - public String title; @Nullable - public Formatter formatter; - public int chapterID; + public String title, chapterURL, unformattedText = null, text = null; + public int chapterID, readerType, novelID; + public boolean ready = false; + //TODO Handle ERRORs on loading, EVERYWHERE + public ErrorView errorView; + private boolean bookmarked; - private ViewPager readerViewPager; @Nullable - public String chapterURL; - @Nullable - public String unformattedText = null; - public int readerType; - - private MenuItem bookmark; - private boolean bookmarked; - - private MenuItem tap_to_scroll; + public Formatter formatter; + private ViewPager readerViewPager; private Chip nextChapter; - public int novelID; @Nullable private String[] chapters; - @Nullable - private String text = null; - - + private MenuItem bookmark, tap_to_scroll; + private Reader selectedReader = null; //Tap to scroll - private View scroll_up; - private View scroll_down; - - // ERROR SCREEN - //TODO Handle ERRORs on loading, EVERYWHERE - public ConstraintLayout errorView; - public TextView errorMessage; - public Button errorButton; + @SuppressWarnings("FieldCanBeLocal") + private View scroll_up, scroll_down; /** @@ -347,19 +320,9 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("OnCreate", "NovelFragmentChapterReader"); - switch (Settings.themeMode) { - case 0: - setTheme(R.style.Theme_MaterialComponents_Light_NoActionBar); - break; - case 1: - setTheme(R.style.Theme_MaterialComponents_NoActionBar); - break; - case 2: - setTheme(R.style.ThemeOverlay_MaterialComponents_Dark); - } - + setupTheme(this); setContentView(R.layout.chapter_reader); - + // SetUp of data if (savedInstanceState != null) { unformattedText = savedInstanceState.getString("unformattedText"); title = savedInstanceState.getString("title"); @@ -378,20 +341,30 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } assert chapterURL != null; - Log.i("Reading", String.valueOf(chapterURL)); - errorView = findViewById(R.id.network_error); - errorMessage = findViewById(R.id.error_message); - errorButton = findViewById(R.id.error_button); - progressBar = findViewById(R.id.fragment_novel_chapter_view_progress); + ASSERT(chapterID != -1); + assert chapters != null; + Log.i("Reading", chapterURL); + + // Declares view variables + { + errorView = new ErrorView(this, findViewById(R.id.network_error), findViewById(R.id.error_message), findViewById(R.id.error_button)); + progressBar = findViewById(R.id.fragment_novel_chapter_view_progress); + scrollView = findViewById(R.id.fragment_novel_scroll); + toolbar = findViewById(R.id.toolbar); + readerViewPager = findViewById(R.id.readerPager); + scroll_up = findViewById(R.id.scroll_up); + scroll_down = findViewById(R.id.scroll_down); + nextChapter = findViewById(R.id.next_chapter); + } - scrollView = findViewById(R.id.fragment_novel_scroll); addBottomListener(); - toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - readerViewPager = findViewById(R.id.readerPager); + fragments.add(new TextViewReader(this)); + fragments.add(new MarkdownViewReader(this)); + switch (readerType) { case 1: selectedReader = fragments.get(1); @@ -407,18 +380,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setViewPager(); // Scroll up listener - scroll_up = findViewById(R.id.scroll_up); scroll_up.setOnClickListener(view -> scrollUp()); - // Scroll down listener - scroll_down = findViewById(R.id.scroll_down); scroll_down.setOnClickListener(view -> scrollDown()); - - nextChapter = findViewById(R.id.next_chapter); nextChapter.setOnClickListener(view -> { - NovelChapter novelChapter = getNextChapter(chapterURL, chapters); - if (novelChapter != null) { if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { title = novelChapter.title; @@ -459,7 +425,6 @@ private void setViewPager() { readerViewPager.setAdapter(pagerAdapter); } - /** * What to do when scroll hits bottom */ diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index a4edea2973..8f22c8c67d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -50,7 +50,7 @@ public ReaderViewLoader(ChapterReader chapterReader) { @Nullable @Override protected String doInBackground(ChapterReader... chapterReaders) { - chapterReader.runOnUiThread(() -> chapterReader.errorView.setVisibility(View.GONE)); + chapterReader.runOnUiThread(() -> chapterReader.errorView.errorView.setVisibility(View.GONE)); try { chapterReader.unformattedText = chapterReader.formatter.getNovelPassage(docFromURL(chapterReader.chapterURL, chapterReader.formatter.hasCloudFlare())); chapterReader.runOnUiThread(chapterReader::setUpReader); @@ -61,9 +61,9 @@ protected String doInBackground(ChapterReader... chapterReaders) { chapterReader.runOnUiThread(() -> chapterReader.ready = true); } catch (Exception e) { chapterReader.runOnUiThread(() -> { - chapterReader.errorView.setVisibility(View.VISIBLE); - chapterReader.errorMessage.setText(e.getMessage()); - chapterReader.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterReader).execute()); + chapterReader.errorView.errorView.setVisibility(View.VISIBLE); + chapterReader.errorView.errorMessage.setText(e.getMessage()); + chapterReader.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterReader).execute()); }); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java index 9de1c6f803..a9e1026b67 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Settings.java @@ -64,6 +64,7 @@ public class Settings { * 0: Light mode * 1: Night mode * 2: Dark mode + *

*/ public static int themeMode; From 22dd116655177f13eaf10615ecf5df4951223fc1 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 29 Nov 2019 17:17:42 -0500 Subject: [PATCH 072/162] Figuring out rework of ChapterReader --- .../ui/reader/readers/MarkdownViewReader.java | 4 ++-- .../ui/reader/readers/TextViewReader.java | 2 +- .../res/layout/chapter_reader_mark_down.xml | 1 - .../res/layout/chapter_reader_text_view.xml | 1 - gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 ++++++ 6 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java index 9a3d8ada72..8ca2247ccf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -26,10 +26,10 @@ public MarkdownViewReader(ChapterReader chapterReader) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.chapter_reader_mark_down, container); + View view = inflater.inflate(R.layout.chapter_reader_mark_down, container, false); markdownView = view.findViewById(R.id.markdown_view); markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(chapterReader.toolbar)); - return super.onCreateView(inflater, container, savedInstanceState); + return view; } @Override diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java index 1d560434b6..0f24ef64ef 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -27,7 +27,7 @@ public TextViewReader(ChapterReader chapterReader) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.chapter_reader_text_view, container); + View view = inflater.inflate(R.layout.chapter_reader_text_view, container, false); textView = view.findViewById(R.id.textview); textView.setOnClickListener(new NovelFragmentChapterViewHideBar(chapterReader.toolbar)); textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); diff --git a/app/src/main/res/layout/chapter_reader_mark_down.xml b/app/src/main/res/layout/chapter_reader_mark_down.xml index e8b63f5f2f..fc0162f9ad 100644 --- a/app/src/main/res/layout/chapter_reader_mark_down.xml +++ b/app/src/main/res/layout/chapter_reader_mark_down.xml @@ -3,5 +3,4 @@ android:id="@+id/markdown_view" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> -
\ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_text_view.xml b/app/src/main/res/layout/chapter_reader_text_view.xml index 368b7ec13c..cb67fae36e 100644 --- a/app/src/main/res/layout/chapter_reader_text_view.xml +++ b/app/src/main/res/layout/chapter_reader_text_view.xml @@ -3,5 +3,4 @@ android:id="@+id/textview" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> -
\ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f6b961fd5a86aa5fbfe90f707c3138408be7c718 GIT binary patch literal 54329 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

<5G2M1WZP5 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 F{|7XC?P&l2 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..2ee8b1e9d5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Nov 29 10:58:13 EST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-milestone-2-all.zip From b4917d794680e83a259993c8adb06d5da77e958e Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 1 Dec 2019 16:44:45 -0500 Subject: [PATCH 073/162] Removed gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 ------ 2 files changed, 6 deletions(-) delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f6b961fd5a86aa5fbfe90f707c3138408be7c718..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54329 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

<5G2M1WZP5 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 F{|7XC?P&l2 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 2ee8b1e9d5..0000000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Nov 29 10:58:13 EST 2019 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-milestone-2-all.zip From 8231ac9ba7c45d9575d43bf8d59071451c0e349b Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 1 Dec 2019 18:23:59 -0500 Subject: [PATCH 074/162] Clicking on unread badge makes a toast that says 'Chapters unread: #' --- .../shosetsu/backend/scraper/cloudflareScrape | 1 - .../library/adapter/LibraryNovelAdapter.java | 38 +++--- ...iewHolder.java => LibNovelViewHolder.java} | 18 ++- .../ui/novel/pages/NovelFragmentInfo.java | 111 +++++++++--------- app/src/main/res/values/strings.xml | 1 + 5 files changed, 87 insertions(+), 82 deletions(-) delete mode 160000 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape rename app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/{LibraryViewHolder.java => LibNovelViewHolder.java} (90%) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape deleted file mode 160000 index 4658bb4dd4..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/scraper/cloudflareScrape +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4658bb4dd424868b0d6a0f0c6300e9f696f510cf diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java index 5e6d8654fe..81c1ae1acd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java @@ -11,7 +11,7 @@ import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.library.LibraryFragment; -import com.github.doomsdayrs.apps.shosetsu.ui.library.viewHolders.LibraryViewHolder; +import com.github.doomsdayrs.apps.shosetsu.ui.library.viewHolders.LibNovelViewHolder; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; @@ -40,7 +40,7 @@ * * @author github.com/doomsdayrs */ -public class LibraryNovelAdapter extends RecyclerView.Adapter { +public class LibraryNovelAdapter extends RecyclerView.Adapter { private final LibraryFragment libraryFragment; private final ArrayList novelCards; @@ -51,51 +51,51 @@ public LibraryNovelAdapter(ArrayList novelCards, LibraryFragment libr @NonNull @Override - public LibraryViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + public LibNovelViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_novel_card, viewGroup, false); - return new LibraryViewHolder(view); + return new LibNovelViewHolder(view); } @Override - public void onBindViewHolder(@NonNull LibraryViewHolder libraryViewHolder, int i) { + public void onBindViewHolder(@NonNull LibNovelViewHolder libNovelViewHolder, int i) { NovelCard novelCard = novelCards.get(i); //Sets values { Picasso.get() .load(novelCard.imageURL) - .into(libraryViewHolder.library_card_image); - libraryViewHolder.libraryFragment = libraryFragment; - libraryViewHolder.novelCard = novelCard; - libraryViewHolder.formatter = DefaultScrapers.getByID(novelCard.formatterID); - libraryViewHolder.library_card_title.setText(novelCard.title); + .into(libNovelViewHolder.library_card_image); + libNovelViewHolder.libraryFragment = libraryFragment; + libNovelViewHolder.novelCard = novelCard; + libNovelViewHolder.formatter = DefaultScrapers.getByID(novelCard.formatterID); + libNovelViewHolder.library_card_title.setText(novelCard.title); switch (Settings.themeMode) { case 0: - libraryViewHolder.library_card_title.setBackgroundResource(R.color.white_trans); + libNovelViewHolder.library_card_title.setBackgroundResource(R.color.white_trans); break; case 1: case 2: - libraryViewHolder.library_card_title.setBackgroundResource(R.color.black_trans); + libNovelViewHolder.library_card_title.setBackgroundResource(R.color.black_trans); break; } } int count = Database.DatabaseChapter.getCountOfChaptersUnread(novelCard.novelID); if (count != 0) { - libraryViewHolder.chip.setVisibility(View.VISIBLE); - libraryViewHolder.chip.setText(String.valueOf(count)); - } else libraryViewHolder.chip.setVisibility(View.INVISIBLE); + libNovelViewHolder.chip.setVisibility(View.VISIBLE); + libNovelViewHolder.chip.setText(String.valueOf(count)); + } else libNovelViewHolder.chip.setVisibility(View.INVISIBLE); if (libraryFragment.contains(novelCard)) { - libraryViewHolder.materialCardView.setStrokeWidth(Utilities.SELECTED_STROKE_WIDTH); + libNovelViewHolder.materialCardView.setStrokeWidth(Utilities.SELECTED_STROKE_WIDTH); } else { - libraryViewHolder.materialCardView.setStrokeWidth(0); + libNovelViewHolder.materialCardView.setStrokeWidth(0); } if (libraryFragment.selectedNovels.size() > 0) { - libraryViewHolder.itemView.setOnClickListener(view -> libraryViewHolder.addToSelect()); + libNovelViewHolder.itemView.setOnClickListener(view -> libNovelViewHolder.addToSelect()); } else { - libraryViewHolder.itemView.setOnClickListener(libraryViewHolder); + libNovelViewHolder.itemView.setOnClickListener(libNovelViewHolder); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java similarity index 90% rename from app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java rename to app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java index 3803071107..6d9bcd172a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibraryViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java @@ -15,15 +15,13 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== - * Shosetsu - * 13 / 07 / 2019 - * - * @author github.com/doomsdayrs */ + import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,7 +35,14 @@ import com.google.android.material.card.MaterialCardView; import com.google.android.material.chip.Chip; -public class LibraryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { +/** + * Shosetsu + * 13 / 07 / 2019 + * + * @author github.com/doomsdayrs + */ + +public class LibNovelViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public final MaterialCardView materialCardView; public final ImageView library_card_image; public final TextView library_card_title; @@ -48,13 +53,14 @@ public class LibraryViewHolder extends RecyclerView.ViewHolder implements View.O public Formatter formatter; public NovelCard novelCard; - public LibraryViewHolder(@NonNull View itemView) { + public LibNovelViewHolder(@NonNull View itemView) { super(itemView); materialCardView = itemView.findViewById(R.id.novel_item_card); library_card_image = itemView.findViewById(R.id.novel_item_image); library_card_title = itemView.findViewById(R.id.title); chip = itemView.findViewById(R.id.novel_item_left_to_read); + chip.setOnClickListener(view -> Toast.makeText(view.getContext(), libraryFragment.getResources().getString(R.string.chapters_unread_label) + chip.getText(), Toast.LENGTH_SHORT).show()); itemView.setOnLongClickListener(view -> { addToSelect(); return true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java index e6b57749d4..b6aa109594 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java @@ -192,64 +192,63 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c * Sets the data of this page */ public void setData() { - assert novelFragment.getView() != null; - - novelFragment.getView().post(() -> { - - if (novelFragment.novelPage == null) { - Log.e("NULL", "Invalid novel page"); - return; - } - - title.setText(novelFragment.novelPage.title); - - if (novelFragment.novelPage.authors != null && novelFragment.novelPage.authors.length > 0) - authors.setText(Arrays.toString(novelFragment.novelPage.authors)); - - description.setText(novelFragment.novelPage.description); - - if (novelFragment.novelPage.artists != null && novelFragment.novelPage.artists.length > 0) - artists.setText(Arrays.toString(novelFragment.novelPage.artists)); - - status.setText(novelFragment.status.getStatus()); - if (novelFragment.novelPage.status != null) { - String s = "unknown"; - switch (novelFragment.novelPage.status) { - case PAUSED: - pStat.setText(R.string.paused); - s = "Paused"; - break; - case COMPLETED: - pStat.setText(R.string.completed); - s = "Completed"; - break; - case PUBLISHING: - pStat.setText(R.string.publishing); - s = "Publishing"; - break; - default: - pStat.setText(R.string.unknown); + if (novelFragment.getView() != null) + novelFragment.getView().post(() -> { + + if (novelFragment.novelPage == null) { + Log.e("NULL", "Invalid novel page"); + return; } - System.out.println("PS: " + s); - } - if (novelFragment.novelPage.genres != null && getContext() != null) { - LayoutInflater layoutInflater = LayoutInflater.from(getContext()); - for (String string : novelFragment.novelPage.genres) { - Chip chip = (Chip) layoutInflater.inflate(R.layout.genre_chip, null, false); - chip.setText(string); - genres.addView(chip); + + title.setText(novelFragment.novelPage.title); + + if (novelFragment.novelPage.authors != null && novelFragment.novelPage.authors.length > 0) + authors.setText(Arrays.toString(novelFragment.novelPage.authors)); + + description.setText(novelFragment.novelPage.description); + + if (novelFragment.novelPage.artists != null && novelFragment.novelPage.artists.length > 0) + artists.setText(Arrays.toString(novelFragment.novelPage.artists)); + + status.setText(novelFragment.status.getStatus()); + if (novelFragment.novelPage.status != null) { + String s = "unknown"; + switch (novelFragment.novelPage.status) { + case PAUSED: + pStat.setText(R.string.paused); + s = "Paused"; + break; + case COMPLETED: + pStat.setText(R.string.completed); + s = "Completed"; + break; + case PUBLISHING: + pStat.setText(R.string.publishing); + s = "Publishing"; + break; + default: + pStat.setText(R.string.unknown); + } + System.out.println("PS: " + s); } - } else genres.setVisibility(View.GONE); - - Picasso.get() - .load(novelFragment.novelPage.imageURL) - .into(imageView); - Picasso.get() - .load(novelFragment.novelPage.imageURL) - .into(imageView_background); - floatingActionButton.show(); - formatterName.setText(novelFragment.formatter.getName()); - }); + if (novelFragment.novelPage.genres != null && getContext() != null) { + LayoutInflater layoutInflater = LayoutInflater.from(getContext()); + for (String string : novelFragment.novelPage.genres) { + Chip chip = (Chip) layoutInflater.inflate(R.layout.genre_chip, null, false); + chip.setText(string); + genres.addView(chip); + } + } else genres.setVisibility(View.GONE); + + Picasso.get() + .load(novelFragment.novelPage.imageURL) + .into(imageView); + Picasso.get() + .load(novelFragment.novelPage.imageURL) + .into(imageView_background); + floatingActionButton.show(); + formatterName.setText(novelFragment.formatter.getName()); + }); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae82bb3c76..0db083976b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,6 +100,7 @@ Reader Default MarkDown reader + Chapters unread: From 4e446b4066ea61fc573051f93083fc64d373658e Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 1 Dec 2019 19:10:48 -0500 Subject: [PATCH 075/162] Working on removing random classes to stream line data, don't need complex data just floating if it isn't needed --- .../shosetsu/ui/library/LibraryFragment.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 81db759d39..1a7101aabd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -60,15 +60,14 @@ */ public class LibraryFragment extends Fragment { @NonNull - public ArrayList libraryNovelCards = new ArrayList<>(); - @Nullable - public ArrayList selectedNovels = new ArrayList<>(); + public ArrayList libraryNovelCards = new ArrayList<>(); + public ArrayList selectedNovels = new ArrayList<>(); public static boolean changedData = false; public boolean contains(@NonNull NovelCard novelCard) { - for (NovelCard n : selectedNovels) - if (n.novelURL.equalsIgnoreCase(novelCard.novelURL)) + for (Integer i : selectedNovels) + if (i == novelCard.novelID) return true; return false; } @@ -158,8 +157,15 @@ public void onResume() { @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putSerializable("selected", selectedNovels); - outState.putSerializable("lib", libraryNovelCards); + ArrayList novelIDs = new ArrayList<>(), selectedIDs = new ArrayList<>(); + + for (NovelCard novelCard : libraryNovelCards) + novelIDs.add(novelCard.novelID); + for (NovelCard novelCard : selectedNovels) + selectedIDs.add(novelCard.novelID); + + outState.putIntegerArrayList("selected", selectedIDs); + outState.putIntegerArrayList("lib", novelIDs); } /** @@ -178,8 +184,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c if (savedInstanceState == null) readFromDB(); else { - this.selectedNovels = (ArrayList) savedInstanceState.getSerializable("selected"); - this.libraryNovelCards = (ArrayList) savedInstanceState.getSerializable("lib"); + ArrayList novelIDs = savedInstanceState.getIntegerArrayList("lib"), selectedIDs = savedInstanceState.getIntegerArrayList("selected"); + + } View view = inflater.inflate(R.layout.fragment_library, container, false); recyclerView = view.findViewById(R.id.fragment_library_recycler); From ac217ebe9f9f529424adac8e3f52e0d6bea0e094 Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 1 Dec 2019 19:33:50 -0500 Subject: [PATCH 076/162] Lowered the unnecessary data usage at any given time for the library. Also added lower API support for searching --- .../apps/shosetsu/backend/Update_Manager.java | 2 +- .../shosetsu/backend/database/Database.java | 44 +++++++++++++++++++ .../shosetsu/ui/library/LibraryFragment.java | 43 ++++++++---------- .../library/adapter/LibraryNovelAdapter.java | 10 +++-- .../library/listener/LibrarySearchQuery.java | 14 ++++-- .../viewHolders/LibNovelViewHolder.java | 8 ++-- .../shosetsu/ui/updates/UpdatesFragment.java | 2 +- .../ui/updates/async/ChapterUpdater.java | 8 ++-- 8 files changed, 89 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java index 59ceb91b6b..018346b14a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Update_Manager.java @@ -36,7 +36,7 @@ public class Update_Manager { @Nullable private static ChapterUpdater chapterUpdater = null; - public static void init(@NonNull ArrayList novelCards, @NonNull Context context) { + public static void init(@NonNull ArrayList novelCards, @NonNull Context context) { if (chapterUpdater == null) { chapterUpdater = new ChapterUpdater(novelCards, context); chapterUpdater.execute(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index b3cce34a7b..6d20ca89a9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -918,6 +918,26 @@ public static ArrayList getLibrary() { } } + public static ArrayList getIntLibrary() { + Log.d("DL", "Getting"); + Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), + new String[]{Columns.PARENT_ID.toString()}, + Columns.BOOKMARKED + "=1", null, null, null, null); + + ArrayList novelCards = new ArrayList<>(); + if (cursor.getCount() <= 0) { + cursor.close(); + return new ArrayList<>(); + } else { + while (cursor.moveToNext()) { + int parent = cursor.getInt(cursor.getColumnIndex(Columns.PARENT_ID.toString())); + novelCards.add(parent); + } + cursor.close(); + return novelCards; + } + } + @Nullable public static NovelCard getNovel(int novelID) { Log.d("DL", "Getting"); @@ -947,6 +967,30 @@ novelID, getNovelURLfromNovelID(novelID), return null; } + + public static String getNovelTitle(int novelID) { + Log.d("DL", "Getting"); + + Cursor cursor = sqLiteDatabase.query(Tables.NOVELS.toString(), + new String[]{Columns.TITLE.toString()}, + Columns.BOOKMARKED + "=1 and " + Columns.PARENT_ID + "=" + novelID, null, null, null, null); + + if (cursor.getCount() <= 0) { + cursor.close(); + return "unknown"; + } else { + cursor.moveToNext(); + try { + String title = checkStringDeserialize(cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString()))); + cursor.close(); + return title; + } catch (Exception e) { + e.printStackTrace(); + } + } + return "unknown"; + } + /** * Gets saved novelPage * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 1a7101aabd..58df01c1fc 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -36,6 +36,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.calculateNoOfColumns; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getNovelTitle; /* * This file is part of Shosetsu. @@ -65,9 +66,9 @@ public class LibraryFragment extends Fragment { public static boolean changedData = false; - public boolean contains(@NonNull NovelCard novelCard) { - for (Integer i : selectedNovels) - if (i == novelCard.novelID) + public boolean contains(@NonNull int i) { + for (Integer I : selectedNovels) + if (I == i) return true; return false; } @@ -86,9 +87,9 @@ public LibraryFragment() { } private void readFromDB() { - libraryNovelCards = Database.DatabaseNovels.getLibrary(); + libraryNovelCards = Database.DatabaseNovels.getIntLibrary(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - libraryNovelCards.sort((novelCard, t1) -> novelCard.title.compareTo(t1.title)); + libraryNovelCards.sort((novel, t1) -> getNovelTitle(novel).compareTo(getNovelTitle(t1))); } else { bubbleSortA_Z(); } @@ -97,22 +98,22 @@ private void readFromDB() { private void bubbleSortA_Z() { for (int i = libraryNovelCards.size() - 1; i > 1; i--) { for (int j = 0; j < i; j++) { - if (libraryNovelCards.get(j).title.compareTo(libraryNovelCards.get(j + 1).title) > 0) + if (getNovelTitle(libraryNovelCards.get(j)).compareTo(getNovelTitle(libraryNovelCards.get(j + 1))) > 0) swapValues(j, j + 1); } } } private void swapValues(int indexOne, int indexTwo) { - NovelCard novelCard = libraryNovelCards.get(indexOne); + int i = libraryNovelCards.get(indexOne); libraryNovelCards.set(indexOne, libraryNovelCards.get(indexTwo)); - libraryNovelCards.set(indexTwo, novelCard); + libraryNovelCards.set(indexTwo, i); } /** * Sets the cards to display */ - public void setLibraryCards(ArrayList novelCards) { + public void setLibraryCards(ArrayList novelCards) { if (recyclerView != null) { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager library_layoutManager; @@ -148,7 +149,7 @@ public void onResume() { Log.d("Library", "Resumed"); if (LibraryFragment.changedData) { Log.d("Library", "Updating data"); - libraryNovelCards = Database.DatabaseNovels.getLibrary(); + libraryNovelCards = Database.DatabaseNovels.getIntLibrary(); changedData = !changedData; } libraryNovelCardsAdapter.notifyDataSetChanged(); @@ -157,15 +158,9 @@ public void onResume() { @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - ArrayList novelIDs = new ArrayList<>(), selectedIDs = new ArrayList<>(); - for (NovelCard novelCard : libraryNovelCards) - novelIDs.add(novelCard.novelID); - for (NovelCard novelCard : selectedNovels) - selectedIDs.add(novelCard.novelID); - - outState.putIntegerArrayList("selected", selectedIDs); - outState.putIntegerArrayList("lib", novelIDs); + outState.putIntegerArrayList("selected", selectedNovels); + outState.putIntegerArrayList("lib", libraryNovelCards); } /** @@ -228,9 +223,9 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { Update_Manager.init(libraryNovelCards, context); return true; case R.id.chapter_select_all: - for (NovelCard novelChapter : libraryNovelCards) - if (!contains(novelChapter)) - selectedNovels.add(novelChapter); + for (int i : libraryNovelCards) + if (!contains(i)) + selectedNovels.add(i); recyclerView.post(() -> libraryNovelCardsAdapter.notifyDataSetChanged()); return true; @@ -241,9 +236,9 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return true; case R.id.remove_from_library: - for (NovelCard novelCard : selectedNovels) { - Database.DatabaseNovels.unBookmark(novelCard.novelID); - libraryNovelCards.remove(novelCard); + for (int i : selectedNovels) { + Database.DatabaseNovels.unBookmark(i); + libraryNovelCards.remove(i); } selectedNovels = new ArrayList<>(); recyclerView.post(() -> libraryNovelCardsAdapter.notifyDataSetChanged()); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java index 81c1ae1acd..9d169bf5f7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/adapter/LibraryNovelAdapter.java @@ -19,6 +19,8 @@ import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getNovel; + /* * This file is part of Shosetsu. * @@ -42,9 +44,9 @@ */ public class LibraryNovelAdapter extends RecyclerView.Adapter { private final LibraryFragment libraryFragment; - private final ArrayList novelCards; + private final ArrayList novelCards; - public LibraryNovelAdapter(ArrayList novelCards, LibraryFragment libraryFragment) { + public LibraryNovelAdapter(ArrayList novelCards, LibraryFragment libraryFragment) { this.libraryFragment = libraryFragment; this.novelCards = novelCards; } @@ -58,7 +60,7 @@ public LibNovelViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i @Override public void onBindViewHolder(@NonNull LibNovelViewHolder libNovelViewHolder, int i) { - NovelCard novelCard = novelCards.get(i); + NovelCard novelCard = getNovel(novelCards.get(i)); //Sets values { Picasso.get() @@ -86,7 +88,7 @@ public void onBindViewHolder(@NonNull LibNovelViewHolder libNovelViewHolder, int libNovelViewHolder.chip.setText(String.valueOf(count)); } else libNovelViewHolder.chip.setVisibility(View.INVISIBLE); - if (libraryFragment.contains(novelCard)) { + if (libraryFragment.contains(novelCard.novelID)) { libNovelViewHolder.materialCardView.setStrokeWidth(Utilities.SELECTED_STROKE_WIDTH); } else { libNovelViewHolder.materialCardView.setStrokeWidth(0); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java index f5a813da69..a29aef702e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java @@ -11,6 +11,8 @@ import java.util.ArrayList; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getNovelTitle; + /* * This file is part of Shosetsu. * @@ -47,11 +49,15 @@ public boolean onQueryTextSubmit(String query) { @Override public boolean onQueryTextChange(@NonNull String newText) { Log.d("Library search", newText); - ArrayList recycleCards = new ArrayList<>(libraryFragment.libraryNovelCards); + ArrayList novelIDs = new ArrayList<>(libraryFragment.libraryNovelCards); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - recycleCards.removeIf(recycleCard -> !recycleCard.title.toLowerCase().contains(newText.toLowerCase())); + novelIDs.removeIf(novelID -> !getNovelTitle(novelID).toLowerCase().contains(newText.toLowerCase())); + } else { + for (int x = novelIDs.size() - 1; x >= 0; x--) + if (!getNovelTitle(novelIDs.get(x)).toLowerCase().contains(newText.toLowerCase())) + novelIDs.remove(x); } - libraryFragment.setLibraryCards(recycleCards); - return recycleCards.size() != 0; + libraryFragment.setLibraryCards(novelIDs); + return novelIDs.size() != 0; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java index 6d9bcd172a..be3035ccb7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/viewHolders/LibNovelViewHolder.java @@ -68,8 +68,8 @@ public LibNovelViewHolder(@NonNull View itemView) { } public void addToSelect() { - if (!libraryFragment.contains(novelCard)) - libraryFragment.selectedNovels.add(novelCard); + if (!libraryFragment.contains(novelCard.novelID)) + libraryFragment.selectedNovels.add(novelCard.novelID); else removeFromSelect(); @@ -79,9 +79,9 @@ public void addToSelect() { } private void removeFromSelect() { - if (libraryFragment.contains(novelCard)) + if (libraryFragment.contains(novelCard.novelID)) for (int x = 0; x < libraryFragment.selectedNovels.size(); x++) - if (libraryFragment.selectedNovels.get(x).novelURL.equalsIgnoreCase(novelCard.novelURL)) { + if (libraryFragment.selectedNovels.get(x) == novelCard.novelID) { libraryFragment.selectedNovels.remove(x); return; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java index 5b5cc61032..0854e2410b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java @@ -67,7 +67,7 @@ public UpdatesFragment() { public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.updater_now: - Update_Manager.init(Database.DatabaseNovels.getLibrary(), getContext()); + Update_Manager.init(Database.DatabaseNovels.getIntLibrary(), getContext()); return true; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java index fc022f251a..ea91d4a72b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/async/ChapterUpdater.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getNovelIDFromNovelURL; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getNovel; import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; /* @@ -52,7 +53,7 @@ public class ChapterUpdater extends AsyncTask { private static final String channel_ID = "shosetsu_updater"; @NonNull - private final ArrayList novelCards; + private final ArrayList novelCards; private boolean continueProcesss = true; @Nullable private final NotificationManager notificationManager; @@ -60,8 +61,7 @@ public class ChapterUpdater extends AsyncTask { private final ArrayList updatedNovels = new ArrayList<>(); - - public ChapterUpdater(@NotNull ArrayList novelCards, @NonNull Context context) { + public ChapterUpdater(@NotNull ArrayList novelCards, @NonNull Context context) { this.novelCards = novelCards; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); @@ -94,7 +94,7 @@ protected void onPreExecute() { @Override protected Void doInBackground(Void... voids) { for (int x = 0; x < novelCards.size(); x++) { - NovelCard novelCard = novelCards.get(x); + NovelCard novelCard = getNovel(novelCards.get(x)); builder.setContentText(novelCard.title); builder.setProgress(novelCards.size(), x + 1, false); notificationManager.notify(ID, builder.build()); From b0bac19dc33b1ce6eb18de761e40860478179a19 Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 1 Dec 2019 19:41:46 -0500 Subject: [PATCH 077/162] Comment change --- .../apps/shosetsu/ui/library/listener/LibrarySearchQuery.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java index a29aef702e..fd654197b3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/listener/LibrarySearchQuery.java @@ -29,6 +29,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 18 / 06 / 2019 * From 90858671f29070d81ee41cbe7e844d5a21dfdb41 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Thu, 5 Dec 2019 21:55:05 -0500 Subject: [PATCH 078/162] Working on new reader model --- .../shosetsu/ui/reader/ChapterReader.java | 42 +++------ .../apps/shosetsu/ui/reader/ChapterView.java | 86 +++++++++++++++++++ app/src/main/res/layout/chapter_reader.xml | 64 -------------- .../main/res/layout/chapter_reader_view.xml | 72 ++++++++++++++++ 4 files changed, 168 insertions(+), 96 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java create mode 100644 app/src/main/res/layout/chapter_reader_view.xml diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index f4804526bb..c44c8993c4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -7,8 +7,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.ProgressBar; -import android.widget.ScrollView; import android.widget.Toast; import androidx.annotation.NonNull; @@ -35,7 +33,6 @@ import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; -import com.google.android.material.chip.Chip; import org.jetbrains.annotations.NotNull; @@ -93,31 +90,23 @@ public class ChapterReader extends AppCompatActivity { // Order of values. Default, Markdown private final MenuItem[] readers = new MenuItem[2]; - public ScrollView scrollView; public Toolbar toolbar; - public ProgressBar progressBar; @Nullable - public String title, chapterURL, unformattedText = null, text = null; - public int chapterID, readerType, novelID; public boolean ready = false; //TODO Handle ERRORs on loading, EVERYWHERE - public ErrorView errorView; - private boolean bookmarked; @Nullable public Formatter formatter; private ViewPager readerViewPager; - private Chip nextChapter; @Nullable private String[] chapters; - private MenuItem bookmark, tap_to_scroll; + protected MenuItem bookmark; + protected int readerType, novelID; private Reader selectedReader = null; - //Tap to scroll - @SuppressWarnings("FieldCanBeLocal") - private View scroll_up, scroll_down; - + protected ChapterView currentChapter; + private MenuItem tap_to_scroll; /** * Save data of view before destroyed @@ -127,12 +116,8 @@ public class ChapterReader extends AppCompatActivity { @Override protected void onSaveInstanceState(@NotNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putString("unformattedText", text); - outState.putString("text", text); - outState.putInt("chapterID", chapterID); - outState.putString("chapterURL", chapterURL); + outState.putInt("formatter", formatter.getID()); - outState.putString("title", title); } /** @@ -152,9 +137,7 @@ public boolean onCreateOptionsMenu(@NonNull Menu menu) { // Bookmark { bookmark = menu.findItem(R.id.chapter_view_bookmark); - bookmarked = Database.DatabaseChapter.isBookMarked(chapterID); - if (bookmarked) - bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); + } @@ -253,8 +236,8 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { tap_to_scroll.setChecked(toggleTapToScroll()); return true; case R.id.chapter_view_bookmark: - bookmarked = toggleBookmarkChapter(chapterID); - if (bookmarked) + currentChapter.bookmarked = toggleBookmarkChapter(currentChapter.chapterID); + if (currentChapter.bookmarked) bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); return true; @@ -296,10 +279,10 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { return true; case R.id.browser: - openInBrowser(this, chapterURL); + openInBrowser(this, currentChapter.chapterURL); return true; case R.id.webview: - openInWebview(this, chapterURL); + openInWebview(this, currentChapter.chapterURL); return true; case R.id.reader_0: demarkMenuItems(readers, 0, demarkActions[3]); @@ -324,12 +307,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setContentView(R.layout.chapter_reader); // SetUp of data if (savedInstanceState != null) { - unformattedText = savedInstanceState.getString("unformattedText"); - title = savedInstanceState.getString("title"); - chapterID = savedInstanceState.getInt("chapterID"); - chapterURL = savedInstanceState.getString("chapterURL"); formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); - text = savedInstanceState.getString("text"); novelID = savedInstanceState.getInt("novelID"); chapters = savedInstanceState.getStringArray("chapters"); } else { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java new file mode 100644 index 0000000000..0e5597e22b --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -0,0 +1,86 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.ScrollView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.google.android.material.chip.Chip; + +/** + * shosetsu + * 05 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class ChapterView extends Fragment { + public ScrollView scrollView; + public ProgressBar progressBar; + public String title, chapterURL, unformattedText = null, text = null; + public int chapterID; + public ErrorView errorView; + protected boolean bookmarked; + ChapterReader chapterReader; + private Chip nextChapter; + //Tap to scroll + @SuppressWarnings("FieldCanBeLocal") + private View scroll_up, scroll_down; + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString("unformattedText", text); + outState.putString("text", text); + outState.putInt("chapterID", chapterID); + outState.putString("chapterURL", chapterURL); + outState.putString("title", title); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.chapter_reader_view, container, false); + if (savedInstanceState != null) { + unformattedText = savedInstanceState.getString("unformattedText"); + title = savedInstanceState.getString("title"); + chapterID = savedInstanceState.getInt("chapterID"); + chapterURL = savedInstanceState.getString("chapterURL"); + text = savedInstanceState.getString("text"); + } + + + bookmarked = Database.DatabaseChapter.isBookMarked(chapterID); + if (bookmarked) + chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); + else chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + + + return view; + } +} diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 22e438773b..4334d0bcdb 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -1,7 +1,6 @@ @@ -25,70 +24,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/chapter_reader_view.xml b/app/src/main/res/layout/chapter_reader_view.xml new file mode 100644 index 0000000000..e6920aad24 --- /dev/null +++ b/app/src/main/res/layout/chapter_reader_view.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From afc7ed4923fee44920cb98fa72d3576a6dd93b2c Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 6 Dec 2019 09:03:16 -0500 Subject: [PATCH 079/162] Working on ze refactoring --- .../apps/shosetsu/backend/Utilities.java | 46 ++--- .../apps/shosetsu/ui/main/MainActivity.java | 10 +- .../shosetsu/ui/reader/ChapterReader.java | 173 +++-------------- .../apps/shosetsu/ui/reader/ChapterView.java | 175 +++++++++++++++++- .../reader/adapters/ChapterReaderAdapter.java | 30 +++ .../subFragments/DownloadSettings.java | 4 +- app/src/main/res/layout/chapter_reader.xml | 6 +- 7 files changed, 255 insertions(+), 189 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index bebe81fbc7..1f3f1af61a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -260,11 +260,11 @@ public static String[] convertStringToArray(@NotNull String s) { // Preference objects - public static SharedPreferences download; - public static SharedPreferences view; - public static SharedPreferences advanced; - public static SharedPreferences tracking; - public static SharedPreferences backup; + public static SharedPreferences downloadPreferences; + public static SharedPreferences viewPreferences; + public static SharedPreferences advancedPreferences; + public static SharedPreferences trackingPreferences; + public static SharedPreferences backupPreferences; /** * Initializes the settings @@ -272,27 +272,27 @@ public static String[] convertStringToArray(@NotNull String s) { * @param */ public static void initPreferences(@NonNull AppCompatActivity mainActivity) { - Settings.ReaderTextColor = view.getInt("ReaderTextColor", Color.BLACK); - Settings.ReaderTextBackgroundColor = view.getInt("ReaderBackgroundColor", Color.WHITE); + Settings.ReaderTextColor = viewPreferences.getInt("ReaderTextColor", Color.BLACK); + Settings.ReaderTextBackgroundColor = viewPreferences.getInt("ReaderBackgroundColor", Color.WHITE); String dir = mainActivity.getExternalFilesDir(null).getAbsolutePath(); dir = dir.substring(0, dir.indexOf("/Android")); - shoDir = download.getString("dir", dir + "/Shosetsu/"); - Settings.downloadPaused = download.getBoolean("paused", false); - Settings.ReaderTextSize = view.getInt("ReaderTextSize", 14); - Settings.themeMode = advanced.getInt("themeMode", 0); - Settings.paragraphSpacing = view.getInt("paragraphSpacing", 1); - Settings.indentSize = view.getInt("indentSize", 1); + shoDir = downloadPreferences.getString("dir", dir + "/Shosetsu/"); + Settings.downloadPaused = downloadPreferences.getBoolean("paused", false); + Settings.ReaderTextSize = viewPreferences.getInt("ReaderTextSize", 14); + Settings.themeMode = advancedPreferences.getInt("themeMode", 0); + Settings.paragraphSpacing = viewPreferences.getInt("paragraphSpacing", 1); + Settings.indentSize = viewPreferences.getInt("indentSize", 1); } public static boolean toggleTapToScroll() { if (isTapToScroll()) - view.edit().putBoolean("tapToScroll", false).apply(); - else view.edit().putBoolean("tapToScroll", true).apply(); + viewPreferences.edit().putBoolean("tapToScroll", false).apply(); + else viewPreferences.edit().putBoolean("tapToScroll", true).apply(); return isTapToScroll(); } public static boolean isTapToScroll() { - return view.getBoolean("tapToScroll", false); + return viewPreferences.getBoolean("tapToScroll", false); } public static boolean intToBoolean(int a) { @@ -307,12 +307,12 @@ public static int booleanToInt(boolean a) { public static void changeIndentSize(int newIndent) { Settings.indentSize = newIndent; - view.edit().putInt("indentSize", newIndent).apply(); + viewPreferences.edit().putInt("indentSize", newIndent).apply(); } public static void changeParagraphSpacing(int newSpacing) { Settings.paragraphSpacing = newSpacing; - view.edit().putInt("paragraphSpacing", newSpacing).apply(); + viewPreferences.edit().putInt("paragraphSpacing", newSpacing).apply(); } @@ -320,7 +320,7 @@ public static void changeMode(@NonNull Activity activity, int newMode) { if (!(newMode >= 0 && newMode <= 2)) throw new IndexOutOfBoundsException("Non valid int passed"); Settings.themeMode = newMode; - advanced.edit() + advancedPreferences.edit() .putInt("themeMode", newMode) .apply(); setupTheme(activity); @@ -347,7 +347,7 @@ public static void setupTheme(Activity activity) { */ public static boolean togglePause() { Settings.downloadPaused = !Settings.downloadPaused; - download.edit() + downloadPreferences.edit() .putBoolean("paused", Settings.downloadPaused) .apply(); return Settings.downloadPaused; @@ -392,7 +392,7 @@ public static void unsetNightMode() { private static void setReaderColor(int text, int background) { Settings.ReaderTextColor = text; Settings.ReaderTextBackgroundColor = background; - view.edit() + viewPreferences.edit() .putInt("ReaderTextColor", text) .putInt("ReaderBackgroundColor", background) .apply(); @@ -440,7 +440,7 @@ public static boolean toggleBookmarkChapter(int chapterID) { public static void setTextSize(int size) { Settings.ReaderTextSize = size; - view.edit() + viewPreferences.edit() .putInt("ReaderTextSize", size) .apply(); } @@ -503,7 +503,7 @@ public static void wait(int time) { @SuppressWarnings({"EmptyMethod", "unused"}) public static boolean isTrackingEnabled() { - return tracking.getBoolean("enabled", false); + return trackingPreferences.getBoolean("enabled", false); } @SuppressWarnings({"EmptyMethod", "unused"}) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index e4604b2ef4..72f91a1e72 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -93,11 +93,11 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } - Utilities.view = getSharedPreferences("view", 0); - Utilities.download = getSharedPreferences("download", 0); - Utilities.advanced = getSharedPreferences("advanced", 0); - Utilities.tracking = getSharedPreferences("tracking", 0); - Utilities.backup = getSharedPreferences("backup", 0); + Utilities.viewPreferences = getSharedPreferences("view", 0); + Utilities.downloadPreferences = getSharedPreferences("download", 0); + Utilities.advancedPreferences = getSharedPreferences("advanced", 0); + Utilities.trackingPreferences = getSharedPreferences("tracking", 0); + Utilities.backupPreferences = getSharedPreferences("backup", 0); initPreferences(this); setupTheme(this); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index c44c8993c4..1b184e11f3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -13,6 +13,8 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; @@ -21,6 +23,7 @@ import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ChapterReaderAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; @@ -80,7 +83,10 @@ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; - private final ArrayList fragments = new ArrayList<>(); + public String[] chapterURLs; + public final ArrayList chapters = new ArrayList<>(); + + // Order of values. Small,Medium,Large private final MenuItem[] textSizes = new MenuItem[3]; // Order of values. Non,Small,Medium,Large @@ -91,20 +97,16 @@ public class ChapterReader extends AppCompatActivity { private final MenuItem[] readers = new MenuItem[2]; public Toolbar toolbar; - @Nullable - public boolean ready = false; - //TODO Handle ERRORs on loading, EVERYWHERE + ViewPager chapterPager; - @Nullable public Formatter formatter; - private ViewPager readerViewPager; - @Nullable - private String[] chapters; protected MenuItem bookmark; protected int readerType, novelID; private Reader selectedReader = null; + public ChapterView currentView; + protected ChapterView currentChapter; private MenuItem tap_to_scroll; @@ -225,10 +227,10 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { case R.id.chapter_view_nightMode: if (!item.isChecked()) { swapReaderColor(); - setUpReader(); + currentView.setUpReader(); } else { swapReaderColor(); - setUpReader(); + currentView.setUpReader(); } item.setChecked(!item.isChecked()); return true; @@ -306,12 +308,15 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setupTheme(this); setContentView(R.layout.chapter_reader); // SetUp of data + String chapterURL = null, title = null; + int chapterID = -1; + if (savedInstanceState != null) { formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); novelID = savedInstanceState.getInt("novelID"); - chapters = savedInstanceState.getStringArray("chapters"); + chapterURLs = savedInstanceState.getStringArray("chapters"); } else { - chapters = getIntent().getStringArrayExtra("chapters"); + chapterURLs = getIntent().getStringArrayExtra("chapters"); chapterID = getIntent().getIntExtra("chapterID", -1); chapterURL = getIntent().getStringExtra("chapterURL"); title = getIntent().getStringExtra("title"); @@ -321,22 +326,15 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { assert chapterURL != null; ASSERT(chapterID != -1); - assert chapters != null; - Log.i("Reading", chapterURL); + + Log.i("Reading", chapterURL); // Declares view variables { - errorView = new ErrorView(this, findViewById(R.id.network_error), findViewById(R.id.error_message), findViewById(R.id.error_button)); - progressBar = findViewById(R.id.fragment_novel_chapter_view_progress); - scrollView = findViewById(R.id.fragment_novel_scroll); toolbar = findViewById(R.id.toolbar); - readerViewPager = findViewById(R.id.readerPager); - scroll_up = findViewById(R.id.scroll_up); - scroll_down = findViewById(R.id.scroll_down); - nextChapter = findViewById(R.id.next_chapter); + chapterPager = findViewById(R.id.viewpager); } - addBottomListener(); setSupportActionBar(toolbar); @@ -357,140 +355,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } setViewPager(); - // Scroll up listener - scroll_up.setOnClickListener(view -> scrollUp()); - // Scroll down listener - scroll_down.setOnClickListener(view -> scrollDown()); - nextChapter.setOnClickListener(view -> { - NovelChapter novelChapter = getNextChapter(chapterURL, chapters); - if (novelChapter != null) { - if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { - title = novelChapter.title; - chapterURL = novelChapter.link; - loadChapter(); - } else - Toast.makeText(getApplicationContext(), "No more chapters!", Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(getApplicationContext(), "Cannot move to next chapter, Please exit reader", Toast.LENGTH_LONG).show(); - } - nextChapter.setVisibility(View.GONE); - }); - loadChapter(); - } - /** - * Changes the theme of the reader - * TODO change the scroll position bars color - */ - public void setUpReader() { - scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); - if (unformattedText != null) { - StringBuilder replaceSpacing = new StringBuilder("\n"); - for (int x = 0; x < Settings.paragraphSpacing; x++) - replaceSpacing.append("\n"); - - for (int x = 0; x < Settings.indentSize; x++) - replaceSpacing.append("\t"); - - text = unformattedText.replaceAll("\n", replaceSpacing.toString()); - assert selectedReader.getView() != null; - selectedReader.getView().post(() -> selectedReader.setText(text)); - } } private void setViewPager() { - ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getSupportFragmentManager(), fragments); - readerViewPager.setAdapter(pagerAdapter); - } - - /** - * What to do when scroll hits bottom - */ - private void bottom() { - int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); - if (ready) - if ((scrollView.getScrollY() / (float) total) < .99) { - int y = scrollView.getScrollY(); - if (y % 5 == 0) { - // Log.d("YMAX", String.valueOf(total)); - // Log.d("YC", String.valueOf(y)); - // Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); - - // Log.d("TY", String.valueOf(textView.getScrollY())); - - if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterID) != Status.READ) - Database.DatabaseChapter.updateY(chapterID, y); - } - } else { - Log.i("Scroll", "Marking chapter as READ"); - if (chapterURL != null) { - Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); - Database.DatabaseChapter.updateY(chapterID, 0); - nextChapter.setVisibility(View.VISIBLE); - } - //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) - } - } - - /** - * Loads the chapter to be read - */ - private void loadChapter() { - ready = false; - if (Database.DatabaseChapter.isSaved(chapterID)) { - unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterID)); - setUpReader(); - scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterID))); - if (getSupportActionBar() != null) - getSupportActionBar().setTitle(title); - ready = true; - } else if (chapterURL != null) { - unformattedText = ""; - setUpReader(); - new ReaderViewLoader(this).execute(); - } - - Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); - } - - /** - * Scrolls the text upwards - */ - private void scrollUp() { - if (isTapToScroll()) { - Log.i("Scroll", "Up"); - int y = scrollView.getScrollY(); - if (y - 100 > 0) - y -= 100; - else y = 0; - scrollView.smoothScrollTo(0, y); - } + ChapterReaderAdapter pagerAdapter = new ChapterReaderAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, this); + chapterPager.setAdapter(pagerAdapter); } - /** - * Scrolls the text downwards - */ - private void scrollDown() { - if (isTapToScroll()) { - Log.i("Scroll", "Down"); - int y = scrollView.getScrollY(); - int my = scrollView.getMaxScrollAmount(); - if (y + 100 < my) - y += 100; - else y = my; - scrollView.smoothScrollTo(0, y); - } - } - - /** - * Sets up the hitting bottom listener - */ - private void addBottomListener() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> bottom()); - } else { - scrollView.getViewTreeObserver().addOnScrollChangedListener(this::bottom); - } - } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 0e5597e22b..2d4ab1b5a8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -17,22 +17,38 @@ * ==================================================================== */ +import android.os.Build; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.ScrollView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; +import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.chip.Chip; +import java.util.ArrayList; +import java.util.Objects; + +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; + /** * shosetsu * 05 / 12 / 2019 @@ -40,12 +56,17 @@ * @author github.com/doomsdayrs */ public class ChapterView extends Fragment { + private ViewPager readerViewPager; + private final ArrayList fragments = new ArrayList<>(); + + public ScrollView scrollView; public ProgressBar progressBar; public String title, chapterURL, unformattedText = null, text = null; public int chapterID; public ErrorView errorView; - protected boolean bookmarked; + protected boolean bookmarked, ready = false; + ChapterReader chapterReader; private Chip nextChapter; //Tap to scroll @@ -65,7 +86,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.chapter_reader_view, container, false); + View chapterView = inflater.inflate(R.layout.chapter_reader_view, container, false); if (savedInstanceState != null) { unformattedText = savedInstanceState.getString("unformattedText"); title = savedInstanceState.getString("title"); @@ -74,6 +95,13 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c text = savedInstanceState.getString("text"); } + errorView = new ErrorView(chapterReader, chapterView.findViewById(R.id.network_error), chapterView.findViewById(R.id.error_message), chapterView.findViewById(R.id.error_button)); + progressBar = chapterView.findViewById(R.id.fragment_novel_chapter_view_progress); + scrollView = chapterView.findViewById(R.id.fragment_novel_scroll); + readerViewPager = chapterView.findViewById(R.id.readerPager); + scroll_up = chapterView.findViewById(R.id.scroll_up); + scroll_down = chapterView.findViewById(R.id.scroll_down); + nextChapter = chapterView.findViewById(R.id.next_chapter); bookmarked = Database.DatabaseChapter.isBookMarked(chapterID); if (bookmarked) @@ -81,6 +109,147 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c else chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); - return view; + addBottomListener(); + setViewPager(); + + // Scroll up listener + scroll_up.setOnClickListener(view -> scrollUp()); + // Scroll down listener + scroll_down.setOnClickListener(view -> scrollDown()); + nextChapter.setOnClickListener(view -> { + NovelChapter novelChapter = getNextChapter(chapterURL, chapterReader.chapterURLs); + if (novelChapter != null) { + if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { + title = novelChapter.title; + chapterURL = novelChapter.link; + loadChapter(); + } else + Toast.makeText(chapterReader.getApplicationContext(), "No more chapters!", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(chapterReader.getApplicationContext(), "Cannot move to next chapter, Please exit reader", Toast.LENGTH_LONG).show(); + } + nextChapter.setVisibility(View.GONE); + }); + loadChapter(); + + return chapterView; + } + + + /** + * Changes the theme of the reader + * TODO change the scroll position bars color + */ + public void setUpReader() { + scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + if (unformattedText != null) { + StringBuilder replaceSpacing = new StringBuilder("\n"); + for (int x = 0; x < Settings.paragraphSpacing; x++) + replaceSpacing.append("\n"); + + for (int x = 0; x < Settings.indentSize; x++) + replaceSpacing.append("\t"); + + text = unformattedText.replaceAll("\n", replaceSpacing.toString()); + assert selectedReader.getView() != null; + selectedReader.getView().post(() -> selectedReader.setText(text)); + } + } + + /** + * Loads the chapter to be read + */ + private void loadChapter() { + ready = false; + if (Database.DatabaseChapter.isSaved(chapterID)) { + unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterID)); + setUpReader(); + scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterID))); + if (chapterReader.getSupportActionBar() != null) + chapterReader.getSupportActionBar().setTitle(title); + ready = true; + } else if (chapterURL != null) { + unformattedText = ""; + setUpReader(); + new ReaderViewLoader(this).execute(); + } + + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); + } + + + /** + * Scrolls the text upwards + */ + private void scrollUp() { + if (isTapToScroll()) { + Log.i("Scroll", "Up"); + int y = scrollView.getScrollY(); + if (y - 100 > 0) + y -= 100; + else y = 0; + scrollView.smoothScrollTo(0, y); + } + } + + /** + * Scrolls the text downwards + */ + private void scrollDown() { + if (isTapToScroll()) { + Log.i("Scroll", "Down"); + int y = scrollView.getScrollY(); + int my = scrollView.getMaxScrollAmount(); + if (y + 100 < my) + y += 100; + else y = my; + scrollView.smoothScrollTo(0, y); + } + } + + /** + * What to do when scroll hits bottom + */ + private void bottom() { + int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); + if (ready) + if ((scrollView.getScrollY() / (float) total) < .99) { + int y = scrollView.getScrollY(); + if (y % 5 == 0) { + // Log.d("YMAX", String.valueOf(total)); + // Log.d("YC", String.valueOf(y)); + // Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); + + // Log.d("TY", String.valueOf(textView.getScrollY())); + + if (chapterURL != null && Database.DatabaseChapter.getStatus(chapterID) != Status.READ) + Database.DatabaseChapter.updateY(chapterID, y); + } + } else { + Log.i("Scroll", "Marking chapter as READ"); + if (chapterURL != null) { + Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); + Database.DatabaseChapter.updateY(chapterID, 0); + nextChapter.setVisibility(View.VISIBLE); + } + //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) + } + } + + + /** + * Sets up the hitting bottom listener + */ + private void addBottomListener() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> bottom()); + } else { + scrollView.getViewTreeObserver().addOnScrollChangedListener(this::bottom); + } + } + + private void setViewPager() { + ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); + readerViewPager.setAdapter(pagerAdapter); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java new file mode 100644 index 0000000000..3d175b7eb3 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java @@ -0,0 +1,30 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; + + +public class ChapterReaderAdapter extends FragmentPagerAdapter { + private final ChapterReader chapterReader; + + public ChapterReaderAdapter(@NonNull FragmentManager fm, int behavior, ChapterReader chapterReader) { + super(fm, behavior); + this.chapterReader = chapterReader; + } + + @NonNull + @Override + public Fragment getItem(int position) { + chapterReader.currentView = chapterReader.chapters.get(position); + return chapterReader.currentView; + } + + @Override + public int getCount() { + return chapterReader.chapters.size(); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java index cdf53429fd..0c537c2760 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/subFragments/DownloadSettings.java @@ -39,7 +39,7 @@ import java.util.Objects; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.download; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.downloadPreferences; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.shoDir; public class DownloadSettings extends Fragment { @@ -61,7 +61,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } private void setDir(String dir) { - download.edit().putString("dir", dir).apply(); + downloadPreferences.edit().putString("dir", dir).apply(); shoDir = dir; textView.setText(dir); } diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 4334d0bcdb..788e644853 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -22,11 +22,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - - - + app:layout_constraintTop_toTopOf="parent" /> Date: Fri, 6 Dec 2019 12:31:18 -0500 Subject: [PATCH 080/162] Adjusting.. --- .../shosetsu/ui/reader/ChapterReader.java | 78 ++++++++----------- .../apps/shosetsu/ui/reader/ChapterView.java | 35 ++++++++- .../reader/adapters/ChapterReaderAdapter.java | 1 + .../ui/reader/async/ReaderViewLoader.java | 21 ++--- 4 files changed, 77 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 1b184e11f3..40e196147f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -1,46 +1,32 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader; -import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentPagerAdapter; import androidx.viewpager.widget.ViewPager; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; -import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ChapterReaderAdapter; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ParaSpacingChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ReaderChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.TextSizeChange; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.MarkdownViewReader; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.TextViewReader; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; -import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.ASSERT; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; @@ -54,7 +40,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; -import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; +import static java.util.Arrays.binarySearch; /* * This file is part of Shosetsu. @@ -83,7 +69,9 @@ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; - public String[] chapterURLs; + public int[] chapterIDs; + public int currentChapterID; + public final ArrayList chapters = new ArrayList<>(); @@ -104,7 +92,6 @@ public class ChapterReader extends AppCompatActivity { public Formatter formatter; protected MenuItem bookmark; protected int readerType, novelID; - private Reader selectedReader = null; public ChapterView currentView; protected ChapterView currentChapter; @@ -308,59 +295,58 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setupTheme(this); setContentView(R.layout.chapter_reader); // SetUp of data - String chapterURL = null, title = null; - int chapterID = -1; if (savedInstanceState != null) { formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); novelID = savedInstanceState.getInt("novelID"); - chapterURLs = savedInstanceState.getStringArray("chapters"); + chapterIDs = savedInstanceState.getIntArray("chapters"); } else { - chapterURLs = getIntent().getStringArrayExtra("chapters"); - chapterID = getIntent().getIntExtra("chapterID", -1); - chapterURL = getIntent().getStringExtra("chapterURL"); - title = getIntent().getStringExtra("title"); + chapterIDs = getIntent().getIntArrayExtra("chapters"); + { + String chapterURL = null, title = null; + int chapterID = -1; + + chapterID = getIntent().getIntExtra("chapterID", -1); + chapterURL = getIntent().getStringExtra("chapterURL"); + title = getIntent().getStringExtra("title"); + + assert chapterURL != null; + ASSERT(chapterID != -1); + Log.i("Reading", chapterURL); + + chapters.add(new ChapterView(title, chapterURL, chapterID)); + } novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } - assert chapterURL != null; - ASSERT(chapterID != -1); + + if (chapterIDs != null) + chapterIDs = new int[]{0, 1}; + //TODO Get chapterID of novel via ID + + for (int id : chapterIDs) + chapters.add(new ChapterView(id)); - Log.i("Reading", chapterURL); // Declares view variables { toolbar = findViewById(R.id.toolbar); chapterPager = findViewById(R.id.viewpager); } - - setSupportActionBar(toolbar); - - fragments.add(new TextViewReader(this)); - fragments.add(new MarkdownViewReader(this)); - - switch (readerType) { - case 1: - selectedReader = fragments.get(1); - break; - case 0: - case -1: - selectedReader = fragments.get(0); - break; - case -2: - default: - throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); - } setViewPager(); - } private void setViewPager() { ChapterReaderAdapter pagerAdapter = new ChapterReaderAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, this); chapterPager.setAdapter(pagerAdapter); + chapterPager.setCurrentItem(getPosition()); + } + + public int getPosition() { + return binarySearch(chapterIDs, currentChapterID); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 2d4ab1b5a8..64d679dcc4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -38,7 +38,9 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ReaderTypeAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.MarkdownViewReader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.Reader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.readers.TextViewReader; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.chip.Chip; @@ -47,6 +49,7 @@ import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; /** @@ -58,6 +61,7 @@ public class ChapterView extends Fragment { private ViewPager readerViewPager; private final ArrayList fragments = new ArrayList<>(); + private Reader selectedReader = null; public ScrollView scrollView; @@ -65,14 +69,26 @@ public class ChapterView extends Fragment { public String title, chapterURL, unformattedText = null, text = null; public int chapterID; public ErrorView errorView; - protected boolean bookmarked, ready = false; + protected boolean bookmarked; + public boolean ready = false; - ChapterReader chapterReader; + public ChapterReader chapterReader; private Chip nextChapter; //Tap to scroll @SuppressWarnings("FieldCanBeLocal") private View scroll_up, scroll_down; + public ChapterView(int chapterID) { + this.chapterID = chapterID; + chapterURL = getChapterURLFromChapterID(chapterID); + } + + public ChapterView(String title, String chapterURL, int chapterID) { + this.title = title; + this.chapterURL = chapterURL; + this.chapterID = chapterID; + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -108,6 +124,21 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); else chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + fragments.add(new TextViewReader(chapterReader)); + fragments.add(new MarkdownViewReader(chapterReader)); + + switch (chapterReader.readerType) { + case 1: + selectedReader = fragments.get(1); + break; + case 0: + case -1: + selectedReader = fragments.get(0); + break; + case -2: + default: + throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); + } addBottomListener(); setViewPager(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java index 3d175b7eb3..d77fb7e53e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java @@ -16,6 +16,7 @@ public ChapterReaderAdapter(@NonNull FragmentManager fm, int behavior, ChapterRe this.chapterReader = chapterReader; } + @NonNull @Override public Fragment getItem(int position) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index 8f22c8c67d..f89b7730eb 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -8,6 +8,7 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterView; import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; @@ -38,29 +39,29 @@ public class ReaderViewLoader extends AsyncTask { */ @SuppressLint("StaticFieldLeak") private final - ChapterReader chapterReader; + ChapterView chapterReader; /** * Constructor */ - public ReaderViewLoader(ChapterReader chapterReader) { + public ReaderViewLoader(ChapterView chapterReader) { this.chapterReader = chapterReader; } @Nullable @Override protected String doInBackground(ChapterReader... chapterReaders) { - chapterReader.runOnUiThread(() -> chapterReader.errorView.errorView.setVisibility(View.GONE)); + chapterReader.chapterReader.runOnUiThread(() -> chapterReader.errorView.errorView.setVisibility(View.GONE)); try { - chapterReader.unformattedText = chapterReader.formatter.getNovelPassage(docFromURL(chapterReader.chapterURL, chapterReader.formatter.hasCloudFlare())); - chapterReader.runOnUiThread(chapterReader::setUpReader); - chapterReader.runOnUiThread(() -> + chapterReader.unformattedText = chapterReader.chapterReader.formatter.getNovelPassage(docFromURL(chapterReader.chapterURL, chapterReader.chapterReader.formatter.hasCloudFlare())); + chapterReader.chapterReader.runOnUiThread(chapterReader::setUpReader); + chapterReader.chapterReader.runOnUiThread(() -> chapterReader.scrollView.post(() -> chapterReader.scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterReader.chapterID))) ); - chapterReader.runOnUiThread(() -> chapterReader.ready = true); + chapterReader.chapterReader.runOnUiThread(() -> chapterReader.ready = true); } catch (Exception e) { - chapterReader.runOnUiThread(() -> { + chapterReader.chapterReader.runOnUiThread(() -> { chapterReader.errorView.errorView.setVisibility(View.VISIBLE); chapterReader.errorView.errorMessage.setText(e.getMessage()); chapterReader.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterReader).execute()); @@ -92,7 +93,7 @@ protected void onPostExecute(String s) { if (chapterReader.progressBar != null) chapterReader.progressBar.setVisibility(View.GONE); - if (chapterReader.getSupportActionBar() != null) - chapterReader.getSupportActionBar().setTitle(chapterReader.title); + if (chapterReader.chapterReader.getSupportActionBar() != null) + chapterReader.chapterReader.getSupportActionBar().setTitle(chapterReader.title); } } \ No newline at end of file From 19a9a3d462de5ceaaf99c094f1d2462fe8f7f5bf Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 6 Dec 2019 13:54:06 -0500 Subject: [PATCH 081/162] Working on a nearly complete build --- .../apps/shosetsu/ui/novel/NovelFragment.java | 13 ++++++----- .../shosetsu/ui/reader/ChapterReader.java | 23 +++++++++++-------- .../apps/shosetsu/ui/reader/ChapterView.java | 14 +++++------ .../ui/reader/demarkActions/IndentChange.java | 2 +- .../demarkActions/ParaSpacingChange.java | 2 +- .../ui/reader/demarkActions/ReaderChange.java | 2 +- .../reader/demarkActions/TextSizeChange.java | 2 +- 7 files changed, 31 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 9b71c580f3..59a356b624 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -35,6 +35,7 @@ import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isOnline; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.getChapter; /* * This file is part of Shosetsu. @@ -78,20 +79,20 @@ public class NovelFragment extends Fragment { * @return chapter after the input, returns the current chapter if no more */ @Nullable - public static NovelChapter getNextChapter(@NotNull String chapterURL, @Nullable String[] novelChapters) { + public static NovelChapter getNextChapter(@NotNull int chapterURL, @Nullable int[] novelChapters) { if (novelChapters != null && novelChapters.length != 0) for (int x = 0; x < novelChapters.length; x++) { - if (novelChapters[x].equalsIgnoreCase(chapterURL)) { + if (novelChapters[x] == chapterURL) { if (NovelFragmentChapters.reversed) { if (x - 1 != -1) - return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x - 1])); + return getChapter((novelChapters[x - 1])); else - return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x])); + return getChapter((novelChapters[x])); } else { if (x + 1 != novelChapters.length) - return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x + 1])); + return getChapter((novelChapters[x + 1])); else - return Database.DatabaseChapter.getChapter(Database.DatabaseIdentification.getChapterIDFromChapterURL(novelChapters[x])); + return getChapter((novelChapters[x])); } } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 40e196147f..522c2ea740 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -16,6 +16,7 @@ import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.ChapterReaderAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ParaSpacingChange; @@ -91,7 +92,8 @@ public class ChapterReader extends AppCompatActivity { public Formatter formatter; protected MenuItem bookmark; - protected int readerType, novelID; + public int readerType; + public int novelID; public ChapterView currentView; protected ChapterView currentChapter; @@ -126,8 +128,11 @@ public boolean onCreateOptionsMenu(@NonNull Menu menu) { // Bookmark { bookmark = menu.findItem(R.id.chapter_view_bookmark); - - + currentView.bookmarked = Database.DatabaseChapter.isBookMarked(currentView.chapterID); + if (currentView.bookmarked) + currentView.chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); + else + currentView.chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); } // Tap To Scroll @@ -303,8 +308,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } else { chapterIDs = getIntent().getIntArrayExtra("chapters"); { - String chapterURL = null, title = null; - int chapterID = -1; + String chapterURL, title; + int chapterID; chapterID = getIntent().getIntExtra("chapterID", -1); chapterURL = getIntent().getStringExtra("chapterURL"); @@ -314,19 +319,20 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { ASSERT(chapterID != -1); Log.i("Reading", chapterURL); - chapters.add(new ChapterView(title, chapterURL, chapterID)); + chapters.add(new ChapterView(this, title, chapterURL, chapterID)); } novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } - if (chapterIDs != null) + if (chapterIDs == null) chapterIDs = new int[]{0, 1}; + //TODO Get chapterID of novel via ID for (int id : chapterIDs) - chapters.add(new ChapterView(id)); + chapters.add(new ChapterView(this, id)); // Declares view variables @@ -336,7 +342,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } setSupportActionBar(toolbar); setViewPager(); - } private void setViewPager() { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 64d679dcc4..1e13d84b16 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -78,12 +78,15 @@ public class ChapterView extends Fragment { @SuppressWarnings("FieldCanBeLocal") private View scroll_up, scroll_down; - public ChapterView(int chapterID) { + public ChapterView(ChapterReader chapterReader,int chapterID) { + this.chapterReader = chapterReader; this.chapterID = chapterID; chapterURL = getChapterURLFromChapterID(chapterID); } - public ChapterView(String title, String chapterURL, int chapterID) { + public ChapterView(ChapterReader chapterReader,String title, String chapterURL, int chapterID) { + this.chapterReader = chapterReader; + this.title = title; this.chapterURL = chapterURL; this.chapterID = chapterID; @@ -119,14 +122,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c scroll_down = chapterView.findViewById(R.id.scroll_down); nextChapter = chapterView.findViewById(R.id.next_chapter); - bookmarked = Database.DatabaseChapter.isBookMarked(chapterID); - if (bookmarked) - chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); - else chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); fragments.add(new TextViewReader(chapterReader)); fragments.add(new MarkdownViewReader(chapterReader)); - switch (chapterReader.readerType) { case 1: selectedReader = fragments.get(1); @@ -148,7 +146,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c // Scroll down listener scroll_down.setOnClickListener(view -> scrollDown()); nextChapter.setOnClickListener(view -> { - NovelChapter novelChapter = getNextChapter(chapterURL, chapterReader.chapterURLs); + NovelChapter novelChapter = getNextChapter(chapterID, chapterReader.chapterIDs); if (novelChapter != null) { if (!novelChapter.link.equalsIgnoreCase(chapterURL)) { title = novelChapter.title; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java index 73311bbd76..d0806c6812 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java @@ -15,6 +15,6 @@ public IndentChange(ChapterReader chapterReader) { @Override public void action(int spared) { changeIndentSize(spared); - chapterReader.setUpReader(); + chapterReader.currentView.setUpReader(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java index 73b1ad2ebc..465456ad8e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java @@ -15,7 +15,7 @@ public ParaSpacingChange(ChapterReader chapterReader) { @Override public void action(int spared) { changeParagraphSpacing(spared); - chapterReader. setUpReader(); + chapterReader.currentView.setUpReader(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java index 1e5a3e7177..91d97105ff 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java @@ -16,7 +16,7 @@ public ReaderChange(ChapterReader chapterReader) { public void action(int spared) { chapterReader.readerType = spared; setReaderType(chapterReader.novelID, spared); - chapterReader.setUpReader(); + chapterReader.currentView.setUpReader(); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java index f1e44cf23f..1270bdc3ea 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java @@ -17,6 +17,6 @@ public TextSizeChange(ChapterReader chapterReader) { public void action(int spared) { int[] a = {14, 17, 20}; setTextSize(a[spared]); - chapterReader.setUpReader(); + chapterReader.currentView.setUpReader(); } } From 36df80fbf2a946c1b585a6db4924d984ec9e73b0 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 6 Dec 2019 16:14:49 -0500 Subject: [PATCH 082/162] New android version, Working on 4.0 Canary, Pushing through with ChapterReader redesign --- app/build.gradle | 6 +-- .../shosetsu/backend/database/Database.java | 40 +++++++++++++++++++ .../shosetsu/ui/reader/ChapterReader.java | 17 ++++++-- build.gradle | 2 +- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a55a47c16f..a3f8a3e889 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,19 +48,19 @@ repositories { dependencies { implementation 'com.google.android.material:material:1.2.0-alpha02' - implementation 'com.graphql-java:graphql-java:2019-11-07T04-06-09-70d9412' + implementation 'com.graphql-java:graphql-java:2019-11-19T08-52-32-b46beb9' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible implementation 'com.google.android.material:material:1.2.0-alpha02' - testImplementation 'junit:junit:4.13-rc-1' + testImplementation 'junit:junit:4.13-rc-2' testImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'com.github.Doomsdayrs:shosetsu-extensions:0.1.5' - implementation 'com.github.Doomsdayrs:shosetsu-services:v0.1.4' + implementation 'com.github.Doomsdayrs:shosetsu-services:0.1.4' implementation 'com.squareup.picasso:picasso:2.71828' diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 6d20ca89a9..8453abe546 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -717,6 +717,46 @@ public static List getChapters(int novelID) { } } + /** + * Gets chapters of a novel + * + * @param novelID ID to retrieve from + * @return List of chapters saved of novel (ID only) + */ + @Nullable + public static List getChaptersOnlyIDs(int novelID) { + Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); + if (cursor.getCount() <= 0) { + cursor.close(); + return null; + } else { + ArrayList novelChapters = new ArrayList<>(); + while (cursor.moveToNext()) { + try { + int id = cursor.getInt(cursor.getColumnIndex(Columns.ID.toString())); + MicroNovelChapter novelChapter = new MicroNovelChapter(); + novelChapter.id = id; + novelChapter.order = cursor.getDouble(cursor.getColumnIndex(Columns.ORDER.toString())); + novelChapters.add(novelChapter); + } catch (Exception e) { + e.printStackTrace(); + } + } + cursor.close(); + Collections.sort(novelChapters, (novelChapter, t1) -> Double.compare(novelChapter.order, t1.order)); + + ArrayList integers = new ArrayList<>(); + for (MicroNovelChapter novelChapter : novelChapters) + integers.add(novelChapter.id); + return integers; + } + } + + private static class MicroNovelChapter { + double order; + int id; + } + /** * Gets a chapter by it's URL * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 522c2ea740..ab4ff11738 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.List; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.ASSERT; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; @@ -40,6 +41,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.swapReaderColor; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.getChaptersOnlyIDs; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; import static java.util.Arrays.binarySearch; @@ -326,10 +328,17 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } - if (chapterIDs == null) - chapterIDs = new int[]{0, 1}; - - //TODO Get chapterID of novel via ID + if (chapterIDs == null) { + List integers = getChaptersOnlyIDs(novelID); + if (integers != null) { + chapterIDs = new int[integers.size()]; + int y = 0; + for (int x = 1; x < integers.size(); x++) { + chapterIDs[x] = integers.get(y); + y++; + } + } else chapterIDs = new int[]{chapters.get(0).chapterID}; + } for (int id : chapterIDs) chapters.add(new ChapterView(this, id)); diff --git a/build.gradle b/build.gradle index 27366f5668..5c71b612f9 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.6.0-beta04' + classpath 'com.android.tools.build:gradle:4.0.0-alpha05' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From 4d1eea4e9d61ac31b1746650695432b6435263df Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sun, 8 Dec 2019 11:50:45 -0500 Subject: [PATCH 083/162] I have no idea what to do ;-; --- .../shosetsu/backend/database/Database.java | 2 +- .../shosetsu/ui/reader/ChapterReader.java | 9 ++-- .../apps/shosetsu/ui/reader/ChapterView.java | 42 +++++++++---------- .../ui/reader/async/ReaderViewLoader.java | 40 +++++++++--------- .../ui/reader/readers/MarkdownViewReader.java | 9 +++- .../shosetsu/ui/reader/readers/Reader.java | 1 + .../ui/reader/readers/TextViewReader.java | 10 ++++- app/src/main/res/layout/chapter_reader.xml | 18 +------- .../main/res/layout/chapter_reader_view.xml | 23 +++++++++- .../main/res/menu/toolbar_chapter_view.xml | 2 + 10 files changed, 90 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 8453abe546..7ecc14224d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -825,7 +825,7 @@ public static boolean isBookmarked(int novelID) { } public static void setReaderType(@NotNull int novelID, int reader) { - sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.ID + "=" + novelID); + sqLiteDatabase.execSQL("update " + Tables.NOVELS + " set " + Columns.READER_TYPE + "=" + reader + " where " + Columns.PARENT_ID + "=" + novelID); } /** diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index ab4ff11738..f129861126 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -98,7 +98,6 @@ public class ChapterReader extends AppCompatActivity { public int novelID; public ChapterView currentView; - protected ChapterView currentChapter; private MenuItem tap_to_scroll; /** @@ -232,8 +231,8 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { tap_to_scroll.setChecked(toggleTapToScroll()); return true; case R.id.chapter_view_bookmark: - currentChapter.bookmarked = toggleBookmarkChapter(currentChapter.chapterID); - if (currentChapter.bookmarked) + currentView.bookmarked = toggleBookmarkChapter(currentView.chapterID); + if (currentView.bookmarked) bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); return true; @@ -275,10 +274,10 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { return true; case R.id.browser: - openInBrowser(this, currentChapter.chapterURL); + openInBrowser(this, currentView.chapterURL); return true; case R.id.webview: - openInWebview(this, currentChapter.chapterURL); + openInWebview(this, currentView.chapterURL); return true; case R.id.reader_0: demarkMenuItems(readers, 0, demarkActions[3]); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 1e13d84b16..65e876674a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -78,13 +78,13 @@ public class ChapterView extends Fragment { @SuppressWarnings("FieldCanBeLocal") private View scroll_up, scroll_down; - public ChapterView(ChapterReader chapterReader,int chapterID) { + public ChapterView(ChapterReader chapterReader, int chapterID) { this.chapterReader = chapterReader; this.chapterID = chapterID; chapterURL = getChapterURLFromChapterID(chapterID); } - public ChapterView(ChapterReader chapterReader,String title, String chapterURL, int chapterID) { + public ChapterView(ChapterReader chapterReader, String title, String chapterURL, int chapterID) { this.chapterReader = chapterReader; this.title = title; @@ -113,25 +113,29 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c chapterURL = savedInstanceState.getString("chapterURL"); text = savedInstanceState.getString("text"); } - - errorView = new ErrorView(chapterReader, chapterView.findViewById(R.id.network_error), chapterView.findViewById(R.id.error_message), chapterView.findViewById(R.id.error_button)); - progressBar = chapterView.findViewById(R.id.fragment_novel_chapter_view_progress); - scrollView = chapterView.findViewById(R.id.fragment_novel_scroll); - readerViewPager = chapterView.findViewById(R.id.readerPager); - scroll_up = chapterView.findViewById(R.id.scroll_up); - scroll_down = chapterView.findViewById(R.id.scroll_down); - nextChapter = chapterView.findViewById(R.id.next_chapter); - + { + errorView = new ErrorView(chapterReader, chapterView.findViewById(R.id.network_error), chapterView.findViewById(R.id.error_message), chapterView.findViewById(R.id.error_button)); + progressBar = chapterView.findViewById(R.id.fragment_novel_chapter_view_progress); + scrollView = chapterView.findViewById(R.id.fragment_novel_scroll); + readerViewPager = chapterView.findViewById(R.id.readerPager); + scroll_up = chapterView.findViewById(R.id.scroll_up); + scroll_down = chapterView.findViewById(R.id.scroll_down); + nextChapter = chapterView.findViewById(R.id.next_chapter); + } fragments.add(new TextViewReader(chapterReader)); fragments.add(new MarkdownViewReader(chapterReader)); + ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); + readerViewPager.setAdapter(pagerAdapter); switch (chapterReader.readerType) { case 1: selectedReader = fragments.get(1); + readerViewPager.setCurrentItem(1); break; case 0: case -1: selectedReader = fragments.get(0); + readerViewPager.setCurrentItem(0); break; case -2: default: @@ -139,12 +143,11 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } addBottomListener(); - setViewPager(); - // Scroll up listener + // TapToScroll listeners scroll_up.setOnClickListener(view -> scrollUp()); - // Scroll down listener scroll_down.setOnClickListener(view -> scrollDown()); + nextChapter.setOnClickListener(view -> { NovelChapter novelChapter = getNextChapter(chapterID, chapterReader.chapterIDs); if (novelChapter != null) { @@ -159,7 +162,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } nextChapter.setVisibility(View.GONE); }); - loadChapter(); + + // loadChapter(); return chapterView; } @@ -180,8 +184,7 @@ public void setUpReader() { replaceSpacing.append("\t"); text = unformattedText.replaceAll("\n", replaceSpacing.toString()); - assert selectedReader.getView() != null; - selectedReader.getView().post(() -> selectedReader.setText(text)); + selectedReader.setText(text); } } @@ -277,8 +280,5 @@ private void addBottomListener() { } } - private void setViewPager() { - ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); - readerViewPager.setAdapter(pagerAdapter); - } + } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java index f89b7730eb..a115698c4e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/ReaderViewLoader.java @@ -1,6 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.async; import android.annotation.SuppressLint; +import android.app.Activity; import android.os.AsyncTask; import android.view.View; @@ -39,32 +40,33 @@ public class ReaderViewLoader extends AsyncTask { */ @SuppressLint("StaticFieldLeak") private final - ChapterView chapterReader; + ChapterView chapterView; /** * Constructor */ public ReaderViewLoader(ChapterView chapterReader) { - this.chapterReader = chapterReader; + this.chapterView = chapterReader; } @Nullable @Override protected String doInBackground(ChapterReader... chapterReaders) { - chapterReader.chapterReader.runOnUiThread(() -> chapterReader.errorView.errorView.setVisibility(View.GONE)); + Activity activity = chapterView.getActivity(); + activity.runOnUiThread(() -> chapterView.errorView.errorView.setVisibility(View.GONE)); try { - chapterReader.unformattedText = chapterReader.chapterReader.formatter.getNovelPassage(docFromURL(chapterReader.chapterURL, chapterReader.chapterReader.formatter.hasCloudFlare())); - chapterReader.chapterReader.runOnUiThread(chapterReader::setUpReader); - chapterReader.chapterReader.runOnUiThread(() -> - chapterReader.scrollView.post(() -> - chapterReader.scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterReader.chapterID))) + chapterView.unformattedText = chapterView.chapterReader.formatter.getNovelPassage(docFromURL(chapterView.chapterURL, chapterView.chapterReader.formatter.hasCloudFlare())); + activity.runOnUiThread(chapterView::setUpReader); + activity.runOnUiThread(() -> + chapterView.scrollView.post(() -> + chapterView.scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterView.chapterID))) ); - chapterReader.chapterReader.runOnUiThread(() -> chapterReader.ready = true); + activity.runOnUiThread(() -> chapterView.ready = true); } catch (Exception e) { - chapterReader.chapterReader.runOnUiThread(() -> { - chapterReader.errorView.errorView.setVisibility(View.VISIBLE); - chapterReader.errorView.errorMessage.setText(e.getMessage()); - chapterReader.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterReader).execute()); + activity.runOnUiThread(() -> { + chapterView.errorView.errorView.setVisibility(View.VISIBLE); + chapterView.errorView.errorMessage.setText(e.getMessage()); + chapterView.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterView).execute()); }); } @@ -78,8 +80,8 @@ protected String doInBackground(ChapterReader... chapterReaders) { @Override protected void onPreExecute() { super.onPreExecute(); - if (chapterReader != null) - chapterReader.progressBar.setVisibility(View.VISIBLE); + if (chapterView != null) + chapterView.progressBar.setVisibility(View.VISIBLE); } /** @@ -90,10 +92,10 @@ protected void onPreExecute() { @Override protected void onPostExecute(String s) { super.onPostExecute(s); - if (chapterReader.progressBar != null) - chapterReader.progressBar.setVisibility(View.GONE); + if (chapterView.progressBar != null) + chapterView.progressBar.setVisibility(View.GONE); - if (chapterReader.chapterReader.getSupportActionBar() != null) - chapterReader.chapterReader.getSupportActionBar().setTitle(chapterReader.title); + if (chapterView.chapterReader.getSupportActionBar() != null) + chapterView.chapterReader.getSupportActionBar().setTitle(chapterView.title); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java index 8ca2247ccf..3c57478cd5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -23,6 +23,13 @@ public MarkdownViewReader(ChapterReader chapterReader) { super(chapterReader); } + + @Nullable + @Override + public View getView() { + return markdownView; + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -34,6 +41,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c @Override public void setText(@NotNull String text) { - markdownView.loadMarkdown(text); + markdownView.post(() -> markdownView.loadMarkdown(text)); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java index 75cbdb9882..a43f1af508 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java @@ -14,4 +14,5 @@ protected Reader(ChapterReader chapterReader) { } public abstract void setText(@NotNull String text); + } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java index 0f24ef64ef..d42a28a78a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -1,6 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,10 +25,17 @@ public TextViewReader(ChapterReader chapterReader) { } + @Nullable + @Override + public View getView() { + return textView; + } + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.chapter_reader_text_view, container, false); + Log.d("Create", "TextViewReader"); textView = view.findViewById(R.id.textview); textView.setOnClickListener(new NovelFragmentChapterViewHideBar(chapterReader.toolbar)); textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); @@ -38,6 +46,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c @Override public void setText(@NotNull String text) { - textView.setText(text); + textView.post(() -> textView.setText(text)); } } diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 788e644853..62400180e0 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -25,24 +25,8 @@ app:layout_constraintTop_toTopOf="parent" /> - - + \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_view.xml b/app/src/main/res/layout/chapter_reader_view.xml index e6920aad24..955fd20217 100644 --- a/app/src/main/res/layout/chapter_reader_view.xml +++ b/app/src/main/res/layout/chapter_reader_view.xml @@ -18,7 +18,9 @@ + android:layout_height="wrap_content" + android:clickable="false" + android:visibility="visible"> + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/toolbar_chapter_view.xml b/app/src/main/res/menu/toolbar_chapter_view.xml index 9ccfeaac5d..90d22bffe7 100644 --- a/app/src/main/res/menu/toolbar_chapter_view.xml +++ b/app/src/main/res/menu/toolbar_chapter_view.xml @@ -86,10 +86,12 @@

From 58253f70139a207df0df6c9ca1def6560e2a0412 Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 8 Dec 2019 17:07:04 -0500 Subject: [PATCH 084/162] Fixed ChapterView crashes, Now to get the text to be visible --- .../apps/shosetsu/ui/reader/ChapterView.java | 14 +++++++++---- .../ui/reader/readers/MarkdownViewReader.java | 3 ++- .../shosetsu/ui/reader/readers/Reader.java | 11 +++++++++- .../ui/reader/readers/TextViewReader.java | 3 ++- app/src/main/res/layout/chapter_reader.xml | 7 ------- .../res/layout/chapter_reader_text_view.xml | 8 ++++---- .../main/res/layout/chapter_reader_view.xml | 20 ++----------------- 7 files changed, 30 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 65e876674a..50e5be2f27 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -59,6 +59,7 @@ * @author github.com/doomsdayrs */ public class ChapterView extends Fragment { + private ReaderTypeAdapter readerTypeAdapter; private ViewPager readerViewPager; private final ArrayList fragments = new ArrayList<>(); private Reader selectedReader = null; @@ -125,8 +126,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c fragments.add(new TextViewReader(chapterReader)); fragments.add(new MarkdownViewReader(chapterReader)); - ReaderTypeAdapter pagerAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); - readerViewPager.setAdapter(pagerAdapter); + readerTypeAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); + readerViewPager.setAdapter(readerTypeAdapter); switch (chapterReader.readerType) { case 1: selectedReader = fragments.get(1); @@ -163,7 +164,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c nextChapter.setVisibility(View.GONE); }); - // loadChapter(); + loadChapter(); return chapterView; } @@ -184,7 +185,12 @@ public void setUpReader() { replaceSpacing.append("\t"); text = unformattedText.replaceAll("\n", replaceSpacing.toString()); - selectedReader.setText(text); + if (text.length() > 100) + Log.d("TextSet", text.substring(0, 100).replace("\n", "\\n")); + else if (text.length() > 0) + Log.d("TextSet", text.substring(0, text.length() - 1).replace("\n", "\\n")); + + readerViewPager.post(() -> selectedReader.setText(text)); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java index 3c57478cd5..0d5517dc98 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/MarkdownViewReader.java @@ -41,6 +41,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c @Override public void setText(@NotNull String text) { - markdownView.post(() -> markdownView.loadMarkdown(text)); + super.setText(text); + markdownView.loadMarkdown(text); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java index a43f1af508..82144111c4 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/Reader.java @@ -1,5 +1,7 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.readers; +import android.util.Log; + import androidx.fragment.app.Fragment; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; @@ -13,6 +15,13 @@ protected Reader(ChapterReader chapterReader) { this.chapterReader = chapterReader; } - public abstract void setText(@NotNull String text); + public void setText(@NotNull String text) { + String t = text; + if (t.length() > 100) + t = t.substring(0, 100); + else if (t.length() > 10) + t = t.substring(0, 10); + Log.d("SetText", t); + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java index d42a28a78a..058b646a8a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/readers/TextViewReader.java @@ -46,6 +46,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c @Override public void setText(@NotNull String text) { - textView.post(() -> textView.setText(text)); + super.setText(text); + textView.setText(text); } } diff --git a/app/src/main/res/layout/chapter_reader.xml b/app/src/main/res/layout/chapter_reader.xml index 62400180e0..bcef8f3c44 100644 --- a/app/src/main/res/layout/chapter_reader.xml +++ b/app/src/main/res/layout/chapter_reader.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_text_view.xml b/app/src/main/res/layout/chapter_reader_text_view.xml index cb67fae36e..790e23cd83 100644 --- a/app/src/main/res/layout/chapter_reader_text_view.xml +++ b/app/src/main/res/layout/chapter_reader_text_view.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="visible">
\ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_view.xml b/app/src/main/res/layout/chapter_reader_view.xml index 955fd20217..2a3ac664bc 100644 --- a/app/src/main/res/layout/chapter_reader_view.xml +++ b/app/src/main/res/layout/chapter_reader_view.xml @@ -17,26 +17,10 @@ - - - - - + android:visibility="visible"/> From 4b29785552ed653bd3f939610447849cb611c6b8 Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 8 Dec 2019 17:10:06 -0500 Subject: [PATCH 085/162] Converted ReaderTypeAdapter to local variable --- .../github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 50e5be2f27..f678efd967 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -59,7 +59,6 @@ * @author github.com/doomsdayrs */ public class ChapterView extends Fragment { - private ReaderTypeAdapter readerTypeAdapter; private ViewPager readerViewPager; private final ArrayList fragments = new ArrayList<>(); private Reader selectedReader = null; @@ -126,7 +125,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c fragments.add(new TextViewReader(chapterReader)); fragments.add(new MarkdownViewReader(chapterReader)); - readerTypeAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); + ReaderTypeAdapter readerTypeAdapter = new ReaderTypeAdapter(getChildFragmentManager(), fragments); readerViewPager.setAdapter(readerTypeAdapter); switch (chapterReader.readerType) { case 1: From 58147057f77dd1805f334a5fb92eba899fb3a2f0 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 12 Dec 2019 17:31:21 -0500 Subject: [PATCH 086/162] Figuring out how to dynamically load tabs. --- app/build.gradle | 2 +- .../apps/shosetsu/ui/reader/ChapterReader.java | 12 +++++++----- .../ui/reader/adapters/ChapterReaderAdapter.java | 12 +++++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a3f8a3e889..44496d5f41 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,7 +48,7 @@ repositories { dependencies { implementation 'com.google.android.material:material:1.2.0-alpha02' - implementation 'com.graphql-java:graphql-java:2019-11-19T08-52-32-b46beb9' + implementation 'com.graphql-java:graphql-java:2019-12-09T21-46-27-74aed1a' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleCompatible diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index f129861126..5ba9c10509 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -74,7 +74,7 @@ public class ChapterReader extends AppCompatActivity { private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; public int[] chapterIDs; public int currentChapterID; - + public boolean first = false; public final ArrayList chapters = new ArrayList<>(); @@ -339,10 +339,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } else chapterIDs = new int[]{chapters.get(0).chapterID}; } - for (int id : chapterIDs) - chapters.add(new ChapterView(this, id)); - - // Declares view variables { toolbar = findViewById(R.id.toolbar); @@ -363,4 +359,10 @@ public int getPosition() { } + public ChapterView cachedChapter(int chapterID) { + for (ChapterView chapterView : chapters) + if (chapterView.chapterID == chapterID) + return chapterView; + return null; + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java index d77fb7e53e..e8a4781eda 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java @@ -6,6 +6,9 @@ import androidx.fragment.app.FragmentPagerAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterView; + +import java.util.ArrayList; public class ChapterReaderAdapter extends FragmentPagerAdapter { @@ -16,16 +19,19 @@ public ChapterReaderAdapter(@NonNull FragmentManager fm, int behavior, ChapterRe this.chapterReader = chapterReader; } - @NonNull @Override public Fragment getItem(int position) { - chapterReader.currentView = chapterReader.chapters.get(position); + chapterReader.currentView = chapterReader.cachedChapter(chapterReader.chapterIDs[position]); + if (chapterReader.currentView == null) { + chapterReader.currentView = new ChapterView(chapterReader, chapterReader.chapterIDs[position]); + chapterReader.chapters.add(chapterReader.currentView); + } return chapterReader.currentView; } @Override public int getCount() { - return chapterReader.chapters.size(); + return chapterReader.chapterIDs.length; } } From 82ae62dcf0baa3005055f498477aa8c73f917540 Mon Sep 17 00:00:00 2001 From: Rahim Date: Thu, 12 Dec 2019 18:19:24 -0500 Subject: [PATCH 087/162] I have noooooo clue what is happening --- .../doomsdayrs/apps/shosetsu/backend/Utilities.java | 2 -- .../apps/shosetsu/ui/reader/ChapterReader.java | 11 +---------- .../apps/shosetsu/ui/reader/ChapterView.java | 13 +++++-------- .../ui/reader/adapters/ChapterReaderAdapter.java | 11 +++++++---- 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 1f3f1af61a..e32079fe61 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -461,9 +461,7 @@ private static void openChapter(@NonNull Activity activity, @NonNull NovelChapte int chapterID = getChapterIDFromChapterURL(novelChapter.link); Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); Intent intent = new Intent(activity, ChapterReader.class); - intent.putExtra("title", novelChapter.title); intent.putExtra("chapterID", chapterID); - intent.putExtra("chapterURL", novelChapter.link); intent.putExtra("novelID", novelID); intent.putExtra("formatter", formatterID); intent.putExtra("chapters", chapters); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 5ba9c10509..4af63d8928 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -309,18 +309,9 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } else { chapterIDs = getIntent().getIntArrayExtra("chapters"); { - String chapterURL, title; int chapterID; - chapterID = getIntent().getIntExtra("chapterID", -1); - chapterURL = getIntent().getStringExtra("chapterURL"); - title = getIntent().getStringExtra("title"); - - assert chapterURL != null; - ASSERT(chapterID != -1); - Log.i("Reading", chapterURL); - - chapters.add(new ChapterView(this, title, chapterURL, chapterID)); + currentChapterID = chapterID; } novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index f678efd967..2bbbfe32aa 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -84,14 +84,6 @@ public ChapterView(ChapterReader chapterReader, int chapterID) { chapterURL = getChapterURLFromChapterID(chapterID); } - public ChapterView(ChapterReader chapterReader, String title, String chapterURL, int chapterID) { - this.chapterReader = chapterReader; - - this.title = title; - this.chapterURL = chapterURL; - this.chapterID = chapterID; - } - @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -113,6 +105,10 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c chapterURL = savedInstanceState.getString("chapterURL"); text = savedInstanceState.getString("text"); } + + if (chapterID == chapterReader.currentChapterID && chapterReader.first) + chapterReader.first = false; + { errorView = new ErrorView(chapterReader, chapterView.findViewById(R.id.network_error), chapterView.findViewById(R.id.error_message), chapterView.findViewById(R.id.error_button)); progressBar = chapterView.findViewById(R.id.fragment_novel_chapter_view_progress); @@ -198,6 +194,7 @@ else if (text.length() > 0) */ private void loadChapter() { ready = false; + Log.i("Loading chapter", String.valueOf(chapterID)); if (Database.DatabaseChapter.isSaved(chapterID)) { unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(chapterID)); setUpReader(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java index e8a4781eda..20c50f2b72 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/ChapterReaderAdapter.java @@ -22,10 +22,13 @@ public ChapterReaderAdapter(@NonNull FragmentManager fm, int behavior, ChapterRe @NonNull @Override public Fragment getItem(int position) { - chapterReader.currentView = chapterReader.cachedChapter(chapterReader.chapterIDs[position]); - if (chapterReader.currentView == null) { - chapterReader.currentView = new ChapterView(chapterReader, chapterReader.chapterIDs[position]); - chapterReader.chapters.add(chapterReader.currentView); + if (!chapterReader.first) { + chapterReader.currentView = chapterReader.cachedChapter(chapterReader.chapterIDs[position]); + if (chapterReader.currentView == null) { + chapterReader.currentView = new ChapterView(chapterReader, chapterReader.chapterIDs[position]); + chapterReader.chapters.add(chapterReader.currentView); + } + chapterReader.currentChapterID = chapterReader.currentView.chapterID; } return chapterReader.currentView; } From 536ee14fb5f0614ec291208bc50d99beb60265c1 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 13 Dec 2019 06:16:54 -0500 Subject: [PATCH 088/162] Will begin process of complete rebuilding of ChapterReader --- .../ui/novel/async/ChapterLoader.java | 24 +++++++++---------- .../shosetsu/ui/reader/ChapterReader.java | 18 +++++++------- .../apps/shosetsu/ui/reader/ChapterView.java | 4 ++++ .../res/layout/chapter_reader_text_view.xml | 2 +- .../main/res/layout/chapter_reader_view.xml | 4 +--- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 8aef20c9f5..5d0c987b78 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -172,17 +172,17 @@ protected void onCancelled() { */ @Override protected void onPostExecute(Boolean result) { - assert novelFragmentChapters != null; - assert novelFragmentChapters.novelFragment.getView() != null; - - novelFragmentChapters.novelFragment.getView().post(() -> { - novelFragmentChapters.swipeRefreshLayout.setRefreshing(false); - if (formatter.isIncrementingChapterList()) - novelFragmentChapters.pageCount.setVisibility(View.GONE); - if (result) - if (novelFragmentChapters.getActivity() != null) - novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setChapters); - novelFragmentChapters.resumeRead.setVisibility(View.VISIBLE); - }); + + View view = novelFragmentChapters.novelFragment.getView(); + if (view != null) + novelFragmentChapters.novelFragment.getView().post(() -> { + novelFragmentChapters.swipeRefreshLayout.setRefreshing(false); + if (formatter.isIncrementingChapterList()) + novelFragmentChapters.pageCount.setVisibility(View.GONE); + if (result) + if (novelFragmentChapters.getActivity() != null) + novelFragmentChapters.getActivity().runOnUiThread(novelFragmentChapters::setChapters); + novelFragmentChapters.resumeRead.setVisibility(View.VISIBLE); + }); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index 4af63d8928..b6e3e156ed 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -30,7 +30,6 @@ import java.util.ArrayList; import java.util.List; -import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.ASSERT; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isReaderNightMode; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; @@ -130,10 +129,7 @@ public boolean onCreateOptionsMenu(@NonNull Menu menu) { { bookmark = menu.findItem(R.id.chapter_view_bookmark); currentView.bookmarked = Database.DatabaseChapter.isBookMarked(currentView.chapterID); - if (currentView.bookmarked) - currentView.chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); - else - currentView.chapterReader.bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + updateBookmark(); } // Tap To Scroll @@ -205,6 +201,13 @@ public boolean onCreateOptionsMenu(@NonNull Menu menu) { return true; } + public void updateBookmark() { + if (bookmark != null) + if (currentView.bookmarked) + bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); + else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + } + /** * What to do when an menu item is selected * @@ -232,11 +235,8 @@ public boolean onOptionsItemSelected(@NotNull MenuItem item) { return true; case R.id.chapter_view_bookmark: currentView.bookmarked = toggleBookmarkChapter(currentView.chapterID); - if (currentView.bookmarked) - bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); - else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + updateBookmark(); return true; - case R.id.chapter_view_textSize_small: demarkMenuItems(indentSpaces, 0, demarkActions[0]); return true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java index 2bbbfe32aa..425fdb36cf 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterView.java @@ -49,6 +49,7 @@ import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.isBookMarked; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; @@ -106,6 +107,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c text = savedInstanceState.getString("text"); } + bookmarked = isBookMarked(chapterID); + chapterReader.updateBookmark(); + if (chapterID == chapterReader.currentChapterID && chapterReader.first) chapterReader.first = false; diff --git a/app/src/main/res/layout/chapter_reader_text_view.xml b/app/src/main/res/layout/chapter_reader_text_view.xml index 790e23cd83..bfadca4bdb 100644 --- a/app/src/main/res/layout/chapter_reader_text_view.xml +++ b/app/src/main/res/layout/chapter_reader_text_view.xml @@ -2,5 +2,5 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/chapter_reader_view.xml b/app/src/main/res/layout/chapter_reader_view.xml index 2a3ac664bc..c30a20080d 100644 --- a/app/src/main/res/layout/chapter_reader_view.xml +++ b/app/src/main/res/layout/chapter_reader_view.xml @@ -18,9 +18,7 @@ + android:layout_height="wrap_content" /> From 91ad38e5302f70ba6a154132beb8435e35290053 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 13 Dec 2019 07:02:32 -0500 Subject: [PATCH 089/162] Building brand new chapterReader --- app/src/main/AndroidManifest.xml | 5 +- .../apps/shosetsu/backend/Utilities.java | 4 +- .../shosetsu/ui/reader/NewChapterReader.java | 86 ++++++++++++++++++ .../adapters/NewChapterReaderAdapter.java | 62 +++++++++++++ .../ui/reader/fragments/NewChapterView.java | 41 +++++++++ .../main/res/layout/new_chapter_reader.xml | 19 ++++ app/src/main/res/layout/new_chapter_view.xml | 16 ++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 ++ 9 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java create mode 100644 app/src/main/res/layout/new_chapter_reader.xml create mode 100644 app/src/main/res/layout/new_chapter_view.xml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c11a3018c1..bac5d77648 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,11 +18,11 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:networkSecurityConfig="@xml/network_security_config" + android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MaterialComponents" tools:ignore="GoogleAppIndexingWarning" - android:requestLegacyExternalStorage="true" tools:targetApi="q"> @@ -44,6 +44,9 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index e32079fe61..2d892dce62 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -22,7 +22,7 @@ import com.github.doomsdayrs.apps.shosetsu.BuildConfig; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import com.github.doomsdayrs.apps.shosetsu.ui.webView.Actions; import com.github.doomsdayrs.apps.shosetsu.ui.webView.WebViewApp; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; @@ -460,7 +460,7 @@ public static void openChapter(@NonNull Activity activity, @NonNull NovelChapter private static void openChapter(@NonNull Activity activity, @NonNull NovelChapter novelChapter, int novelID, int formatterID, String[] chapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); - Intent intent = new Intent(activity, ChapterReader.class); + Intent intent = new Intent(activity, NewChapterReader.class); intent.putExtra("chapterID", chapterID); intent.putExtra("novelID", novelID); intent.putExtra("formatter", formatterID); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java new file mode 100644 index 0000000000..a65329a921 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -0,0 +1,86 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.viewpager2.widget.ViewPager2; + +import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.NewChapterReaderAdapter; +import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; + +import java.util.List; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewChapterReader extends AppCompatActivity { + public int[] chapterIDs; + ViewPager2 viewPager2; + Formatter formatter; + int novelID, currentChapterID; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.new_chapter_reader); + + viewPager2 = findViewById(R.id.viewpager); + NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); + + + if (savedInstanceState != null) { + formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); + novelID = savedInstanceState.getInt("novelID"); + chapterIDs = savedInstanceState.getIntArray("chapters"); + } else { + chapterIDs = getIntent().getIntArrayExtra("chapters"); + { + int chapterID; + chapterID = getIntent().getIntExtra("chapterID", -1); + currentChapterID = chapterID; + } + novelID = getIntent().getIntExtra("novelID", -1); + formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); + } + if (chapterIDs == null) { + List integers = Database.DatabaseChapter.getChaptersOnlyIDs(novelID); + chapterIDs = new int[integers.size()]; + for (int x = 0; x < integers.size(); x++) + chapterIDs[x] = integers.get(x); + } + + viewPager2.setAdapter(newChapterReaderAdapter); + viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); + } + + public int findCurrentPosition(int id) { + for (int x = 0; x < chapterIDs.length; x++) + if (chapterIDs[x] == id) + return x; + return -1; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java new file mode 100644 index 0000000000..46eb21dc75 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java @@ -0,0 +1,62 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments.NewChapterView; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewChapterReaderAdapter extends RecyclerView.Adapter { + final NewChapterReader newChapterReader; + + public NewChapterReaderAdapter(NewChapterReader newChapterReader) { + this.newChapterReader = newChapterReader; + } + + @NonNull + @Override + public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_chapter_view, parent, false); + return new NewChapterView(view); + } + + + @Override + public void onBindViewHolder(@NonNull NewChapterView holder, int position) { + holder.textView.setText("ChapterID: " + newChapterReader.chapterIDs[position]); + } + + + @Override + public int getItemCount() { + return newChapterReader.chapterIDs.length; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java new file mode 100644 index 0000000000..19941c563d --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java @@ -0,0 +1,41 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.github.doomsdayrs.apps.shosetsu.R; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewChapterView extends RecyclerView.ViewHolder { + public TextView textView; + + public NewChapterView(@NonNull View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.textView); + } +} diff --git a/app/src/main/res/layout/new_chapter_reader.xml b/app/src/main/res/layout/new_chapter_reader.xml new file mode 100644 index 0000000000..2784c1814b --- /dev/null +++ b/app/src/main/res/layout/new_chapter_reader.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/new_chapter_view.xml b/app/src/main/res/layout/new_chapter_view.xml new file mode 100644 index 0000000000..7edf712542 --- /dev/null +++ b/app/src/main/res/layout/new_chapter_view.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f6b961fd5a86aa5fbfe90f707c3138408be7c718 GIT binary patch literal 54329 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

<5G2M1WZP5 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 F{|7XC?P&l2 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..45664f82b1 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Dec 06 15:30:40 EST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-milestone-3-all.zip From 5f47e1eebb524892a76dbe1c47dd6714fc09d75e Mon Sep 17 00:00:00 2001 From: Rahim Date: Fri, 13 Dec 2019 09:46:52 -0500 Subject: [PATCH 090/162] Continuing work on new Reader --- .../shosetsu/backend/database/Database.java | 3 +-- .../shosetsu/ui/reader/NewChapterReader.java | 3 ++- .../adapters/NewChapterReaderAdapter.java | 25 ++++++++++++++++++- .../async/NewChapterReaderViewLoader.java | 19 ++++++++++++++ .../ui/reader/fragments/NewChapterView.java | 6 +++++ 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index 7ecc14224d..fff50b1253 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -723,12 +723,11 @@ public static List getChapters(int novelID) { * @param novelID ID to retrieve from * @return List of chapters saved of novel (ID only) */ - @Nullable public static List getChaptersOnlyIDs(int novelID) { Cursor cursor = sqLiteDatabase.rawQuery("select " + Columns.ID + ", " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.PARENT_ID + " =" + novelID, null); if (cursor.getCount() <= 0) { cursor.close(); - return null; + return new ArrayList<>(); } else { ArrayList novelChapters = new ArrayList<>(); while (cursor.moveToNext()) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java index a65329a921..4e08650c84 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -49,7 +49,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setContentView(R.layout.new_chapter_reader); viewPager2 = findViewById(R.id.viewpager); - NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); if (savedInstanceState != null) { @@ -66,6 +65,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { novelID = getIntent().getIntExtra("novelID", -1); formatter = DefaultScrapers.getByID(getIntent().getIntExtra("formatter", -1)); } + if (chapterIDs == null) { List integers = Database.DatabaseChapter.getChaptersOnlyIDs(novelID); chapterIDs = new int[integers.size()]; @@ -73,6 +73,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { chapterIDs[x] = integers.get(x); } + NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); viewPager2.setAdapter(newChapterReaderAdapter); viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java index 46eb21dc75..b14aea525f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java @@ -17,6 +17,7 @@ * ==================================================================== */ +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -25,8 +26,14 @@ import androidx.recyclerview.widget.RecyclerView; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.NewChapterReaderViewLoader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments.NewChapterView; +import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; + +import java.util.Objects; /** * shosetsu @@ -51,7 +58,23 @@ public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType @Override public void onBindViewHolder(@NonNull NewChapterView holder, int position) { - holder.textView.setText("ChapterID: " + newChapterReader.chapterIDs[position]); + final int CHAPTER_ID = newChapterReader.chapterIDs[position]; + Log.i("Loading chapter", String.valueOf(CHAPTER_ID)); + holder.ready = false; + if (Database.DatabaseChapter.isSaved(CHAPTER_ID)) { + holder.unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(CHAPTER_ID)); + holder.setUpReader(); + //holder.scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterID))); + //if (chapterReader.getSupportActionBar() != null) + // chapterReader.getSupportActionBar().setTitle(title); + holder.ready = true; + } else if (holder.chapterURL != null) { + holder.unformattedText = ""; + holder.setUpReader(); + new NewChapterReaderViewLoader(holder).execute(); + } + + Database.DatabaseChapter.setChapterStatus(CHAPTER_ID, Status.READING); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java new file mode 100644 index 0000000000..f44b3f8657 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java @@ -0,0 +1,19 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.async; + +import android.os.AsyncTask; + +import com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments.NewChapterView; + +public class NewChapterReaderViewLoader extends AsyncTask { + + final NewChapterView newChapterView; + + public NewChapterReaderViewLoader(NewChapterView holder) { + newChapterView = holder; + } + + @Override + protected Void doInBackground(Object... objects) { + return null; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java index 19941c563d..da2ecc6737 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java @@ -33,9 +33,15 @@ */ public class NewChapterView extends RecyclerView.ViewHolder { public TextView textView; + public boolean ready; + public String unformattedText; + public String chapterURL; public NewChapterView(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.textView); } + + public void setUpReader() { + } } From 037b6517042d5fce7f755336fbbb580f779377be Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 13 Dec 2019 17:00:07 -0500 Subject: [PATCH 091/162] Figuring out MultiLevelPaging --- .../shosetsu/ui/reader/NewChapterReader.java | 64 ++++++++++++-- .../adapters/NewChapterReaderAdapter.java | 24 +++-- .../adapters/NewChapterReaderTypeAdapter.java | 81 +++++++++++++++++ .../async/NewChapterReaderViewLoader.java | 31 ++++++- .../NovelFragmentChapterViewHideBar.java | 12 +-- .../ui/reader/viewHolders/NewChapterView.java | 87 +++++++++++++++++++ .../reader/viewHolders/NewMarkdownReader.java | 53 +++++++++++ .../NewReader.java} | 21 ++--- .../ui/reader/viewHolders/NewTextReader.java | 52 +++++++++++ .../main/res/layout/new_chapter_reader.xml | 17 ++-- app/src/main/res/layout/new_chapter_view.xml | 20 ++--- 11 files changed, 413 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewMarkdownReader.java rename app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/{fragments/NewChapterView.java => viewHolders/NewReader.java} (67%) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewTextReader.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java index 4e08650c84..40a8f3b6cd 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -17,20 +17,28 @@ * ==================================================================== */ +import android.os.BaseBundle; import android.os.Bundle; +import android.os.PersistableBundle; +import android.util.Log; +import android.view.MenuItem; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import androidx.viewpager2.widget.ViewPager2; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.NewChapterReaderAdapter; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; import java.util.List; + /** * shosetsu * 13 / 12 / 2019 @@ -38,23 +46,62 @@ * @author github.com/doomsdayrs */ public class NewChapterReader extends AppCompatActivity { - public int[] chapterIDs; + //private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; + + + // Order of values. Small,Medium,Large + private final MenuItem[] textSizes = new MenuItem[3]; + // Order of values. Non,Small,Medium,Large + private final MenuItem[] paragraphSpaces = new MenuItem[4]; + // Order of values. Non,Small,Medium,Large + private final MenuItem[] indentSpaces = new MenuItem[4]; + // Order of values. Default, Markdown + private final MenuItem[] readers = new MenuItem[2]; + ViewPager2 viewPager2; - Formatter formatter; - int novelID, currentChapterID; + public Toolbar toolbar; + + // NovelData + public int[] chapterIDs; + public Formatter formatter; + public int novelID; + public NewChapterView currentView; + int currentChapterID = -1; + + @Override + public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) { + super.onSaveInstanceState(outState, outPersistentState); + outPersistentState.putIntArray("chapters", chapterIDs); + outPersistentState.putInt("novelID", novelID); + outPersistentState.putInt("formatter", formatter.getID()); + } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log.i("OnCreate", "Only Bundle"); + onCreate(savedInstanceState, null); + } + + private void restoreInstanceState(BaseBundle bundle) { + formatter = DefaultScrapers.getByID(bundle.getInt("formatter")); + novelID = bundle.getInt("novelID"); + chapterIDs = bundle.getIntArray("chapters"); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { setContentView(R.layout.new_chapter_reader); viewPager2 = findViewById(R.id.viewpager); + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); - if (savedInstanceState != null) { - formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); - novelID = savedInstanceState.getInt("novelID"); - chapterIDs = savedInstanceState.getIntArray("chapters"); + if (persistentState != null) { + restoreInstanceState(persistentState); + } else if (savedInstanceState != null) { + restoreInstanceState(savedInstanceState); } else { chapterIDs = getIntent().getIntArrayExtra("chapters"); { @@ -75,7 +122,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); viewPager2.setAdapter(newChapterReaderAdapter); - viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); + if (currentChapterID != -1) + viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); } public int findCurrentPosition(int id) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java index b14aea525f..e8592d4be3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java @@ -29,12 +29,14 @@ import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.NewChapterReaderViewLoader; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.ReaderViewLoader; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments.NewChapterView; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import java.util.Objects; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; + /** * shosetsu * 13 / 12 / 2019 @@ -52,19 +54,31 @@ public NewChapterReaderAdapter(NewChapterReader newChapterReader) { @Override public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_chapter_view, parent, false); - return new NewChapterView(view); + return new NewChapterView(newChapterReader, view); } @Override public void onBindViewHolder(@NonNull NewChapterView holder, int position) { + newChapterReader.currentView = holder; + final int CHAPTER_ID = newChapterReader.chapterIDs[position]; - Log.i("Loading chapter", String.valueOf(CHAPTER_ID)); + + holder.setChapterID(CHAPTER_ID); + holder.setChapterURL(getChapterURLFromChapterID(CHAPTER_ID)); + + holder.viewPager2.setUserInputEnabled(false); + NewChapterReaderTypeAdapter newChapterReaderTypeAdapter = new NewChapterReaderTypeAdapter(newChapterReader); + holder.viewPager2.setAdapter(newChapterReaderTypeAdapter); + holder.viewPager2.setCurrentItem(getReaderType(newChapterReader.novelID)); + + Log.i("Loading chapter", holder.chapterURL); + holder.ready = false; if (Database.DatabaseChapter.isSaved(CHAPTER_ID)) { holder.unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(CHAPTER_ID)); holder.setUpReader(); - //holder.scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(chapterID))); + holder.scrollView.post(() -> holder.scrollView.scrollTo(0, Database.DatabaseChapter.getY(holder.chapterID))); //if (chapterReader.getSupportActionBar() != null) // chapterReader.getSupportActionBar().setTitle(title); holder.ready = true; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java new file mode 100644 index 0000000000..8d9706d4c9 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java @@ -0,0 +1,81 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewMarkdownReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewTextReader; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewChapterReaderTypeAdapter extends RecyclerView.Adapter { + final NewChapterReader newChapterReader; + + public NewChapterReaderTypeAdapter(NewChapterReader newChapterReader) { + this.newChapterReader = newChapterReader; + } + + @NonNull + @Override + public NewReader onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view; + NewReader newReader; + switch (viewType) { + case 0: + view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chapter_reader_text_view, parent, false); + newReader = new NewTextReader(view, newChapterReader); + break; + case 1: + view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chapter_reader_mark_down, parent, false); + newReader = new NewMarkdownReader(view, newChapterReader); + break; + default: + throw new IllegalStateException("Unexpected value: " + viewType); + } + return newReader; + } + + + @Override + public void onBindViewHolder(@NonNull NewReader holder, int position) { + Log.i("LoadingReader", String.valueOf(position)); + newChapterReader.currentView.currentReader = holder; + holder.bind(); + newChapterReader.currentView.setUpReader(); + } + + + @Override + public int getItemCount() { + return 2; + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java index f44b3f8657..d16d3f1d87 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java @@ -1,12 +1,16 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.async; +import android.app.Activity; import android.os.AsyncTask; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments.NewChapterView; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseChapter.getY; +import static com.github.doomsdayrs.apps.shosetsu.backend.scraper.WebViewScrapper.docFromURL; public class NewChapterReaderViewLoader extends AsyncTask { - final NewChapterView newChapterView; + private final NewChapterView newChapterView; public NewChapterReaderViewLoader(NewChapterView holder) { newChapterView = holder; @@ -14,6 +18,29 @@ public NewChapterReaderViewLoader(NewChapterView holder) { @Override protected Void doInBackground(Object... objects) { + + Activity activity = newChapterView.newChapterReader; + //activity.runOnUiThread(() -> chapterView.errorView.errorView.setVisibility(View.GONE)); + try { + newChapterView.unformattedText = newChapterView.newChapterReader.formatter.getNovelPassage(docFromURL(newChapterView.chapterURL, newChapterView.newChapterReader.formatter.hasCloudFlare())); + activity.runOnUiThread(newChapterView::setUpReader); + activity.runOnUiThread(() -> newChapterView.scrollView.post(() -> newChapterView.scrollView.scrollTo(0, getY(newChapterView.chapterID)))); + activity.runOnUiThread(() -> newChapterView.ready = true); + } catch (Exception e) { + // activity.runOnUiThread(() -> { chapterView.errorView.errorView.setVisibility(View.VISIBLE);chapterView.errorView.errorMessage.setText(e.getMessage());chapterView.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterView).execute()); }); + } return null; } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + //TODO + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + //TODO + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/listeners/NovelFragmentChapterViewHideBar.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/listeners/NovelFragmentChapterViewHideBar.java index f91ae17ad3..609fb2e9c1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/listeners/NovelFragmentChapterViewHideBar.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/listeners/NovelFragmentChapterViewHideBar.java @@ -22,6 +22,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 18 / 06 / 2019 * @@ -29,7 +32,7 @@ */ public class NovelFragmentChapterViewHideBar implements View.OnClickListener { private final Toolbar toolbar; - private boolean visible = true; + public NovelFragmentChapterViewHideBar(Toolbar toolbar) { this.toolbar = toolbar; @@ -37,12 +40,9 @@ public NovelFragmentChapterViewHideBar(Toolbar toolbar) { @Override public void onClick(View v) { - if (visible) { + if (toolbar.getY() == 0) toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start(); - visible = !visible; - } else { + else toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start(); - visible = !visible; - } } } \ No newline at end of file diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java new file mode 100644 index 0000000000..6dbe422692 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java @@ -0,0 +1,87 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.util.Log; +import android.view.View; +import android.widget.ScrollView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.widget.ViewPager2; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewChapterView extends RecyclerView.ViewHolder { + public final NewChapterReader newChapterReader; + public String chapterURL; + public int chapterID; + + public ScrollView scrollView; + + + public ViewPager2 viewPager2; + public NewReader currentReader; + + + public boolean ready; + public String unformattedText; + public String text; + + public NewChapterView(NewChapterReader newChapterReader, @NonNull View itemView) { + super(itemView); + this.newChapterReader = newChapterReader; + scrollView = itemView.findViewById(R.id.scrollView); + viewPager2 = itemView.findViewById(R.id.viewpager); + } + + public void setChapterURL(String chapterURL) { + this.chapterURL = chapterURL; + } + + public void setChapterID(int chapterID) { + this.chapterID = chapterID; + } + + public void setUpReader() { + scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + if (unformattedText != null) { + StringBuilder replaceSpacing = new StringBuilder("\n"); + for (int x = 0; x < Settings.paragraphSpacing; x++) + replaceSpacing.append("\n"); + + for (int x = 0; x < Settings.indentSize; x++) + replaceSpacing.append("\t"); + + text = unformattedText.replaceAll("\n", replaceSpacing.toString()); + if (text.length() > 100) + Log.d("TextSet", text.substring(0, 100).replace("\n", "\\n")); + else if (text.length() > 0) + Log.d("TextSet", text.substring(0, text.length() - 1).replace("\n", "\\n")); + viewPager2.post(() -> currentReader.setText(text)); + } + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewMarkdownReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewMarkdownReader.java new file mode 100644 index 0000000000..594f9fc7d2 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewMarkdownReader.java @@ -0,0 +1,53 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.view.View; + +import androidx.annotation.NonNull; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; + +import us.feras.mdv.MarkdownView; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewMarkdownReader extends NewReader { + MarkdownView markdownView; + + public NewMarkdownReader(@NonNull View itemView, NewChapterReader newChapterReader) { + super(itemView, newChapterReader); + markdownView = itemView.findViewById(R.id.markdown_view); + } + + @Override + public void setText(String text) { + markdownView.loadMarkdown(text); + } + + @Override + public void bind() { + markdownView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); + } +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewReader.java similarity index 67% rename from app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java rename to app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewReader.java index da2ecc6737..d474df0ff1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/fragments/NewChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewReader.java @@ -1,4 +1,4 @@ -package com.github.doomsdayrs.apps.shosetsu.ui.reader.fragments; +package com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders; /* * This file is part of shosetsu. * @@ -18,12 +18,11 @@ */ import android.view.View; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; -import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; /** * shosetsu @@ -31,17 +30,15 @@ * * @author github.com/doomsdayrs */ -public class NewChapterView extends RecyclerView.ViewHolder { - public TextView textView; - public boolean ready; - public String unformattedText; - public String chapterURL; +public abstract class NewReader extends RecyclerView.ViewHolder { + final NewChapterReader newChapterReader; - public NewChapterView(@NonNull View itemView) { + public NewReader(@NonNull View itemView, NewChapterReader newChapterReader) { super(itemView); - textView = itemView.findViewById(R.id.textView); + this.newChapterReader = newChapterReader; } - public void setUpReader() { - } + public abstract void setText(String text); + + public abstract void bind(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewTextReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewTextReader.java new file mode 100644 index 0000000000..aac37ed8ce --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewTextReader.java @@ -0,0 +1,52 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders; +/* + * This file is part of shosetsu. + * + * shosetsu is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * shosetsu is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with shosetsu. If not, see . + * ==================================================================== + */ + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; + +/** + * shosetsu + * 13 / 12 / 2019 + * + * @author github.com/doomsdayrs + */ +public class NewTextReader extends NewReader { + public final TextView textView; + + public NewTextReader(@NonNull View itemView, NewChapterReader newChapterReader) { + super(itemView, newChapterReader); + textView = itemView.findViewById(R.id.textview); + } + + @Override + public void setText(String text) { + textView.setText(text); + } + + @Override + public void bind() { + textView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); + } +} diff --git a/app/src/main/res/layout/new_chapter_reader.xml b/app/src/main/res/layout/new_chapter_reader.xml index 2784c1814b..08078ba142 100644 --- a/app/src/main/res/layout/new_chapter_reader.xml +++ b/app/src/main/res/layout/new_chapter_reader.xml @@ -4,14 +4,19 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + - + + + + \ No newline at end of file From 3b2bc082f8e63adc9ef5739cd04cfe978707c59b Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Fri, 13 Dec 2019 20:37:30 -0500 Subject: [PATCH 092/162] Trying.... To figure it out.. --- .../shosetsu/backend/database/Database.java | 26 ++++++ .../shosetsu/ui/reader/NewChapterReader.java | 1 + .../adapters/NewChapterReaderAdapter.java | 79 ++++++++++++++++--- .../adapters/NewChapterReaderTypeAdapter.java | 2 +- .../ui/reader/viewHolders/NewChapterView.java | 24 ++++-- app/src/main/res/layout/new_chapter_view.xml | 26 +++++- 6 files changed, 138 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java index fff50b1253..3406038dc7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/database/Database.java @@ -521,6 +521,32 @@ else if (y == 1) } } + public static float getOrder(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.ORDER + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); + if (cursor.getCount() <= 0) { + cursor.close(); + return -1; + } else { + cursor.moveToNext(); + float y = cursor.getFloat(cursor.getColumnIndex(Columns.ORDER.toString())); + cursor.close(); + return y; + } + } + + public static String getTitle(int chapterID) { + Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + Columns.TITLE + " from " + Tables.CHAPTERS + " where " + Columns.ID + " =" + chapterID, null); + if (cursor.getCount() <= 0) { + cursor.close(); + return "UNKNOWN"; + } else { + cursor.moveToNext(); + String y = cursor.getString(cursor.getColumnIndex(Columns.TITLE.toString())); + cursor.close(); + return checkStringDeserialize(y); + } + } + /** * Sets chapter status * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java index 40a8f3b6cd..a0f61fd03c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -122,6 +122,7 @@ public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableB NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); viewPager2.setAdapter(newChapterReaderAdapter); + if (currentChapterID != -1) viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java index e8592d4be3..14d01e329e 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java @@ -32,10 +32,10 @@ import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; +import java.util.List; import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getReaderType; /** * shosetsu @@ -50,6 +50,13 @@ public NewChapterReaderAdapter(NewChapterReader newChapterReader) { this.newChapterReader = newChapterReader; } + private void updateTitle(NewChapterView holder) { + newChapterReader.currentView = holder; + String title = Database.DatabaseChapter.getTitle(holder.chapterID); + Log.i("Setting TITLE", title); + newChapterReader.toolbar.setTitle(title); + } + @NonNull @Override public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -57,6 +64,63 @@ public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType return new NewChapterView(newChapterReader, view); } + @Override + public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { + super.onAttachedToRecyclerView(recyclerView); + Log.i("Adapter", "onAttachedToRecyclerView"); + + } + + @Override + public void onBindViewHolder(@NonNull NewChapterView holder, int position, @NonNull List payloads) { + super.onBindViewHolder(holder, position, payloads); + Log.i("Adapter", "onBindViewHolder"); + updateTitle(holder); + } + + @Override + public void onViewRecycled(@NonNull NewChapterView holder) { + super.onViewRecycled(holder); + Log.i("Adapter", "onViewRecycled"); + updateTitle(holder); + } + + @Override + public boolean onFailedToRecycleView(@NonNull NewChapterView holder) { + Log.i("Adapter", "onFailedToRecycleView"); + return super.onFailedToRecycleView(holder); + } + + @Override + public void onViewAttachedToWindow(@NonNull NewChapterView holder) { + super.onViewAttachedToWindow(holder); + Log.i("Adapter", "onViewAttachedToWindow"); + updateTitle(holder); + } + + @Override + public void onViewDetachedFromWindow(@NonNull NewChapterView holder) { + super.onViewDetachedFromWindow(holder); + Log.i("Adapter", "onViewDetachedFromWindow"); + } + + @Override + public void registerAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) { + super.registerAdapterDataObserver(observer); + Log.i("Adapter", "registerAdapterDataObserver"); + } + + @Override + public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) { + super.unregisterAdapterDataObserver(observer); + Log.i("Adapter", "unregisterAdapterDataObserver"); + } + + @Override + public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { + super.onDetachedFromRecyclerView(recyclerView); + Log.i("Adapter", "onDetachedFromRecyclerView"); + } @Override public void onBindViewHolder(@NonNull NewChapterView holder, int position) { @@ -67,20 +131,17 @@ public void onBindViewHolder(@NonNull NewChapterView holder, int position) { holder.setChapterID(CHAPTER_ID); holder.setChapterURL(getChapterURLFromChapterID(CHAPTER_ID)); - holder.viewPager2.setUserInputEnabled(false); - NewChapterReaderTypeAdapter newChapterReaderTypeAdapter = new NewChapterReaderTypeAdapter(newChapterReader); - holder.viewPager2.setAdapter(newChapterReaderTypeAdapter); - holder.viewPager2.setCurrentItem(getReaderType(newChapterReader.novelID)); + //holder.viewPager2.setUserInputEnabled(false); + //NewChapterReaderTypeAdapter newChapterReaderTypeAdapter = new NewChapterReaderTypeAdapter(newChapterReader); + //holder.viewPager2.setAdapter(newChapterReaderTypeAdapter); + //holder.viewPager2.setCurrentItem(getReaderType(newChapterReader.novelID)); Log.i("Loading chapter", holder.chapterURL); - holder.ready = false; if (Database.DatabaseChapter.isSaved(CHAPTER_ID)) { holder.unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(CHAPTER_ID)); holder.setUpReader(); holder.scrollView.post(() -> holder.scrollView.scrollTo(0, Database.DatabaseChapter.getY(holder.chapterID))); - //if (chapterReader.getSupportActionBar() != null) - // chapterReader.getSupportActionBar().setTitle(title); holder.ready = true; } else if (holder.chapterURL != null) { holder.unformattedText = ""; @@ -91,9 +152,9 @@ public void onBindViewHolder(@NonNull NewChapterView holder, int position) { Database.DatabaseChapter.setChapterStatus(CHAPTER_ID, Status.READING); } - @Override public int getItemCount() { + Log.i("size", String.valueOf(newChapterReader.chapterIDs.length)); return newChapterReader.chapterIDs.length; } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java index 8d9706d4c9..1e30c75266 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderTypeAdapter.java @@ -68,7 +68,7 @@ public NewReader onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @Override public void onBindViewHolder(@NonNull NewReader holder, int position) { Log.i("LoadingReader", String.valueOf(position)); - newChapterReader.currentView.currentReader = holder; + //newChapterReader.currentView.currentReader = holder; holder.bind(); newChapterReader.currentView.setUpReader(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java index 6dbe422692..154bad075d 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java @@ -17,16 +17,18 @@ * ==================================================================== */ +import android.annotation.SuppressLint; import android.util.Log; import android.view.View; import android.widget.ScrollView; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; -import androidx.viewpager2.widget.ViewPager2; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; /** @@ -42,22 +44,29 @@ public class NewChapterView extends RecyclerView.ViewHolder { public ScrollView scrollView; - - public ViewPager2 viewPager2; - public NewReader currentReader; - + //public View coverView; + // public ViewPager2 viewPager2; + //public NewReader currentReader; + private TextView textView; public boolean ready; public String unformattedText; public String text; + + @SuppressLint("ClickableViewAccessibility") public NewChapterView(NewChapterReader newChapterReader, @NonNull View itemView) { super(itemView); this.newChapterReader = newChapterReader; scrollView = itemView.findViewById(R.id.scrollView); - viewPager2 = itemView.findViewById(R.id.viewpager); + textView = itemView.findViewById(R.id.textView); + textView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); + //viewPager2 = itemView.findViewById(R.id.viewpager); + //coverView = itemView.findViewById(R.id.viewCover); + //coverView.setOnTouchListener((view, motionEvent) -> true); } + public void setChapterURL(String chapterURL) { this.chapterURL = chapterURL; } @@ -81,7 +90,8 @@ public void setUpReader() { Log.d("TextSet", text.substring(0, 100).replace("\n", "\\n")); else if (text.length() > 0) Log.d("TextSet", text.substring(0, text.length() - 1).replace("\n", "\\n")); - viewPager2.post(() -> currentReader.setText(text)); + textView.setText(text); + // viewPager2.post(() -> currentReader.setText(text)); } } } diff --git a/app/src/main/res/layout/new_chapter_view.xml b/app/src/main/res/layout/new_chapter_view.xml index a6e236da21..a5d92d62e3 100644 --- a/app/src/main/res/layout/new_chapter_view.xml +++ b/app/src/main/res/layout/new_chapter_view.xml @@ -1,15 +1,35 @@ + android:layout_height="match_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + From c7573b0d176676041be4272518f6c7197583c496 Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 14 Dec 2019 07:40:25 -0500 Subject: [PATCH 093/162] Completed a proper swiping NewChapterReader --- .../ui/novel/adapters/ChaptersAdapter.java | 2 +- .../ui/novel/pages/NovelFragmentChapters.java | 2 +- .../ui/novel/pages/NovelFragmentInfo.java | 10 +- .../shosetsu/ui/reader/ChapterReader.java | 2 +- .../shosetsu/ui/reader/NewChapterReader.java | 245 ++++++++++++++++-- .../adapters/NewChapterReaderAdapter.java | 128 +-------- .../async/NewChapterReaderViewLoader.java | 4 +- .../ui/reader/demarkActions/IndentChange.java | 6 +- .../demarkActions/ParaSpacingChange.java | 6 +- .../ui/reader/demarkActions/ReaderChange.java | 8 +- .../reader/demarkActions/TextSizeChange.java | 7 +- .../ui/reader/viewHolders/NewChapterView.java | 85 +++++- .../main/res/layout/new_chapter_reader.xml | 2 +- app/src/main/res/layout/toolbar_main.xml | 1 + .../main/res/menu/toolbar_chapter_view.xml | 4 +- build.gradle | 2 +- 16 files changed, 331 insertions(+), 183 deletions(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java index da034202f6..f4aba81a7b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/adapters/ChaptersAdapter.java @@ -154,7 +154,7 @@ public void onBindViewHolder(@NonNull ChaptersViewHolder chaptersViewHolder, int @Override public int getItemCount() { - if (novelFragmentChapters.novelFragment.novelChapters != null) + if (novelFragmentChapters.novelFragment != null && novelFragmentChapters.novelFragment.novelChapters != null) return novelFragmentChapters.novelFragment.novelChapters.size(); else return 0; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index aaf4e41ba2..3f53550cc9 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -187,7 +187,7 @@ public void setChapters() { recyclerView.post(() -> { recyclerView.setHasFixedSize(false); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext()); - if (Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { + if (novelFragment != null && Database.DatabaseNovels.inDatabase(novelFragment.novelID)) { novelFragment.novelChapters = Database.DatabaseChapter.getChapters(novelFragment.novelID); if (novelFragment.novelChapters != null && novelFragment.novelChapters.size() != 0) resumeRead.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java index b6aa109594..3161159277 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java @@ -123,7 +123,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.toolbar_novel, menu); - if (Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) { + if (novelFragment != null && Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) { menu.findItem(R.id.source_migrate).setVisible(true); } else menu.findItem(R.id.source_migrate).setVisible(false); @@ -172,14 +172,14 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c floatingActionButton.hide(); - - if (Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) - inLibrary(); + if (novelFragment != null) + if (Database.DatabaseNovels.isBookmarked(novelFragment.novelID)) + inLibrary(); if (inLibrary) floatingActionButton.setImageResource(R.drawable.ic_add_circle_black_24dp); - if (novelFragment.novelPage != null && title != null) + if (novelFragment != null && novelFragment.novelPage != null && title != null) setData(); floatingActionButton.setOnClickListener(new NovelFragmentMainAddToLibrary(this)); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java index b6e3e156ed..258eacafce 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/ChapterReader.java @@ -70,7 +70,7 @@ */ //TODO MarkDown support public class ChapterReader extends AppCompatActivity { - private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; + private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(null), new ParaSpacingChange(null), new IndentChange(null), new ReaderChange(null)}; public int[] chapterIDs; public int currentChapterID; public boolean first = false; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java index a0f61fd03c..45cc370998 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -17,27 +17,47 @@ * ==================================================================== */ -import android.os.BaseBundle; import android.os.Bundle; import android.os.PersistableBundle; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.viewpager2.widget.ViewPager2; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; import com.github.Doomsdayrs.api.shosetsu.services.core.dep.Formatter; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.adapters.NewChapterReaderAdapter; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.IndentChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ParaSpacingChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.ReaderChange; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions.TextSizeChange; import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; +import com.github.doomsdayrs.apps.shosetsu.variables.Settings; + +import org.jetbrains.annotations.NotNull; import java.util.List; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.demarkMenuItems; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isReaderNightMode; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.isTapToScroll; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setTextSize; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.swapReaderColor; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleBookmarkChapter; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.toggleTapToScroll; + /** * shosetsu @@ -46,9 +66,7 @@ * @author github.com/doomsdayrs */ public class NewChapterReader extends AppCompatActivity { - //private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; - - + private final Utilities.DemarkAction[] demarkActions = {new TextSizeChange(this), new ParaSpacingChange(this), new IndentChange(this), new ReaderChange(this)}; // Order of values. Small,Medium,Large private final MenuItem[] textSizes = new MenuItem[3]; // Order of values. Non,Small,Medium,Large @@ -57,10 +75,12 @@ public class NewChapterReader extends AppCompatActivity { private final MenuItem[] indentSpaces = new MenuItem[4]; // Order of values. Default, Markdown private final MenuItem[] readers = new MenuItem[2]; + MenuItem bookmark, tap_to_scroll; - ViewPager2 viewPager2; + ViewPager viewPager; public Toolbar toolbar; + // NovelData public int[] chapterIDs; public Formatter formatter; @@ -68,6 +88,189 @@ public class NewChapterReader extends AppCompatActivity { public NewChapterView currentView; int currentChapterID = -1; + + /** + * Creates the option menu (on the top toolbar) + * + * @param menu Menu reference to fill + * @return if made + */ + @Override + public boolean onCreateOptionsMenu(@NonNull Menu menu) { + MenuInflater inflater = getMenuInflater(); + + inflater.inflate(R.menu.toolbar_chapter_view, menu); + // Night mode + menu.findItem(R.id.chapter_view_nightMode).setChecked(isReaderNightMode()); + + // Bookmark + { + bookmark = menu.findItem(R.id.chapter_view_bookmark); + currentView.bookmarked = Database.DatabaseChapter.isBookMarked(currentView.CHAPTER_ID); + updateBookmark(); + } + + + // Tap To Scroll + { + tap_to_scroll = menu.findItem(R.id.tap_to_scroll); + tap_to_scroll.setChecked(isTapToScroll()); + } + + + // Text size + { + textSizes[0] = menu.findItem(R.id.chapter_view_textSize_small); + textSizes[1] = menu.findItem(R.id.chapter_view_textSize_medium); + textSizes[2] = menu.findItem(R.id.chapter_view_textSize_large); + + switch ((int) Settings.ReaderTextSize) { + default: + setTextSize(14); + case 14: + textSizes[0].setChecked(true); + break; + case 17: + textSizes[1].setChecked(true); + break; + case 20: + textSizes[2].setChecked(true); + break; + } + } + + // Paragraph Space + { + paragraphSpaces[0] = menu.findItem(R.id.chapter_view_paragraphSpace_none); + paragraphSpaces[1] = menu.findItem(R.id.chapter_view_paragraphSpace_small); + paragraphSpaces[2] = menu.findItem(R.id.chapter_view_paragraphSpace_medium); + paragraphSpaces[3] = menu.findItem(R.id.chapter_view_paragraphSpace_large); + + paragraphSpaces[Settings.paragraphSpacing].setChecked(true); + } + + // Indent Space + { + indentSpaces[0] = menu.findItem(R.id.chapter_view_indent_none); + indentSpaces[1] = menu.findItem(R.id.chapter_view_indent_small); + indentSpaces[2] = menu.findItem(R.id.chapter_view_indent_medium); + indentSpaces[3] = menu.findItem(R.id.chapter_view_indent_large); + + indentSpaces[Settings.indentSize].setChecked(true); + } + + /* Reader + { + + readers[0] = menu.findItem(R.id.reader_0); + readers[1] = menu.findItem(R.id.reader_1); + readerType = getReaderType(novelID); + + switch (readerType) { + case 1: + demarkMenuItems(readers, 1, null); + break; + case 0: + case -1: + demarkMenuItems(readers, 0, null); + break; + case -2: + default: + throw new RuntimeException("Invalid chapter?!? How are you reading this without the novel loaded in"); + } + }*/ + return true; + } + + public void updateBookmark() { + if (bookmark != null) + if (currentView.bookmarked) + bookmark.setIcon(R.drawable.ic_bookmark_black_24dp); + else bookmark.setIcon(R.drawable.ic_bookmark_border_black_24dp); + } + + /** + * What to do when an menu item is selected + * + * @param item item selected + * @return true if processed + */ + @Override + public boolean onOptionsItemSelected(@NotNull MenuItem item) { + Log.d("item", item.toString()); + switch (item.getItemId()) { + default: + return false; + case R.id.chapter_view_nightMode: + if (!item.isChecked()) { + swapReaderColor(); + currentView.setUpReader(); + } else { + swapReaderColor(); + currentView.setUpReader(); + } + item.setChecked(!item.isChecked()); + return true; + case R.id.tap_to_scroll: + tap_to_scroll.setChecked(toggleTapToScroll()); + return true; + case R.id.chapter_view_bookmark: + currentView.bookmarked = toggleBookmarkChapter(currentView.CHAPTER_ID); + updateBookmark(); + return true; + case R.id.chapter_view_textSize_small: + demarkMenuItems(indentSpaces, 0, demarkActions[0]); + return true; + case R.id.chapter_view_textSize_medium: + demarkMenuItems(textSizes, 1, demarkActions[0]); + return true; + case R.id.chapter_view_textSize_large: + demarkMenuItems(textSizes, 2, demarkActions[0]); + return true; + + case R.id.chapter_view_paragraphSpace_none: + demarkMenuItems(paragraphSpaces, 0, demarkActions[1]); + return true; + case R.id.chapter_view_paragraphSpace_small: + demarkMenuItems(paragraphSpaces, 1, demarkActions[1]); + return true; + case R.id.chapter_view_paragraphSpace_medium: + demarkMenuItems(paragraphSpaces, 2, demarkActions[1]); + return true; + case R.id.chapter_view_paragraphSpace_large: + demarkMenuItems(paragraphSpaces, 3, demarkActions[1]); + return true; + + case R.id.chapter_view_indent_none: + demarkMenuItems(indentSpaces, 0, demarkActions[2]); + return true; + case R.id.chapter_view_indent_small: + demarkMenuItems(indentSpaces, 1, demarkActions[2]); + return true; + case R.id.chapter_view_indent_medium: + demarkMenuItems(indentSpaces, 2, demarkActions[2]); + return true; + case R.id.chapter_view_indent_large: + demarkMenuItems(indentSpaces, 3, demarkActions[2]); + return true; + + case R.id.browser: + openInBrowser(this, currentView.CHAPTER_URL); + return true; + case R.id.webview: + openInWebview(this, currentView.CHAPTER_URL); + return true; + case R.id.reader_0: + demarkMenuItems(readers, 0, demarkActions[3]); + return true; + case R.id.reader_1: + demarkMenuItems(readers, 1, demarkActions[3]); + return true; + + } + } + + @Override public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) { super.onSaveInstanceState(outState, outPersistentState); @@ -77,31 +280,19 @@ public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBu } @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { + public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Log.i("OnCreate", "Only Bundle"); - onCreate(savedInstanceState, null); - } - - private void restoreInstanceState(BaseBundle bundle) { - formatter = DefaultScrapers.getByID(bundle.getInt("formatter")); - novelID = bundle.getInt("novelID"); - chapterIDs = bundle.getIntArray("chapters"); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { setContentView(R.layout.new_chapter_reader); - viewPager2 = findViewById(R.id.viewpager); + viewPager = findViewById(R.id.viewpager); toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - if (persistentState != null) { - restoreInstanceState(persistentState); - } else if (savedInstanceState != null) { - restoreInstanceState(savedInstanceState); + if (savedInstanceState != null) { + formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); + novelID = savedInstanceState.getInt("novelID"); + chapterIDs = savedInstanceState.getIntArray("chapters"); } else { chapterIDs = getIntent().getIntArrayExtra("chapters"); { @@ -120,11 +311,11 @@ public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableB chapterIDs[x] = integers.get(x); } - NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(this); - viewPager2.setAdapter(newChapterReaderAdapter); + NewChapterReaderAdapter newChapterReaderAdapter = new NewChapterReaderAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, this); + viewPager.setAdapter(newChapterReaderAdapter); if (currentChapterID != -1) - viewPager2.setCurrentItem(findCurrentPosition(currentChapterID)); + viewPager.setCurrentItem(findCurrentPosition(currentChapterID)); } public int findCurrentPosition(int id) { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java index 14d01e329e..a4d5761113 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/adapters/NewChapterReaderAdapter.java @@ -18,24 +18,16 @@ */ import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; -import com.github.doomsdayrs.apps.shosetsu.R; -import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.NewChapterReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.viewHolders.NewChapterView; -import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; -import java.util.List; -import java.util.Objects; - -import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import java.util.ArrayList; /** * shosetsu @@ -43,117 +35,25 @@ * * @author github.com/doomsdayrs */ -public class NewChapterReaderAdapter extends RecyclerView.Adapter { - final NewChapterReader newChapterReader; +public class NewChapterReaderAdapter extends FragmentPagerAdapter { + private final NewChapterReader newChapterReader; + private ArrayList chapterViews = new ArrayList<>(); - public NewChapterReaderAdapter(NewChapterReader newChapterReader) { + public NewChapterReaderAdapter(@NonNull FragmentManager fm, int behavior, NewChapterReader newChapterReader) { + super(fm, behavior); this.newChapterReader = newChapterReader; - } - - private void updateTitle(NewChapterView holder) { - newChapterReader.currentView = holder; - String title = Database.DatabaseChapter.getTitle(holder.chapterID); - Log.i("Setting TITLE", title); - newChapterReader.toolbar.setTitle(title); + for (int i : newChapterReader.chapterIDs) + chapterViews.add(new NewChapterView(newChapterReader, i)); } @NonNull @Override - public NewChapterView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.new_chapter_view, parent, false); - return new NewChapterView(newChapterReader, view); - } - - @Override - public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { - super.onAttachedToRecyclerView(recyclerView); - Log.i("Adapter", "onAttachedToRecyclerView"); - - } - - @Override - public void onBindViewHolder(@NonNull NewChapterView holder, int position, @NonNull List payloads) { - super.onBindViewHolder(holder, position, payloads); - Log.i("Adapter", "onBindViewHolder"); - updateTitle(holder); - } - - @Override - public void onViewRecycled(@NonNull NewChapterView holder) { - super.onViewRecycled(holder); - Log.i("Adapter", "onViewRecycled"); - updateTitle(holder); - } - - @Override - public boolean onFailedToRecycleView(@NonNull NewChapterView holder) { - Log.i("Adapter", "onFailedToRecycleView"); - return super.onFailedToRecycleView(holder); - } - - @Override - public void onViewAttachedToWindow(@NonNull NewChapterView holder) { - super.onViewAttachedToWindow(holder); - Log.i("Adapter", "onViewAttachedToWindow"); - updateTitle(holder); - } - - @Override - public void onViewDetachedFromWindow(@NonNull NewChapterView holder) { - super.onViewDetachedFromWindow(holder); - Log.i("Adapter", "onViewDetachedFromWindow"); - } - - @Override - public void registerAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) { - super.registerAdapterDataObserver(observer); - Log.i("Adapter", "registerAdapterDataObserver"); - } - - @Override - public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) { - super.unregisterAdapterDataObserver(observer); - Log.i("Adapter", "unregisterAdapterDataObserver"); - } - - @Override - public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { - super.onDetachedFromRecyclerView(recyclerView); - Log.i("Adapter", "onDetachedFromRecyclerView"); - } - - @Override - public void onBindViewHolder(@NonNull NewChapterView holder, int position) { - newChapterReader.currentView = holder; - - final int CHAPTER_ID = newChapterReader.chapterIDs[position]; - - holder.setChapterID(CHAPTER_ID); - holder.setChapterURL(getChapterURLFromChapterID(CHAPTER_ID)); - - //holder.viewPager2.setUserInputEnabled(false); - //NewChapterReaderTypeAdapter newChapterReaderTypeAdapter = new NewChapterReaderTypeAdapter(newChapterReader); - //holder.viewPager2.setAdapter(newChapterReaderTypeAdapter); - //holder.viewPager2.setCurrentItem(getReaderType(newChapterReader.novelID)); - - Log.i("Loading chapter", holder.chapterURL); - holder.ready = false; - if (Database.DatabaseChapter.isSaved(CHAPTER_ID)) { - holder.unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(CHAPTER_ID)); - holder.setUpReader(); - holder.scrollView.post(() -> holder.scrollView.scrollTo(0, Database.DatabaseChapter.getY(holder.chapterID))); - holder.ready = true; - } else if (holder.chapterURL != null) { - holder.unformattedText = ""; - holder.setUpReader(); - new NewChapterReaderViewLoader(holder).execute(); - } - - Database.DatabaseChapter.setChapterStatus(CHAPTER_ID, Status.READING); + public Fragment getItem(int position) { + return chapterViews.get(position); } @Override - public int getItemCount() { + public int getCount() { Log.i("size", String.valueOf(newChapterReader.chapterIDs.length)); return newChapterReader.chapterIDs.length; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java index d16d3f1d87..d7031e859c 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/async/NewChapterReaderViewLoader.java @@ -22,9 +22,9 @@ protected Void doInBackground(Object... objects) { Activity activity = newChapterView.newChapterReader; //activity.runOnUiThread(() -> chapterView.errorView.errorView.setVisibility(View.GONE)); try { - newChapterView.unformattedText = newChapterView.newChapterReader.formatter.getNovelPassage(docFromURL(newChapterView.chapterURL, newChapterView.newChapterReader.formatter.hasCloudFlare())); + newChapterView.unformattedText = newChapterView.newChapterReader.formatter.getNovelPassage(docFromURL(newChapterView.CHAPTER_URL, newChapterView.newChapterReader.formatter.hasCloudFlare())); activity.runOnUiThread(newChapterView::setUpReader); - activity.runOnUiThread(() -> newChapterView.scrollView.post(() -> newChapterView.scrollView.scrollTo(0, getY(newChapterView.chapterID)))); + activity.runOnUiThread(() -> newChapterView.scrollView.post(() -> newChapterView.scrollView.scrollTo(0, getY(newChapterView.CHAPTER_ID)))); activity.runOnUiThread(() -> newChapterView.ready = true); } catch (Exception e) { // activity.runOnUiThread(() -> { chapterView.errorView.errorView.setVisibility(View.VISIBLE);chapterView.errorView.errorMessage.setText(e.getMessage());chapterView.errorView.errorButton.setOnClickListener(view -> new ReaderViewLoader(chapterView).execute()); }); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java index d0806c6812..6b8075b302 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/IndentChange.java @@ -1,14 +1,14 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeIndentSize; public class IndentChange implements Utilities.DemarkAction { - private final ChapterReader chapterReader; + private final NewChapterReader chapterReader; - public IndentChange(ChapterReader chapterReader) { + public IndentChange(NewChapterReader chapterReader) { this.chapterReader = chapterReader; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java index 465456ad8e..bc425fe258 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ParaSpacingChange.java @@ -1,14 +1,14 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.changeParagraphSpacing; public class ParaSpacingChange implements Utilities.DemarkAction { - private final ChapterReader chapterReader; + private final NewChapterReader chapterReader; - public ParaSpacingChange(ChapterReader chapterReader) { + public ParaSpacingChange(NewChapterReader chapterReader) { this.chapterReader = chapterReader; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java index 91d97105ff..d062882b47 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/ReaderChange.java @@ -1,20 +1,20 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.setReaderType; public class ReaderChange implements Utilities.DemarkAction { - private final ChapterReader chapterReader; + private final NewChapterReader chapterReader; - public ReaderChange(ChapterReader chapterReader) { + public ReaderChange(NewChapterReader chapterReader) { this.chapterReader = chapterReader; } @Override public void action(int spared) { - chapterReader.readerType = spared; + //chapterReader.readerType = spared; setReaderType(chapterReader.novelID, spared); chapterReader.currentView.setUpReader(); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java index 1270bdc3ea..46bdccb1e2 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/demarkActions/TextSizeChange.java @@ -1,18 +1,17 @@ package com.github.doomsdayrs.apps.shosetsu.ui.reader.demarkActions; import com.github.doomsdayrs.apps.shosetsu.backend.Utilities; -import com.github.doomsdayrs.apps.shosetsu.ui.reader.ChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setTextSize; public class TextSizeChange implements Utilities.DemarkAction { - private final ChapterReader chapterReader; + private final NewChapterReader chapterReader; - public TextSizeChange(ChapterReader chapterReader) { + public TextSizeChange(NewChapterReader chapterReader) { this.chapterReader = chapterReader; } - @Override public void action(int spared) { int[] a = {14, 17, 20}; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java index 154bad075d..ae0cb873e5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java @@ -18,18 +18,29 @@ */ import android.annotation.SuppressLint; +import android.os.Bundle; import android.util.Log; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.ScrollView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import com.github.doomsdayrs.apps.shosetsu.R; +import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; +import com.github.doomsdayrs.apps.shosetsu.ui.reader.async.NewChapterReaderViewLoader; import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; +import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; + +import java.util.Objects; + +import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; /** * shosetsu @@ -37,46 +48,92 @@ * * @author github.com/doomsdayrs */ -public class NewChapterView extends RecyclerView.ViewHolder { +public class NewChapterView extends Fragment { public final NewChapterReader newChapterReader; - public String chapterURL; - public int chapterID; - public ScrollView scrollView; + public final String CHAPTER_URL; + public final int CHAPTER_ID; + public ScrollView scrollView; + public boolean bookmarked; //public View coverView; // public ViewPager2 viewPager2; //public NewReader currentReader; private TextView textView; + public boolean ready; public String unformattedText; public String text; @SuppressLint("ClickableViewAccessibility") - public NewChapterView(NewChapterReader newChapterReader, @NonNull View itemView) { - super(itemView); + public NewChapterView(NewChapterReader newChapterReader, int chapter_id) { this.newChapterReader = newChapterReader; - scrollView = itemView.findViewById(R.id.scrollView); - textView = itemView.findViewById(R.id.textView); - textView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); //viewPager2 = itemView.findViewById(R.id.viewpager); //coverView = itemView.findViewById(R.id.viewCover); //coverView.setOnTouchListener((view, motionEvent) -> true); + CHAPTER_ID = chapter_id; + this.CHAPTER_URL = getChapterURLFromChapterID(CHAPTER_ID); } + private void updateParent() { + newChapterReader.currentView = this; + newChapterReader.updateBookmark(); + } - public void setChapterURL(String chapterURL) { - this.chapterURL = chapterURL; + @Override + public void onResume() { + super.onResume(); + updateParent(); + String title = Database.DatabaseChapter.getTitle(CHAPTER_ID); + Log.i("Setting TITLE", title); + newChapterReader.toolbar.setTitle(title); } - public void setChapterID(int chapterID) { - this.chapterID = chapterID; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.new_chapter_view, container, false); + + scrollView = view.findViewById(R.id.scrollView); + textView = view.findViewById(R.id.textView); + textView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); + textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + textView.setTextColor(Settings.ReaderTextColor); + textView.setTextSize(Settings.ReaderTextSize); + + updateParent(); + + + //holder.viewPager2.setUserInputEnabled(false); + //NewChapterReaderTypeAdapter newChapterReaderTypeAdapter = new NewChapterReaderTypeAdapter(newChapterReader); + //holder.viewPager2.setAdapter(newChapterReaderTypeAdapter); + //holder.viewPager2.setCurrentItem(getReaderType(newChapterReader.novelID)); + + Log.i("Loading chapter", CHAPTER_URL); + ready = false; + if (Database.DatabaseChapter.isSaved(CHAPTER_ID)) { + unformattedText = Objects.requireNonNull(Database.DatabaseChapter.getSavedNovelPassage(CHAPTER_ID)); + setUpReader(); + scrollView.post(() -> scrollView.scrollTo(0, Database.DatabaseChapter.getY(CHAPTER_ID))); + ready = true; + } else { + unformattedText = ""; + setUpReader(); + new NewChapterReaderViewLoader(this).execute(); + } + + Database.DatabaseChapter.setChapterStatus(CHAPTER_ID, Status.READING); + return view; } public void setUpReader() { scrollView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); + textView.setTextColor(Settings.ReaderTextColor); + textView.setTextSize(Settings.ReaderTextSize); if (unformattedText != null) { StringBuilder replaceSpacing = new StringBuilder("\n"); for (int x = 0; x < Settings.paragraphSpacing; x++) diff --git a/app/src/main/res/layout/new_chapter_reader.xml b/app/src/main/res/layout/new_chapter_reader.xml index 08078ba142..e8c92c39be 100644 --- a/app/src/main/res/layout/new_chapter_reader.xml +++ b/app/src/main/res/layout/new_chapter_reader.xml @@ -13,7 +13,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - \ No newline at end of file diff --git a/app/src/main/res/menu/toolbar_chapter_view.xml b/app/src/main/res/menu/toolbar_chapter_view.xml index 90d22bffe7..1c1dddfc48 100644 --- a/app/src/main/res/menu/toolbar_chapter_view.xml +++ b/app/src/main/res/menu/toolbar_chapter_view.xml @@ -102,12 +102,12 @@ diff --git a/build.gradle b/build.gradle index 5c71b612f9..dd04b78454 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0-alpha05' + classpath 'com.android.tools.build:gradle:4.0.0-alpha06' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From 48d440f115ffbed635ef690781a2233d28c8bfef Mon Sep 17 00:00:00 2001 From: doomsdayrs Date: Sat, 14 Dec 2019 22:34:55 -0500 Subject: [PATCH 094/162] Trying to solve ChapterLoader.java --- .../doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java index 5d0c987b78..95e1528dd1 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/ChapterLoader.java @@ -147,7 +147,6 @@ private void refresh(Activity activity) { */ @Override protected void onPreExecute() { - assert novelFragmentChapters != null; novelFragmentChapters.swipeRefreshLayout.setRefreshing(true); if (formatter.isIncrementingChapterList()) novelFragmentChapters.pageCount.setVisibility(View.VISIBLE); From 60ba6027f3adda4d00cd5df12e2358b2ffb19fb8 Mon Sep 17 00:00:00 2001 From: Rahim Date: Sun, 15 Dec 2019 18:24:01 -0500 Subject: [PATCH 095/162] - Removed Statics.java - Download_Manager.java now uses a Activity.findViewByID() method to update NovelFragmentChapters.java Chapters - Setting activity title now using new Utilities.setActivityTitle method in Utilities.java via implementation of Supporter.java to the MainActivity --- .../shosetsu/backend/Download_Manager.java | 31 +++-- .../apps/shosetsu/backend/Utilities.java | 12 +- .../ui/catalogue/CatalogueFragment.java | 4 +- .../ui/catalogue/CataloguesFragment.java | 5 +- .../ui/downloads/DownloadsFragment.java | 6 +- .../shosetsu/ui/library/LibraryFragment.java | 5 +- .../apps/shosetsu/ui/main/MainActivity.java | 14 +- .../apps/shosetsu/ui/main/Supporter.java | 7 + .../apps/shosetsu/ui/novel/NovelFragment.java | 5 +- .../shosetsu/ui/novel/async/NovelLoader.java | 2 - .../ui/novel/pages/NovelFragmentChapters.java | 130 +++++++++++------- .../ui/novel/pages/NovelFragmentInfo.java | 8 +- .../novel/viewHolders/ChaptersViewHolder.java | 34 +++-- .../shosetsu/ui/reader/NewChapterReader.java | 2 +- .../ui/reader/viewHolders/NewChapterView.java | 62 ++++++++- .../ui/settings/SettingsFragment.java | 5 +- .../shosetsu/ui/updates/UpdatesFragment.java | 12 +- .../adapters/UpdatedChaptersAdapter.java | 2 +- .../apps/shosetsu/variables/Statics.java | 34 ----- app/src/main/res/layout/new_chapter_view.xml | 30 +++- 20 files changed, 268 insertions(+), 142 deletions(-) create mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/Supporter.java delete mode 100644 app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java index d15a0791a5..47a3dda7c3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Download_Manager.java @@ -1,5 +1,6 @@ package com.github.doomsdayrs.apps.shosetsu.backend; +import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.util.Log; @@ -7,7 +8,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; +import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.downloads.DownloadsFragment; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; @@ -56,11 +59,11 @@ public class Download_Manager { /** * Initializes download manager */ - public static void init() { + public static void init(Activity activity) { if (download.isCancelled()) download = new Downloading(); if (download.getStatus().equals(AsyncTask.Status.FINISHED) || download.getStatus().equals(AsyncTask.Status.PENDING)) - download.execute(); + download.execute(activity); } /** @@ -68,13 +71,13 @@ public static void init() { * * @param downloadItem download item to add */ - public static void addToDownload(@NonNull DownloadItem downloadItem) { + public static void addToDownload(Activity activity, @NonNull DownloadItem downloadItem) { if (!Database.DatabaseDownloads.inDownloads(downloadItem)) { Database.DatabaseDownloads.addToDownloads(downloadItem); if (download.isCancelled()) if (Database.DatabaseDownloads.getDownloadCount() >= 1) { download = new Downloading(); - download.execute(); + download.execute(activity); } } } @@ -129,16 +132,20 @@ public static String getText(@NonNull String path) { * TODO Notification of download progress (( What is being downloaded * TODO Skip over paused chapters or move them to the bottom of the list */ - static class Downloading extends AsyncTask { + static class Downloading extends AsyncTask { + @Nullable @Override - protected Void doInBackground(Void... voids) { + protected Void doInBackground(Activity... voids) { + Activity activity = voids[0]; while (Database.DatabaseDownloads.getDownloadCount() >= 1 && !Settings.downloadPaused) { DownloadItem downloadItem = Database.DatabaseDownloads.getFirstDownload(); // Starts up - DownloadsFragment.toggleProcess(downloadItem); + if (downloadItem != null) { + DownloadsFragment.toggleProcess(downloadItem); + } if (downloadItem != null) try { { @@ -159,8 +166,14 @@ protected Void doInBackground(Void... voids) { fileOutputStream.close(); Database.DatabaseChapter.addSavedPath(downloadItem.chapterURL, folder.getPath() + "/" + formattedName + ".txt"); - if (NovelFragmentChapters.recyclerView != null && NovelFragmentChapters.adapter != null) - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + if (activity != null) { + RecyclerView recyclerView = activity.findViewById(R.id.fragment_novel_chapters_recycler); + if (recyclerView != null) + recyclerView.post(() -> { + if (recyclerView.getAdapter() != null) + recyclerView.getAdapter().notifyDataSetChanged(); + }); + } Log.d("Downloaded", "Downloaded:" + downloadItem.novelName + " " + formattedName); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java index 2d892dce62..5b710ac9c3 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/backend/Utilities.java @@ -22,6 +22,7 @@ import com.github.doomsdayrs.apps.shosetsu.BuildConfig; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; +import com.github.doomsdayrs.apps.shosetsu.ui.main.Supporter; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; import com.github.doomsdayrs.apps.shosetsu.ui.webView.Actions; import com.github.doomsdayrs.apps.shosetsu.ui.webView.WebViewApp; @@ -67,12 +68,13 @@ */ public class Utilities { - public static void ASSERT(boolean b) { - Log.e("ASSERT, D", String.valueOf(BuildConfig.DEBUG)); - Log.e("ASSERT, B", String.valueOf(b)); - if (BuildConfig.DEBUG && !b) - throw new RuntimeException(); + public static void setActivityTitle(Activity activity, String title){ + Supporter supporter = (Supporter) activity; + if (supporter != null) { + supporter.setTitle(title); + } + } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java index 502cbb1691..a57d78798b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CatalogueFragment.java @@ -32,7 +32,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.listeners.CatalogueSearchQuery; import com.github.doomsdayrs.apps.shosetsu.ui.webView.WebViewApp; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueNovelCard; import java.util.ArrayList; @@ -41,6 +40,7 @@ import okhttp3.OkHttpClient; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.calculateNoOfColumns; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; /* * This file is part of Shosetsu. @@ -154,7 +154,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c catalogueNovelCards = (ArrayList) savedInstanceState.getSerializable("list"); formatter = DefaultScrapers.getByID(savedInstanceState.getInt("formatter")); } - Statics.mainActionBar.setTitle(formatter.getName()); + setActivityTitle(getActivity(), formatter.getName()); swipeRefreshLayout.setOnRefreshListener(new CatalogueRefresh(this)); this.context = Objects.requireNonNull(container).getContext(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java index d583f7814f..e5505a2143 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/catalogue/CataloguesFragment.java @@ -18,7 +18,6 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.ui.catalogue.adapters.CataloguesAdapter; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.CatalogueCard; import org.jetbrains.annotations.NotNull; @@ -26,6 +25,8 @@ import java.util.ArrayList; import java.util.Objects; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; + /* * This file is part of Shosetsu. * @@ -76,7 +77,7 @@ public void onCreateOptionsMenu(@NotNull Menu menu, @NonNull MenuInflater inflat @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d("OnCreateView", "CataloguesFragment"); - Statics.mainActionBar.setTitle("Catalogues"); + setActivityTitle(getActivity(),"Catalogues"); //TODO Conditional for turning formatter on and off // > Conditional for languages // > Conditional for categories, maybe diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java index e9b6676268..0f9be7b3d7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/downloads/DownloadsFragment.java @@ -22,13 +22,13 @@ import com.github.doomsdayrs.apps.shosetsu.ui.downloads.adapters.DownloadAdapter; import com.github.doomsdayrs.apps.shosetsu.variables.DownloadItem; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.togglePause; /* @@ -141,7 +141,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d("OnCreateView", "NovelFragmentChapters"); - Statics.mainActionBar.setTitle("Downloads"); + setActivityTitle(getActivity(), "Downloads"); View view = inflater.inflate(R.layout.fragment_downloads, container, false); recyclerView = view.findViewById(R.id.fragment_downloads_recycler); downloadItems = Database.DatabaseDownloads.getDownloadList(); @@ -183,7 +183,7 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { item.setIcon(R.drawable.ic_pause_circle_filled_black_24dp); else { item.setIcon(R.drawable.ic_pause_circle_outline_black_24dp); - Download_Manager.init(); + Download_Manager.init(getActivity()); } return true; } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java index 58df01c1fc..a337fcd6a7 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/library/LibraryFragment.java @@ -25,8 +25,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.library.adapter.LibraryNovelAdapter; import com.github.doomsdayrs.apps.shosetsu.ui.library.listener.LibrarySearchQuery; import com.github.doomsdayrs.apps.shosetsu.ui.migration.MigrationView; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; -import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.NovelCard; import org.jetbrains.annotations.NotNull; @@ -36,6 +34,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.calculateNoOfColumns; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseNovels.getNovelTitle; /* @@ -174,7 +173,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - Statics.mainActionBar.setTitle("Library"); + setActivityTitle(getActivity(), "Library"); Log.d("Library", "creating"); if (savedInstanceState == null) readFromDB(); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java index 72f91a1e72..d6f73947ec 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/MainActivity.java @@ -10,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -30,7 +31,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.settings.SettingsFragment; import com.github.doomsdayrs.apps.shosetsu.ui.updates.UpdatesFragment; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.javiersantos.appupdater.AppUpdater; import com.github.javiersantos.appupdater.AppUpdaterUtils; import com.github.javiersantos.appupdater.enums.AppUpdaterError; @@ -64,7 +64,7 @@ * @author github.com/doomsdayrs */ //TODO Inform users to refresh their libraries -public class MainActivity extends AppCompatActivity { +public class MainActivity extends AppCompatActivity implements Supporter { public DrawerLayout drawerLayout; public NavigationView navigationView; public final CataloguesFragment cataloguesFragment = new CataloguesFragment(); @@ -156,7 +156,7 @@ public void onFailed(AppUpdaterError error) { //Sets the toolbar Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - Statics.mainActionBar = getSupportActionBar(); + //Sets up the sidebar drawerLayout = findViewById(R.id.drawer_layout); navigationView = findViewById(R.id.nav_view); @@ -173,7 +173,7 @@ public void onFailed(AppUpdaterError error) { DBHelper helper = new DBHelper(this); Database.sqLiteDatabase = helper.getWritableDatabase(); - Download_Manager.init(); + Download_Manager.init(this); //Prevent the frag from changing on rotation @@ -198,4 +198,10 @@ public void onBackPressed() { } } + + @Override + public void setTitle(String name) { + if (getSupportActionBar() != null) + getSupportActionBar().setTitle(name); + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/Supporter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/Supporter.java new file mode 100644 index 0000000000..e8b708c370 --- /dev/null +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/main/Supporter.java @@ -0,0 +1,7 @@ +package com.github.doomsdayrs.apps.shosetsu.ui.main; + +import androidx.appcompat.app.ActionBar; + +public interface Supporter { + void setTitle(String name); +} diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java index 59a356b624..e92dd24c89 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/NovelFragment.java @@ -25,7 +25,6 @@ import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentChapters; import com.github.doomsdayrs.apps.shosetsu.ui.novel.pages.NovelFragmentInfo; import com.github.doomsdayrs.apps.shosetsu.variables.DefaultScrapers; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; import com.google.android.material.tabs.TabLayout; @@ -192,8 +191,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c } else { novelPage = Database.DatabaseNovels.getNovelPage(novelID); status = Database.DatabaseNovels.getStatus(novelID); - if (novelPage != null) - Statics.mainActionBar.setTitle(novelPage.title); + if (novelPage != null && getActivity() != null && getActivity().getActionBar() != null) + getActivity().getActionBar().setTitle(novelPage.title); setViewPager(); } } else { diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java index 79032f39d6..91efde3a50 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/async/NovelLoader.java @@ -10,7 +10,6 @@ import com.github.doomsdayrs.apps.shosetsu.backend.ErrorView; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import org.jsoup.nodes.Document; @@ -142,7 +141,6 @@ protected void onPostExecute(Boolean result) { if (result) { assert novelFragment != null; - Statics.mainActionBar.setTitle(novelFragment.novelPage.title); if (loadAll) errorView.activity.runOnUiThread(() -> new ChapterLoader(novelFragment.novelPage, novelFragment.novelURL, novelFragment.formatter).execute()); errorView.activity.runOnUiThread(this::setData); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java index 3f53550cc9..db555c5b7b 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentChapters.java @@ -1,7 +1,8 @@ package com.github.doomsdayrs.apps.shosetsu.ui.novel.pages; -import android.annotation.SuppressLint; +import android.content.BroadcastReceiver; import android.os.Bundle; +import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -54,21 +55,34 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 9 / June / 2019 * * @author github.com/doomsdayrs - */ - -/** + *

* Displays the chapters the novel contains * TODO Check filesystem if the chapter is saved, even if not in DB. + *

*/ public class NovelFragmentChapters extends Fragment { + public static boolean reversed; + public RecyclerView recyclerView; + private int currentMaxPage = 1; @NonNull public ArrayList selectedChapters = new ArrayList<>(); + @Nullable + public ChaptersAdapter adapter; + public SwipeRefreshLayout swipeRefreshLayout; + public NovelFragment novelFragment; + public TextView pageCount; + public FloatingActionButton resumeRead; + public Menu menu; + public boolean contains(@NonNull NovelChapter novelChapter) { for (NovelChapter n : selectedChapters) if (n.link.equalsIgnoreCase(novelChapter.link)) @@ -76,37 +90,31 @@ public boolean contains(@NonNull NovelChapter novelChapter) { return false; } - private int currentMaxPage = 1; private int findMinPosition() { - int min = novelFragment.novelChapters.size(); - for (int x = 0; x < novelFragment.novelChapters.size(); x++) - if (contains(novelFragment.novelChapters.get(x))) - if (x < min) - min = x; + int min = 0; + if (novelFragment.novelChapters != null) { + min = novelFragment.novelChapters.size(); + } + if (novelFragment.novelChapters != null) { + for (int x = 0; x < novelFragment.novelChapters.size(); x++) + if (contains(novelFragment.novelChapters.get(x))) + if (x < min) + min = x; + } return min; } - public static boolean reversed; - @Nullable - @SuppressLint("StaticFieldLeak") - public static RecyclerView recyclerView; - private int findMaxPosition() { int max = -1; - for (int x = novelFragment.novelChapters.size() - 1; x >= 0; x--) - if (contains(novelFragment.novelChapters.get(x))) - if (x > max) - max = x; + if (novelFragment.novelChapters != null) + for (int x = novelFragment.novelChapters.size() - 1; x >= 0; x--) + if (contains(novelFragment.novelChapters.get(x))) + if (x > max) + max = x; return max; } - @Nullable - public static ChaptersAdapter adapter; - public SwipeRefreshLayout swipeRefreshLayout; - public NovelFragment novelFragment; - public TextView pageCount; - public FloatingActionButton resumeRead; /** * Constructor @@ -172,9 +180,10 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c onResume(); resumeRead.setOnClickListener(view1 -> { int i = novelFragment.lastRead(); - if (i != -1 && i != -2) - Utilities.openChapter(getActivity(), novelFragment.novelChapters.get(i), novelFragment.novelID, novelFragment.formatter.getID()); - else + if (i != -1 && i != -2) { + if (getActivity() != null && novelFragment.novelChapters != null && novelFragment.formatter != null) + Utilities.openChapter(getActivity(), novelFragment.novelChapters.get(i), novelFragment.novelID, novelFragment.formatter.getID()); + } else Toast.makeText(getContext(), "No chapters! How did you even press this!", Toast.LENGTH_SHORT).show(); }); return view; @@ -199,48 +208,58 @@ public void setChapters() { }); } - public Menu menu; @Nullable public MenuInflater getInflater() { return new MenuInflater(getContext()); } + public boolean updateAdapter() { + return recyclerView.post(() -> { + if (adapter != null) + adapter.notifyDataSetChanged(); + }); + } + @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.chapter_select_all: - for (NovelChapter novelChapter : novelFragment.novelChapters) - if (!contains(novelChapter)) - selectedChapters.add(novelChapter); - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + if (novelFragment.novelChapters != null) + for (NovelChapter novelChapter : novelFragment.novelChapters) + if (!contains(novelChapter)) + selectedChapters.add(novelChapter); + updateAdapter(); return true; case R.id.chapter_download_selected: for (NovelChapter novelChapter : selectedChapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); - if (!Database.DatabaseChapter.isSaved(chapterID)) { + if (novelFragment.novelPage != null && !Database.DatabaseChapter.isSaved(chapterID)) { DownloadItem downloadItem = new DownloadItem(novelFragment.formatter, novelFragment.novelPage.title, novelChapter.title, chapterID); - Download_Manager.addToDownload(downloadItem); + Download_Manager.addToDownload(getActivity(), downloadItem); } } - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + updateAdapter(); return true; case R.id.chapter_delete_selected: for (NovelChapter novelChapter : selectedChapters) { int chapterID = getChapterIDFromChapterURL(novelChapter.link); - if (Database.DatabaseChapter.isSaved(chapterID)) + + if (novelFragment.novelPage != null && Database.DatabaseChapter.isSaved(chapterID)) Download_Manager.delete(getContext(), new DownloadItem(novelFragment.formatter, novelFragment.novelPage.title, novelChapter.title, chapterID)); } - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + updateAdapter(); + return true; case R.id.chapter_deselect_all: selectedChapters = new ArrayList<>(); - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); - onCreateOptionsMenu(menu, getInflater()); + updateAdapter(); + if (getInflater() != null) + onCreateOptionsMenu(menu, getInflater()); return true; case R.id.chapter_mark_read: @@ -250,7 +269,8 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (Database.DatabaseChapter.getStatus(chapterID).getA() != 2) Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); } - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + updateAdapter(); + return true; case R.id.chapter_mark_unread: @@ -260,7 +280,8 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (Database.DatabaseChapter.getStatus(chapterID).getA() != 0) Database.DatabaseChapter.setChapterStatus(chapterID, Status.UNREAD); } - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + updateAdapter(); + return true; case R.id.chapter_mark_reading: @@ -269,26 +290,37 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (Database.DatabaseChapter.getStatus(chapterID).getA() != 0) Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); } - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + updateAdapter(); + return true; case R.id.chapter_select_between: int min = findMinPosition(); int max = findMaxPosition(); - for (int x = min; x < max; x++) - if (!contains(novelFragment.novelChapters.get(x))) - selectedChapters.add(novelFragment.novelChapters.get(x)); - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + if (novelFragment.novelChapters != null) + for (int x = min; x < max; x++) + if (!contains(novelFragment.novelChapters.get(x))) + selectedChapters.add(novelFragment.novelChapters.get(x)); + updateAdapter(); + return true; case R.id.chapter_filter: - Collections.reverse(novelFragment.novelChapters); + if (novelFragment.novelChapters != null) + Collections.reverse(novelFragment.novelChapters); NovelFragmentChapters.reversed = !NovelFragmentChapters.reversed; - return NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + return updateAdapter(); } return false; } + @Override + public void onResume() { + super.onResume(); + if (adapter != null) + adapter.notifyDataSetChanged(); + } + /** * Creates the option menu (on the top toolbar) * diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java index 3161159277..8bf5a6e0e5 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/pages/NovelFragmentInfo.java @@ -36,6 +36,7 @@ import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInBrowser; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.openInWebview; import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.serializeToString; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; /* * This file is part of Shosetsu. @@ -192,6 +193,9 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c * Sets the data of this page */ public void setData() { + if (novelFragment.novelPage != null) { + setActivityTitle(getActivity(), novelFragment.novelPage.title); + } if (novelFragment.getView() != null) novelFragment.getView().post(() -> { @@ -247,7 +251,9 @@ public void setData() { .load(novelFragment.novelPage.imageURL) .into(imageView_background); floatingActionButton.show(); - formatterName.setText(novelFragment.formatter.getName()); + if (novelFragment.formatter != null) { + formatterName.setText(novelFragment.formatter.getName()); + } }); } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java index e591c29cd0..c46d53b15a 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/novel/viewHolders/ChaptersViewHolder.java @@ -6,6 +6,7 @@ import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; @@ -42,6 +43,9 @@ * You should have received a copy of the GNU General Public License * along with Shosetsu. If not, see . * ==================================================================== + */ + +/** * Shosetsu * 16 / 06 / 2019 * @@ -52,7 +56,6 @@ public class ChaptersViewHolder extends RecyclerView.ViewHolder implements View. public NovelChapter novelChapter; public int chapterID = -1; - private final ImageView moreOptions; public final MaterialCardView cardView; public final ConstraintLayout constraintLayout; public final CheckBox checkBox; @@ -69,6 +72,7 @@ public class ChaptersViewHolder extends RecyclerView.ViewHolder implements View. public ChaptersViewHolder(@NonNull View itemView) { super(itemView); + ImageView moreOptions; { cardView = itemView.findViewById(R.id.recycler_novel_chapter_card); checkBox = itemView.findViewById(R.id.recycler_novel_chapter_selectCheck); @@ -96,31 +100,35 @@ public ChaptersViewHolder(@NonNull View itemView) { library_card_title.setTextColor(ChaptersAdapter.DefaultTextColor); } - NovelFragmentChapters.adapter.notifyDataSetChanged(); + novelFragmentChapters.updateAdapter(); return true; case R.id.popup_chapter_menu_download: - if (!Database.DatabaseChapter.isSaved(chapterID)) { + if (!Database.DatabaseChapter.isSaved(chapterID) && novelFragmentChapters.novelFragment.novelPage != null) { DownloadItem downloadItem = new DownloadItem(novelFragmentChapters.novelFragment.formatter, novelFragmentChapters.novelFragment.novelPage.title, novelChapter.title, chapterID); - Download_Manager.addToDownload(downloadItem); + Download_Manager.addToDownload(novelFragmentChapters.getActivity(), downloadItem); } else { - if (Download_Manager.delete(itemView.getContext(), new DownloadItem(novelFragmentChapters.novelFragment.formatter, novelFragmentChapters.novelFragment.novelPage.title, novelChapter.title, chapterID))) { + if (novelFragmentChapters.novelFragment.novelPage != null && Download_Manager.delete(itemView.getContext(), new DownloadItem(novelFragmentChapters.novelFragment.formatter, novelFragmentChapters.novelFragment.novelPage.title, novelChapter.title, chapterID))) { downloadTag.setVisibility(View.INVISIBLE); } } - NovelFragmentChapters.adapter.notifyDataSetChanged(); + novelFragmentChapters.updateAdapter(); + return true; case R.id.popup_chapter_menu_mark_read: Database.DatabaseChapter.setChapterStatus(chapterID, Status.READ); - NovelFragmentChapters.adapter.notifyDataSetChanged(); + novelFragmentChapters.updateAdapter(); + return true; case R.id.popup_chapter_menu_mark_unread: Database.DatabaseChapter.setChapterStatus(chapterID, Status.UNREAD); - NovelFragmentChapters.adapter.notifyDataSetChanged(); + novelFragmentChapters.updateAdapter(); + return true; case R.id.popup_chapter_menu_mark_reading: Database.DatabaseChapter.setChapterStatus(chapterID, Status.READING); - NovelFragmentChapters.adapter.notifyDataSetChanged(); + novelFragmentChapters.updateAdapter(); + return true; case R.id.browser: if (novelFragmentChapters.getActivity() != null) @@ -149,9 +157,10 @@ public void addToSelect() { novelFragmentChapters.selectedChapters.add(novelChapter); else removeFromSelect(); - if (novelFragmentChapters.selectedChapters.size() == 1 || novelFragmentChapters.selectedChapters.size() <= 0) + if ((novelFragmentChapters.selectedChapters.size() == 1 || novelFragmentChapters.selectedChapters.size() <= 0) && novelFragmentChapters.getInflater() != null) novelFragmentChapters.onCreateOptionsMenu(novelFragmentChapters.menu, novelFragmentChapters.getInflater()); - NovelFragmentChapters.recyclerView.post(() -> NovelFragmentChapters.adapter.notifyDataSetChanged()); + novelFragmentChapters.updateAdapter(); + } private void removeFromSelect() { @@ -165,6 +174,7 @@ private void removeFromSelect() { @Override public void onClick(View v) { - openChapter(novelFragmentChapters.getActivity(), novelChapter, novelFragmentChapters.novelFragment.novelID, novelFragmentChapters.novelFragment.formatter.getID()); + if (novelFragmentChapters.getActivity() != null && novelFragmentChapters.novelFragment.formatter != null) + openChapter(novelFragmentChapters.getActivity(), novelChapter, novelFragmentChapters.novelFragment.novelID, novelFragmentChapters.novelFragment.formatter.getID()); } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java index 45cc370998..3e40f353de 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/NewChapterReader.java @@ -77,7 +77,7 @@ public class NewChapterReader extends AppCompatActivity { private final MenuItem[] readers = new MenuItem[2]; MenuItem bookmark, tap_to_scroll; - ViewPager viewPager; + public ViewPager viewPager; public Toolbar toolbar; diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java index ae0cb873e5..4b589de37f 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/reader/viewHolders/NewChapterView.java @@ -18,6 +18,7 @@ */ import android.annotation.SuppressLint; +import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -25,11 +26,13 @@ import android.view.ViewGroup; import android.widget.ScrollView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.github.Doomsdayrs.api.shosetsu.services.core.objects.NovelChapter; import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.reader.NewChapterReader; @@ -37,10 +40,12 @@ import com.github.doomsdayrs.apps.shosetsu.ui.reader.listeners.NovelFragmentChapterViewHideBar; import com.github.doomsdayrs.apps.shosetsu.variables.Settings; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Status; +import com.google.android.material.chip.Chip; import java.util.Objects; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseIdentification.getChapterURLFromChapterID; +import static com.github.doomsdayrs.apps.shosetsu.ui.novel.NovelFragment.getNextChapter; /** * shosetsu @@ -56,13 +61,14 @@ public class NewChapterView extends Fragment { public ScrollView scrollView; public boolean bookmarked; + public Chip nextChapter; //public View coverView; // public ViewPager2 viewPager2; //public NewReader currentReader; private TextView textView; - public boolean ready; + public boolean ready = false; public String unformattedText; public String text; @@ -98,12 +104,26 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c View view = inflater.inflate(R.layout.new_chapter_view, container, false); scrollView = view.findViewById(R.id.scrollView); + addBottomListener(); + textView = view.findViewById(R.id.textView); textView.setOnClickListener(new NovelFragmentChapterViewHideBar(newChapterReader.toolbar)); textView.setBackgroundColor(Settings.ReaderTextBackgroundColor); textView.setTextColor(Settings.ReaderTextColor); textView.setTextSize(Settings.ReaderTextSize); + nextChapter = view.findViewById(R.id.next_chapter); + + nextChapter.setOnClickListener(view1 -> { + int position = newChapterReader.findCurrentPosition(this.CHAPTER_ID); + if (position + 1 < newChapterReader.chapterIDs.length) { + nextChapter.setVisibility(View.GONE); + newChapterReader.viewPager.setCurrentItem(position + 1); + } else + Toast.makeText(newChapterReader.getApplicationContext(), "No more chapters!", Toast.LENGTH_SHORT).show(); + // Toast.makeText(newChapterReader.getApplicationContext(), "Cannot move to next chapter, Please exit reader", Toast.LENGTH_LONG).show(); + }); + updateParent(); @@ -151,4 +171,44 @@ else if (text.length() > 0) // viewPager2.post(() -> currentReader.setText(text)); } } + + + /** + * What to do when scroll hits bottom + */ + private void bottom() { + int total = scrollView.getChildAt(0).getHeight() - scrollView.getHeight(); + if (ready) + if ((scrollView.getScrollY() / (float) total) < .99) { + int y = scrollView.getScrollY(); + if (y % 5 == 0) { + // Log.d("YMAX", String.valueOf(total)); + // Log.d("YC", String.valueOf(y)); + // Log.d("YD", String.valueOf((scrollView.getScrollY() / (float) total))); + + // Log.d("TY", String.valueOf(textView.getScrollY())); + + if (Database.DatabaseChapter.getStatus(CHAPTER_ID) != Status.READ) + Database.DatabaseChapter.updateY(CHAPTER_ID, y); + } + } else { + Log.i("Scroll", "Marking chapter as READ"); + Database.DatabaseChapter.setChapterStatus(CHAPTER_ID, Status.READ); + Database.DatabaseChapter.updateY(CHAPTER_ID, 0); + nextChapter.setVisibility(View.VISIBLE); + //TODO Get total word count of passage, then add to a storage counter that memorizes the total (Chapters read, Chapters Unread, Chapters reading, Word count) + } + } + + + /** + * Sets up the hitting bottom listener + */ + private void addBottomListener() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> bottom()); + } else { + scrollView.getViewTreeObserver().addOnScrollChangedListener(this::bottom); + } + } } diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java index 1215f52b63..1eb8dc35fe 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/settings/SettingsFragment.java @@ -14,13 +14,14 @@ import com.github.doomsdayrs.apps.shosetsu.R; import com.github.doomsdayrs.apps.shosetsu.ui.settings.adapter.SettingsAdapter; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.github.doomsdayrs.apps.shosetsu.variables.enums.Types; import com.github.doomsdayrs.apps.shosetsu.variables.recycleObjects.SettingsCard; import java.util.ArrayList; import java.util.Objects; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; + /* * This file is part of Shosetsu. * @@ -83,7 +84,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d("OnCreateView", "SettingsFragment"); - Statics.mainActionBar.setTitle("Settings"); + setActivityTitle(getActivity(),"Settings"); View view = inflater.inflate(R.layout.settings, container, false); RecyclerView recyclerView = view.findViewById(R.id.settings_recycler); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java index 0854e2410b..0d9b28b8b8 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/UpdatesFragment.java @@ -39,7 +39,6 @@ import com.github.doomsdayrs.apps.shosetsu.backend.Update_Manager; import com.github.doomsdayrs.apps.shosetsu.backend.database.Database; import com.github.doomsdayrs.apps.shosetsu.ui.updates.adapters.UpdatedDaysPager; -import com.github.doomsdayrs.apps.shosetsu.variables.Statics; import com.google.android.material.tabs.TabLayout; import org.joda.time.DateTime; @@ -47,6 +46,7 @@ import java.util.ArrayList; import java.util.Collections; +import static com.github.doomsdayrs.apps.shosetsu.backend.Utilities.setActivityTitle; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseUpdates.getCountBetween; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseUpdates.getStartingDay; import static com.github.doomsdayrs.apps.shosetsu.backend.database.Database.DatabaseUpdates.getTotalDays; @@ -67,10 +67,11 @@ public UpdatesFragment() { public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.updater_now: - Update_Manager.init(Database.DatabaseNovels.getIntLibrary(), getContext()); - return true; + if (getContext() != null) { + Update_Manager.init(Database.DatabaseNovels.getIntLibrary(), getContext()); + return true; + } else return false; } - return false; } @@ -83,8 +84,7 @@ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflat @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_update, container, false); - Statics.mainActionBar.setTitle("Updates"); - + setActivityTitle(getActivity(),"Updates"); viewPager = view.findViewById(R.id.viewpager); tabLayout = view.findViewById(R.id.tabLayout); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java index b5be6b4e27..80399ebd69 100644 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java +++ b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/ui/updates/adapters/UpdatedChaptersAdapter.java @@ -118,7 +118,7 @@ public void onBindViewHolder(@NonNull UpdatedChapterHolder updatedChapterHolder, case R.id.popup_chapter_menu_download: { if (!Database.DatabaseChapter.isSaved(chapterID)) { DownloadItem downloadItem = new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, chapterID); - Download_Manager.addToDownload(downloadItem); + Download_Manager.addToDownload(activity, downloadItem); } else { if (Download_Manager.delete(updatedChapterHolder.itemView.getContext(), new DownloadItem(formatter, novelPage.title, updatedChapterHolder.novelChapter.title, chapterID))) { updatedChapterHolder.downloadTag.setVisibility(View.INVISIBLE); diff --git a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java b/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java deleted file mode 100644 index bc0ab59114..0000000000 --- a/app/src/main/java/com/github/doomsdayrs/apps/shosetsu/variables/Statics.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.doomsdayrs.apps.shosetsu.variables; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; - -/* - * This file is part of Shosetsu. - * - * Shosetsu is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Shosetsu is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Shosetsu. If not, see . - * ==================================================================== - * Shosetsu - * 20 / 06 / 2019 - * - * @author github.com/doomsdayrs - */ - -/** - * Static variables to work with - */ -public class Statics { - @Nullable - public static ActionBar mainActionBar; -} diff --git a/app/src/main/res/layout/new_chapter_view.xml b/app/src/main/res/layout/new_chapter_view.xml index a5d92d62e3..33e02393db 100644 --- a/app/src/main/res/layout/new_chapter_view.xml +++ b/app/src/main/res/layout/new_chapter_view.xml @@ -2,7 +2,9 @@ + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools"> + + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.0"> + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_info.xml b/app/src/main/res/layout/settings_info.xml index ff21a2771d..6218d12d70 100644 --- a/app/src/main/res/layout/settings_info.xml +++ b/app/src/main/res/layout/settings_info.xml @@ -1,27 +1,8 @@ - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_item.xml b/app/src/main/res/layout/settings_item.xml index 20de5950c3..6e62f18d06 100644 --- a/app/src/main/res/layout/settings_item.xml +++ b/app/src/main/res/layout/settings_item.xml @@ -1,29 +1,81 @@ - + + - + + + + - + + + +