diff --git a/build.gradle b/build.gradle index da7ff9338..e40241cd9 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,7 @@ allprojects { jcenter() google() maven { url 'https://dl.bintray.com/inorichi/tachiyomi' } + maven { url "https://jitpack.io" } } } diff --git a/lib/preference-stub/build.gradle b/lib/preference-stub/build.gradle new file mode 100644 index 000000000..80509ba3f --- /dev/null +++ b/lib/preference-stub/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'java-library' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} + +sourceCompatibility = "1.6" +targetCompatibility = "1.6" diff --git a/lib/preference-stub/src/main/java/android/content/Context.java b/lib/preference-stub/src/main/java/android/content/Context.java new file mode 100644 index 000000000..f27638c6c --- /dev/null +++ b/lib/preference-stub/src/main/java/android/content/Context.java @@ -0,0 +1,7 @@ +package android.content; + +/** + * Created by Carlos on 5/9/2018. + */ + +public class Context {} diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/DialogPreference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/DialogPreference.java new file mode 100644 index 000000000..e7a7f280e --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/DialogPreference.java @@ -0,0 +1,7 @@ +package android.support.v7.preference; + +/** + * Created by Carlos on 5/9/2018. + */ + +public abstract class DialogPreference extends Preference {} diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/ListPreference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/ListPreference.java new file mode 100644 index 000000000..1359b6b26 --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/ListPreference.java @@ -0,0 +1,69 @@ +package android.support.v7.preference; + +import android.content.Context; + +/** + * Created by Carlos on 5/9/2018. + */ + +public class ListPreference extends Preference { + + public ListPreference(Context context) { + throw new RuntimeException("Stub!"); + } + + public CharSequence getTitle() { + throw new RuntimeException("Stub!"); + + } + + public void setTitle(CharSequence title) { + throw new RuntimeException("Stub!"); + } + + public void setEntries(CharSequence[] entries) { + throw new RuntimeException("Stub!"); + } + + public CharSequence[] getEntries() { + throw new RuntimeException("Stub!"); + + } + + public void setOnPreferenceChangeListener(OnPreferenceChangeListener onPreferenceChangeListener) { + throw new RuntimeException("Stub!"); + + } + + public int findIndexOfValue(String value) { + throw new RuntimeException("Stub!"); + } + + public void setEntryValues(CharSequence[] entryValues) { + throw new RuntimeException("Stub!"); + } + + public CharSequence[] getEntryValues() { + throw new RuntimeException("Stub!"); + } + + public void setValueIndex(int index) { + throw new RuntimeException("Stub!"); + } + + public String getValue() { + throw new RuntimeException("Stub!"); + } + + public void setValue(String value) { + throw new RuntimeException("Stub!"); + } + + public void setSummary(CharSequence summary) { + throw new RuntimeException("Stub!"); + } + + public CharSequence getSummary() { + throw new RuntimeException("Stub!"); + } +} diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java new file mode 100644 index 000000000..9baf39539 --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java @@ -0,0 +1,19 @@ +package android.support.v7.preference; + +/** + * Created by Carlos on 5/9/2018. + */ + +public class Preference { + public interface OnPreferenceChangeListener { + boolean onPreferenceChange(Preference preference, Object newValue); + } + + public void setKey(String key) { + throw new RuntimeException("Stub!"); + } + + public String getKey() { + throw new RuntimeException("Stub!"); + } +} diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/PreferenceScreen.java b/lib/preference-stub/src/main/java/android/support/v7/preference/PreferenceScreen.java new file mode 100644 index 000000000..26badb6c8 --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/PreferenceScreen.java @@ -0,0 +1,18 @@ +package android.support.v7.preference; + +import android.content.Context; + +/** + * Created by Carlos on 5/7/2018. + */ + +public class PreferenceScreen{ + + public boolean addPreference(Preference preference) { + throw new RuntimeException("Stub!"); + } + + public Context getContext() { + throw new RuntimeException("Stub!"); + } +} diff --git a/lib/preference-stub/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.java b/lib/preference-stub/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.java new file mode 100644 index 000000000..727b53763 --- /dev/null +++ b/lib/preference-stub/src/main/java/eu/kanade/tachiyomi/source/ConfigurableSource.java @@ -0,0 +1,13 @@ +package eu.kanade.tachiyomi.source; + +import android.support.v7.preference.PreferenceScreen; + +/** + * Created by Carlos on 5/7/2018. + */ + +public interface ConfigurableSource { + + void setupPreferenceScreen(PreferenceScreen screen); + +} diff --git a/settings.gradle b/settings.gradle index b8a9c2a7e..4619bfc30 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,4 +6,6 @@ new File(rootDir, "src").eachDir { dir -> } } include ':duktape-stub' -project(':duktape-stub').projectDir = new File("lib/duktape-stub") \ No newline at end of file +include ':preference-stub' +project(':duktape-stub').projectDir = new File("lib/duktape-stub") +project(':preference-stub').projectDir = new File("lib/preference-stub") \ No newline at end of file diff --git a/src/all/mangadex/build.gradle b/src/all/mangadex/build.gradle index c7a377643..16f1cc464 100644 --- a/src/all/mangadex/build.gradle +++ b/src/all/mangadex/build.gradle @@ -5,14 +5,16 @@ ext { appName = 'Tachiyomi: MangaDex' pkgNameSuffix = "all.mangadex" extClass = '.MangadexFactory' - extVersionCode = 22 - extVersionSuffix = 22 + extVersionCode = 23 + extVersionSuffix = 23 libVersion = '1.2' } dependencies { provided "com.google.code.gson:gson:2.8.0" provided "com.github.salomonbrys.kotson:kotson:2.5.0" + provided project(':preference-stub') + provided "com.github.inorichi.injekt:injekt-core:65b0440" } apply from: "$rootDir/common.gradle" diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt index a6a4e9816..60c08b542 100644 --- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt +++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/Mangadex.kt @@ -1,10 +1,15 @@ package eu.kanade.tachiyomi.extension.all.mangadex +import android.app.Application +import android.content.SharedPreferences +import android.support.v7.preference.ListPreference +import android.support.v7.preference.PreferenceScreen import com.github.salomonbrys.kotson.* import com.google.gson.JsonObject import com.google.gson.JsonParser import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.asObservableSuccess +import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.online.ParsedHttpSource import okhttp3.HttpUrl @@ -15,11 +20,14 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.nodes.Element import rx.Observable +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import java.net.URLEncoder import java.util.* import java.util.concurrent.TimeUnit -open class Mangadex(override val lang: String, private val internalLang: String, private val langCode: Int) : ParsedHttpSource() { +open class Mangadex(override val lang: String, private val internalLang: String, private val langCode: Int) : ConfigurableSource, ParsedHttpSource() { + override val name = "MangaDex" @@ -27,7 +35,12 @@ open class Mangadex(override val lang: String, private val internalLang: String, override val supportsLatest = true - override val client = clientBuilder(ALL) + private val preferences: SharedPreferences by lazy { + Injekt.get().getSharedPreferences("source_$id", 0x0000) + } + + private fun clientBuilder(): OkHttpClient = clientBuilder(getShowR18()) + private fun clientBuilder(r18Toggle: Int): OkHttpClient = network.cloudflareClient.newBuilder() .connectTimeout(10, TimeUnit.SECONDS) @@ -97,6 +110,22 @@ open class Mangadex(override val lang: String, private val internalLang: String, override fun searchMangaNextPageSelector() = ".pagination li:not(.disabled) span[title*=last page]:not(disabled)" + override fun fetchPopularManga(page: Int): Observable { + return clientBuilder().newCall(popularMangaRequest(page)) + .asObservableSuccess() + .map { response -> + popularMangaParse(response) + } + } + + override fun fetchLatestUpdates(page: Int): Observable { + return clientBuilder().newCall(latestUpdatesRequest(page)) + .asObservableSuccess() + .map { response -> + latestUpdatesParse(response) + } + } + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return getSearchClient(filters).newCall(searchMangaRequest(page, query, filters)) .asObservableSuccess() @@ -105,8 +134,6 @@ open class Mangadex(override val lang: String, private val internalLang: String, } } - /* get search client based off r18 filter. This will always return default client builder now until r18 solution is found or login is add - */ private fun getSearchClient(filters: FilterList): OkHttpClient { filters.forEach { filter -> when (filter) { @@ -165,7 +192,7 @@ open class Mangadex(override val lang: String, private val internalLang: String, } override fun fetchMangaDetails(manga: SManga): Observable { - return client.newCall(apiRequest(manga)) + return clientBuilder().newCall(apiRequest(manga)) .asObservableSuccess() .map { response -> mangaDetailsParse(response).apply { initialized = true } @@ -192,11 +219,18 @@ open class Mangadex(override val lang: String, private val internalLang: String, var jsonData = response.body()!!.string() val json = JsonParser().parse(jsonData).asJsonObject val mangaJson = json.getAsJsonObject("manga") + manga.title = baseUrl + mangaJson.get("title").string manga.thumbnail_url = baseUrl + mangaJson.get("cover_url").string manga.description = cleanString(mangaJson.get("description").string) manga.author = mangaJson.get("author").string manga.artist = mangaJson.get("artist").string - manga.status = parseStatus(mangaJson.get("status").int) + val finalChapterNumber = mangaJson.get("last_chapter").int + if (finalChapterNumber != 0) { + manga.status = SManga.COMPLETED + } else { + manga.status = parseStatus(mangaJson.get("status").int) + } + var genres = mutableListOf() mangaJson.get("genres").asJsonArray.forEach { id -> @@ -219,7 +253,7 @@ open class Mangadex(override val lang: String, private val internalLang: String, override fun chapterListSelector() = "" override fun fetchChapterList(manga: SManga): Observable> { - return client.newCall(apiRequest(manga)) + return clientBuilder().newCall(apiRequest(manga)) .asObservableSuccess() .map { response -> chapterListParse(response) @@ -230,6 +264,9 @@ open class Mangadex(override val lang: String, private val internalLang: String, val now = Date().time var jsonData = response.body()!!.string() val json = JsonParser().parse(jsonData).asJsonObject + val mangaJson = json.getAsJsonObject("manga") + + val finalChapterNumber = mangaJson.get("last_chapter").double val chapterJson = json.getAsJsonObject("chapter") val chapters = mutableListOf() @@ -238,13 +275,13 @@ open class Mangadex(override val lang: String, private val internalLang: String, val chapterElement = jsonElement.asJsonObject if (chapterElement.get("lang_code").string == internalLang && (chapterElement.get("timestamp").asLong * 1000) <= now) { chapterElement.toString() - chapters.add(chapterFromJson(key, chapterElement)) + chapters.add(chapterFromJson(key, chapterElement, finalChapterNumber)) } } return chapters } - private fun chapterFromJson(chapterId: String, chapterJson: JsonObject): SChapter { + private fun chapterFromJson(chapterId: String, chapterJson: JsonObject, finalChapterNumber: Double): SChapter { val chapter = SChapter.create() chapter.url = BASE_CHAPTER + chapterId var chapterName = mutableListOf() @@ -259,6 +296,9 @@ open class Mangadex(override val lang: String, private val internalLang: String, chapterName.add("-") chapterName.add(chapterJson.get("title").string) } + if (finalChapterNumber != 0.00 && chapterJson.get("chapter").double == finalChapterNumber) { + chapterName.add(" [END]") + } chapter.name = cleanString(chapterName.joinToString(" ")) //convert from unix time @@ -302,7 +342,6 @@ open class Mangadex(override val lang: String, private val internalLang: String, private fun parseStatus(status: Int) = when (status) { 1 -> SManga.ONGOING - 2 -> SManga.COMPLETED else -> SManga.UNKNOWN } @@ -314,6 +353,28 @@ open class Mangadex(override val lang: String, private val internalLang: String, return baseUrl + attr } + override fun setupPreferenceScreen(screen: PreferenceScreen) { + val myPref = ListPreference(screen.context).apply { + key = SHOW_R18_PREF_Title + title = SHOW_R18_PREF_Title + + title = SHOW_R18_PREF_Title + entries = arrayOf("Show No R18+", "Show All", "Show Only R18+") + entryValues = arrayOf("0", "1", "2") + summary = "%s" + + setOnPreferenceChangeListener { _, newValue -> + val selected = newValue as String + val index = this.findIndexOfValue(selected) + preferences.edit().putInt(SHOW_R18_PREF, index).commit() + } + } + screen.addPreference(myPref) + } + + private fun getShowR18(): Int = preferences.getInt(SHOW_R18_PREF, 0) + + private class TextField(name: String, val key: String) : Filter.Text(name) private class Genre(val id: String, name: String) : Filter.CheckBox(name) private class GenreList(genres: List) : Filter.Group("Genres", genres) @@ -376,6 +437,8 @@ open class Mangadex(override val lang: String, private val internalLang: String, private const val NO_R18 = 0 private const val ALL = 1 private const val ONLY_R18 = 2 + private const val SHOW_R18_PREF_Title = "Default R18 Setting" + private const val SHOW_R18_PREF = "showR18Default" private const val URL = "/api/3640f3fb/" private const val BASE_CHAPTER = "/chapter/"