From 68aca55e6f8e2b506a2b5000c32a8bfd9aed75e4 Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 16 Apr 2019 11:34:52 -0400 Subject: [PATCH 01/13] Add options to open catalogue in browser/webview (#1979) --- .../browse/BrowseCatalogueController.kt | 25 +++++++++++++++++++ .../ui/manga/info/MangaInfoController.kt | 11 ++------ .../tachiyomi/util/ContextExtensions.kt | 18 +++++++++++++ app/src/main/res/menu/catalogue_list.xml | 11 ++++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 80f284204f..97cfd76e16 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -17,11 +17,13 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.SecondaryDrawerController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.manga.MangaController +import eu.kanade.tachiyomi.ui.manga.info.MangaWebViewController import eu.kanade.tachiyomi.util.* import eu.kanade.tachiyomi.widget.AutofitRecyclerView import kotlinx.android.synthetic.main.catalogue_controller.* @@ -259,15 +261,38 @@ open class BrowseCatalogueController(bundle: Bundle) : } } + override fun onPrepareOptionsMenu(menu: Menu) { + super.onPrepareOptionsMenu(menu) + + val isHttpSource = presenter.source is HttpSource + menu.findItem(R.id.action_open_in_browser).isVisible = isHttpSource + menu.findItem(R.id.action_open_in_web_view).isVisible = isHttpSource + } + override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_display_mode -> swapDisplayMode() R.id.action_set_filter -> navView?.let { activity?.drawer?.openDrawer(Gravity.END) } + R.id.action_open_in_browser -> openInBrowser() + R.id.action_open_in_web_view -> openInWebView() else -> return super.onOptionsItemSelected(item) } return true } + private fun openInBrowser() { + val source = presenter.source as? HttpSource ?: return + + activity?.openInBrowser(source.baseUrl) + } + + private fun openInWebView() { + val source = presenter.source as? HttpSource ?: return + + router.pushController(MangaWebViewController(source.id, source.baseUrl) + .withFadeTransaction()) + } + /** * Restarts the request with a new query. * diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index f2a0f412ef..b3bb48289a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -42,6 +42,7 @@ import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.util.getResourceColor +import eu.kanade.tachiyomi.util.openInBrowser import eu.kanade.tachiyomi.util.snack import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.truncateCenter @@ -287,15 +288,7 @@ class MangaInfoController : NucleusController(), val context = view?.context ?: return val source = presenter.source as? HttpSource ?: return - try { - val url = Uri.parse(source.mangaDetailsRequest(presenter.manga).url().toString()) - val intent = CustomTabsIntent.Builder() - .setToolbarColor(context.getResourceColor(R.attr.colorPrimary)) - .build() - intent.launchUrl(activity, url) - } catch (e: Exception) { - context.toast(e.message) - } + context.openInBrowser(source.mangaDetailsRequest(presenter.manga).url().toString()) } private fun openInWebView() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt index d89b3ce5a4..2c54b236c5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/ContextExtensions.kt @@ -10,14 +10,17 @@ import android.content.IntentFilter import android.content.pm.PackageManager import android.content.res.Resources import android.net.ConnectivityManager +import android.net.Uri import android.os.PowerManager import android.support.annotation.AttrRes import android.support.annotation.StringRes +import android.support.customtabs.CustomTabsIntent import android.support.v4.app.NotificationCompat import android.support.v4.content.ContextCompat import android.support.v4.content.LocalBroadcastManager import android.widget.Toast import com.nononsenseapps.filepicker.FilePickerActivity +import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.widget.CustomLayoutPickerActivity /** @@ -163,3 +166,18 @@ fun Context.isServiceRunning(serviceClass: Class<*>): Boolean { return manager.getRunningServices(Integer.MAX_VALUE) .any { className == it.service.className } } + +/** + * Opens a URL in a custom tab. + */ +fun Context.openInBrowser(url: String) { + try { + val url = Uri.parse(url) + val intent = CustomTabsIntent.Builder() + .setToolbarColor(getResourceColor(R.attr.colorPrimary)) + .build() + intent.launchUrl(this, url) + } catch (e: Exception) { + toast(e.message) + } +} diff --git a/app/src/main/res/menu/catalogue_list.xml b/app/src/main/res/menu/catalogue_list.xml index ff4373df40..1b75d4ae75 100644 --- a/app/src/main/res/menu/catalogue_list.xml +++ b/app/src/main/res/menu/catalogue_list.xml @@ -19,4 +19,15 @@ android:id="@+id/action_display_mode" android:title="@string/action_display_mode" app:showAsAction="ifRoom"/> + + + + + From 7c6478fe6b5f7a4a19042548029d099cd4b5ade6 Mon Sep 17 00:00:00 2001 From: FlaminSarge Date: Mon, 29 Apr 2019 09:38:59 -0700 Subject: [PATCH 02/13] Force Migration to display titles from source rather than from local DB, and update local titles when migrated (#1670) --- .../data/database/queries/MangaQueries.kt | 5 +++ .../resolvers/MangaTitlePutResolver.kt | 32 +++++++++++++++++++ .../resolvers/MangaViewerPutResolver.kt | 8 ++--- .../global_search/CatalogueSearchPresenter.kt | 2 +- .../ui/migration/MigrationPresenter.kt | 3 ++ .../tachiyomi/ui/migration/SearchPresenter.kt | 8 +++++ 6 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaTitlePutResolver.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt index a27a11c342..a64a097925 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt @@ -82,6 +82,11 @@ interface MangaQueries : DbProvider { .withPutResolver(MangaViewerPutResolver()) .prepare() + fun updateMangaTitle(manga: Manga) = db.put() + .`object`(manga) + .withPutResolver(MangaTitlePutResolver()) + .prepare() + fun deleteManga(manga: Manga) = db.delete().`object`(manga).prepare() fun deleteMangas(mangas: List) = db.delete().objects(mangas).prepare() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaTitlePutResolver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaTitlePutResolver.kt new file mode 100644 index 0000000000..702173afbe --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaTitlePutResolver.kt @@ -0,0 +1,32 @@ +package eu.kanade.tachiyomi.data.database.resolvers + +import android.content.ContentValues +import com.pushtorefresh.storio.sqlite.StorIOSQLite +import com.pushtorefresh.storio.sqlite.operations.put.PutResolver +import com.pushtorefresh.storio.sqlite.operations.put.PutResult +import com.pushtorefresh.storio.sqlite.queries.UpdateQuery +import eu.kanade.tachiyomi.data.database.inTransactionReturn +import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.data.database.tables.MangaTable + +class MangaTitlePutResolver : PutResolver() { + + override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn { + val updateQuery = mapToUpdateQuery(manga) + val contentValues = mapToContentValues(manga) + + val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues) + PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table()) + } + + fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder() + .table(MangaTable.TABLE) + .where("${MangaTable.COL_ID} = ?") + .whereArgs(manga.id) + .build() + + fun mapToContentValues(manga: Manga) = ContentValues(1).apply { + put(MangaTable.COL_TITLE, manga.title) + } + +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaViewerPutResolver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaViewerPutResolver.kt index 86c67f3463..e40f397a8d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaViewerPutResolver.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaViewerPutResolver.kt @@ -20,10 +20,10 @@ class MangaViewerPutResolver : PutResolver() { } fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder() - .table(MangaTable.TABLE) - .where("${MangaTable.COL_ID} = ?") - .whereArgs(manga.id) - .build() + .table(MangaTable.TABLE) + .where("${MangaTable.COL_ID} = ?") + .whereArgs(manga.id) + .build() fun mapToContentValues(manga: Manga) = ContentValues(1).apply { put(MangaTable.COL_VIEWER, manga.viewer) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchPresenter.kt index b0cc97a62a..39bcfc1c65 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchPresenter.kt @@ -239,7 +239,7 @@ open class CatalogueSearchPresenter( * @param sManga the manga from the source. * @return a manga from the database. */ - private fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga { + protected open fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga { var localManga = db.getManga(sManga.url, sourceId).executeAsBlocking() if (localManga == null) { val newManga = Manga.create(sManga.url, sManga.title, sourceId) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationPresenter.kt index 712006367d..35b6bc06bd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationPresenter.kt @@ -146,6 +146,9 @@ class MigrationPresenter( } manga.favorite = true db.updateMangaFavorite(manga).executeAsBlocking() + + // SearchPresenter#networkToLocalManga may have updated the manga title, so ensure db gets updated title + db.updateMangaTitle(manga).executeAsBlocking() } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchPresenter.kt index 2a7f218b8c..b4a31c0da6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/migration/SearchPresenter.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.migration import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.source.CatalogueSource +import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchCardItem import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchItem import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchPresenter @@ -21,4 +22,11 @@ class SearchPresenter( //Set the catalogue search item as highlighted if the source matches that of the selected manga return CatalogueSearchItem(source, results, source.id == manga.source) } + + override fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga { + val localManga = super.networkToLocalManga(sManga, sourceId) + // For migration, displayed title should always match source rather than local DB + localManga.title = sManga.title + return localManga + } } From 5840a3e1e2388c3f2f77ef22f6620282e13186b9 Mon Sep 17 00:00:00 2001 From: Pavka Date: Mon, 29 Apr 2019 19:40:26 +0300 Subject: [PATCH 03/13] Shikomori -> Shikimori. Fix update chapters (#1996) * Shikomori -> Shikimori. Fix update chapters * Removed logs and format code --- app/src/main/AndroidManifest.xml | 4 +- .../tachiyomi/data/track/TrackManager.kt | 8 +-- .../track/{shikomori => shikimori}/OAuth.kt | 2 +- .../Shikomori.kt => shikimori/Shikimori.kt} | 13 ++-- .../ShikimoriApi.kt} | 56 +++++++++++------- .../ShikimoriInterceptor.kt} | 12 ++-- .../data/track/shikimori/ShikimoriModels.kt | 24 ++++++++ .../data/track/shikomori/ShikomoriModels.kt | 24 -------- .../ui/setting/SettingsTrackingController.kt | 8 +-- .../ui/setting/ShikomoriLoginActivity.kt | 6 +- .../{shikomori.png => shikimori.png} | Bin 11 files changed, 87 insertions(+), 70 deletions(-) rename app/src/main/java/eu/kanade/tachiyomi/data/track/{shikomori => shikimori}/OAuth.kt (83%) rename app/src/main/java/eu/kanade/tachiyomi/data/track/{shikomori/Shikomori.kt => shikimori/Shikimori.kt} (89%) rename app/src/main/java/eu/kanade/tachiyomi/data/track/{shikomori/ShikomoriApi.kt => shikimori/ShikimoriApi.kt} (77%) rename app/src/main/java/eu/kanade/tachiyomi/data/track/{shikomori/ShikomoriInterceptor.kt => shikimori/ShikimoriInterceptor.kt} (79%) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriModels.kt delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriModels.kt rename app/src/main/res/drawable-xxxhdpi/{shikomori.png => shikimori.png} (100%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index feddf20960..eff4c70578 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -62,8 +62,8 @@ + android:name=".ui.setting.ShikimoriLoginActivity" + android:label="Shikimori"> diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt index 14558d1f1b..70d669af56 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackManager.kt @@ -4,7 +4,7 @@ import android.content.Context import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.data.track.kitsu.Kitsu import eu.kanade.tachiyomi.data.track.myanimelist.Myanimelist -import eu.kanade.tachiyomi.data.track.shikomori.Shikomori +import eu.kanade.tachiyomi.data.track.shikimori.Shikimori class TrackManager(private val context: Context) { @@ -12,7 +12,7 @@ class TrackManager(private val context: Context) { const val MYANIMELIST = 1 const val ANILIST = 2 const val KITSU = 3 - const val SHIKOMORI = 4 + const val SHIKIMORI = 4 } val myAnimeList = Myanimelist(context, MYANIMELIST) @@ -21,9 +21,9 @@ class TrackManager(private val context: Context) { val kitsu = Kitsu(context, KITSU) - val shikomori = Shikomori(context, SHIKOMORI) + val shikimori = Shikimori(context, SHIKIMORI) - val services = listOf(myAnimeList, aniList, kitsu, shikomori) + val services = listOf(myAnimeList, aniList, kitsu, shikimori) fun getService(id: Int) = services.find { it.id == id } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/OAuth.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt similarity index 83% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/OAuth.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt index ad6adc18a4..118e584e73 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/OAuth.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.data.track.shikomori +package eu.kanade.tachiyomi.data.track.shikimori data class OAuth( val access_token: String, diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/Shikomori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt similarity index 89% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/Shikomori.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index 83fee74cf4..8068e6d55b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/Shikomori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -1,7 +1,8 @@ -package eu.kanade.tachiyomi.data.track.shikomori +package eu.kanade.tachiyomi.data.track.shikimori import android.content.Context import android.graphics.Color +import android.util.Log import com.google.gson.Gson import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track @@ -11,7 +12,7 @@ import rx.Completable import rx.Observable import uy.kohesive.injekt.injectLazy -class Shikomori(private val context: Context, id: Int) : TrackService(id) { +class Shikimori(private val context: Context, id: Int) : TrackService(id) { override fun getScoreList(): List { return IntRange(0, 10).map(Int::toString) @@ -75,15 +76,15 @@ class Shikomori(private val context: Context, id: Int) : TrackService(id) { const val DEFAULT_SCORE = 0 } - override val name = "Shikomori" + override val name = "Shikimori" private val gson: Gson by injectLazy() - private val interceptor by lazy { ShikomoriInterceptor(this, gson) } + private val interceptor by lazy { ShikimoriInterceptor(this, gson) } - private val api by lazy { ShikomoriApi(client, interceptor) } + private val api by lazy { ShikimoriApi(client, interceptor) } - override fun getLogo() = R.drawable.shikomori + override fun getLogo() = R.drawable.shikimori override fun getLogoColor() = Color.rgb(40, 40, 40) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt similarity index 77% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriApi.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index 2df1eae635..35dbb532b5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -1,4 +1,4 @@ -package eu.kanade.tachiyomi.data.track.shikomori +package eu.kanade.tachiyomi.data.track.shikimori import android.net.Uri import com.github.salomonbrys.kotson.array @@ -18,7 +18,7 @@ import okhttp3.* import rx.Observable import uy.kohesive.injekt.injectLazy -class ShikomoriApi(private val client: OkHttpClient, interceptor: ShikomoriInterceptor) { +class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInterceptor) { private val gson: Gson by injectLazy() private val parser = JsonParser() @@ -33,7 +33,7 @@ class ShikomoriApi(private val client: OkHttpClient, interceptor: ShikomoriInter "target_type" to "Manga", "chapters" to track.last_chapter_read, "score" to track.score.toInt(), - "status" to track.toShikomoriStatus() + "status" to track.toShikimoriStatus() ) ) val body = RequestBody.create(jsonime, payload.toString()) @@ -74,7 +74,7 @@ class ShikomoriApi(private val client: OkHttpClient, interceptor: ShikomoriInter } private fun jsonToSearch(obj: JsonObject): TrackSearch { - return TrackSearch.create(TrackManager.SHIKOMORI).apply { + return TrackSearch.create(TrackManager.SHIKIMORI).apply { media_id = obj["id"].asInt title = obj["name"].asString total_chapters = obj["chapters"].asInt @@ -87,14 +87,15 @@ class ShikomoriApi(private val client: OkHttpClient, interceptor: ShikomoriInter } } - private fun jsonToTrack(obj: JsonObject): Track { - return Track.create(TrackManager.SHIKOMORI).apply { + private fun jsonToTrack(obj: JsonObject, mangas: JsonObject): Track { + return Track.create(TrackManager.SHIKIMORI).apply { + title = mangas["name"].asString media_id = obj["id"].asInt - title = "" + total_chapters = mangas["chapters"].asInt last_chapter_read = obj["chapters"].asInt - total_chapters = obj["chapters"].asInt score = (obj["score"].asInt).toFloat() status = toTrackStatus(obj["status"].asString) + tracking_url = baseUrl + mangas["url"].asString } } @@ -108,21 +109,36 @@ class ShikomoriApi(private val client: OkHttpClient, interceptor: ShikomoriInter .url(url.toString()) .get() .build() - return authClient.newCall(request) + + val urlMangas = Uri.parse("$apiUrl/mangas").buildUpon() + .appendPath(track.media_id.toString()) + .build() + val requestMangas = Request.Builder() + .url(urlMangas.toString()) + .get() + .build() + return authClient.newCall(requestMangas) .asObservableSuccess() .map { netResponse -> val responseBody = netResponse.body()?.string().orEmpty() - if (responseBody.isEmpty()) { - throw Exception("Null Response") - } - val response = parser.parse(responseBody).array - if (response.size() > 1) { - throw Exception("Too much mangas in response") - } - val entry = response.map { - jsonToTrack(it.obj) - } - entry.firstOrNull() + parser.parse(responseBody).obj + }.flatMap { mangas -> + authClient.newCall(request) + .asObservableSuccess() + .map { netResponse -> + val responseBody = netResponse.body()?.string().orEmpty() + if (responseBody.isEmpty()) { + throw Exception("Null Response") + } + val response = parser.parse(responseBody).array + if (response.size() > 1) { + throw Exception("Too much mangas in response") + } + val entry = response.map { + jsonToTrack(it.obj, mangas) + } + entry.firstOrNull() + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt similarity index 79% rename from app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriInterceptor.kt rename to app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt index e46e7cfb4f..1540207277 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt @@ -1,26 +1,26 @@ -package eu.kanade.tachiyomi.data.track.shikomori +package eu.kanade.tachiyomi.data.track.shikimori import com.google.gson.Gson import okhttp3.Interceptor import okhttp3.Response -class ShikomoriInterceptor(val shikomori: Shikomori, val gson: Gson) : Interceptor { +class ShikimoriInterceptor(val shikimori: Shikimori, val gson: Gson) : Interceptor { /** * OAuth object used for authenticated requests. */ - private var oauth: OAuth? = shikomori.restoreToken() + private var oauth: OAuth? = shikimori.restoreToken() override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() - val currAuth = oauth ?: throw Exception("Not authenticated with Shikomori") + val currAuth = oauth ?: throw Exception("Not authenticated with Shikimori") val refreshToken = currAuth.refresh_token!! // Refresh access token if expired. if (currAuth.isExpired()) { - val response = chain.proceed(ShikomoriApi.refreshTokenRequest(refreshToken)) + val response = chain.proceed(ShikimoriApi.refreshTokenRequest(refreshToken)) if (response.isSuccessful) { newAuth(gson.fromJson(response.body()!!.string(), OAuth::class.java)) } else { @@ -38,6 +38,6 @@ class ShikomoriInterceptor(val shikomori: Shikomori, val gson: Gson) : Intercept fun newAuth(oauth: OAuth?) { this.oauth = oauth - shikomori.saveToken(oauth) + shikimori.saveToken(oauth) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriModels.kt new file mode 100644 index 0000000000..91e556bdd8 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriModels.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.data.track.shikimori + +import eu.kanade.tachiyomi.data.database.models.Track + +fun Track.toShikimoriStatus() = when (status) { + Shikimori.READING -> "watching" + Shikimori.COMPLETED -> "completed" + Shikimori.ON_HOLD -> "on_hold" + Shikimori.DROPPED -> "dropped" + Shikimori.PLANNING -> "planned" + Shikimori.REPEATING -> "rewatching" + else -> throw NotImplementedError("Unknown status") +} + +fun toTrackStatus(status: String) = when (status) { + "watching" -> Shikimori.READING + "completed" -> Shikimori.COMPLETED + "on_hold" -> Shikimori.ON_HOLD + "dropped" -> Shikimori.DROPPED + "planned" -> Shikimori.PLANNING + "rewatching" -> Shikimori.REPEATING + + else -> throw Exception("Unknown status") +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriModels.kt deleted file mode 100644 index d66f206495..0000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikomori/ShikomoriModels.kt +++ /dev/null @@ -1,24 +0,0 @@ -package eu.kanade.tachiyomi.data.track.shikomori - -import eu.kanade.tachiyomi.data.database.models.Track - -fun Track.toShikomoriStatus() = when (status) { - Shikomori.READING -> "watching" - Shikomori.COMPLETED -> "completed" - Shikomori.ON_HOLD -> "on_hold" - Shikomori.DROPPED -> "dropped" - Shikomori.PLANNING -> "planned" - Shikomori.REPEATING -> "rewatching" - else -> throw NotImplementedError("Unknown status") -} - -fun toTrackStatus(status: String) = when (status) { - "watching" -> Shikomori.READING - "completed" -> Shikomori.COMPLETED - "on_hold" -> Shikomori.ON_HOLD - "dropped" -> Shikomori.DROPPED - "planned" -> Shikomori.PLANNING - "rewatching" -> Shikomori.REPEATING - - else -> throw Exception("Unknown status") -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingController.kt index 250289cc1c..2a8f1f73ac 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsTrackingController.kt @@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.AnilistApi -import eu.kanade.tachiyomi.data.track.shikomori.ShikomoriApi +import eu.kanade.tachiyomi.data.track.shikimori.ShikimoriApi import eu.kanade.tachiyomi.util.getResourceColor import eu.kanade.tachiyomi.widget.preference.LoginPreference import eu.kanade.tachiyomi.widget.preference.TrackLoginDialog @@ -54,13 +54,13 @@ class SettingsTrackingController : SettingsController(), dialog.showDialog(router) } } - trackPreference(trackManager.shikomori) { + trackPreference(trackManager.shikimori) { onClick { val tabsIntent = CustomTabsIntent.Builder() .setToolbarColor(context.getResourceColor(R.attr.colorPrimary)) .build() tabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) - tabsIntent.launchUrl(activity, ShikomoriApi.authUrl()) + tabsIntent.launchUrl(activity, ShikimoriApi.authUrl()) } } } @@ -80,7 +80,7 @@ class SettingsTrackingController : SettingsController(), super.onActivityResumed(activity) // Manually refresh anilist holder updatePreference(trackManager.aniList.id) - updatePreference(trackManager.shikomori.id) + updatePreference(trackManager.shikimori.id) } private fun updatePreference(id: Int) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/ShikomoriLoginActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/ShikomoriLoginActivity.kt index 6c3ba6f839..d369896edb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/ShikomoriLoginActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/ShikomoriLoginActivity.kt @@ -13,7 +13,7 @@ import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers import uy.kohesive.injekt.injectLazy -class ShikomoriLoginActivity : AppCompatActivity() { +class ShikimoriLoginActivity : AppCompatActivity() { private val trackManager: TrackManager by injectLazy() @@ -25,7 +25,7 @@ class ShikomoriLoginActivity : AppCompatActivity() { val code = intent.data?.getQueryParameter("code") if (code != null) { - trackManager.shikomori.login(code) + trackManager.shikimori.login(code) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ @@ -34,7 +34,7 @@ class ShikomoriLoginActivity : AppCompatActivity() { returnToSettings() }) } else { - trackManager.shikomori.logout() + trackManager.shikimori.logout() returnToSettings() } } diff --git a/app/src/main/res/drawable-xxxhdpi/shikomori.png b/app/src/main/res/drawable-xxxhdpi/shikimori.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/shikomori.png rename to app/src/main/res/drawable-xxxhdpi/shikimori.png From 021dde66ebb854f54de7b461c8e6783b43c5198f Mon Sep 17 00:00:00 2001 From: Deumiankio <39210184+Deumiankio@users.noreply.github.com> Date: Mon, 29 Apr 2019 19:32:49 +0200 Subject: [PATCH 04/13] Add color filter blend modes (#2013) * Add color filter blend modes * Only show modes supported by currently used API level. * Fix arrays.xml for API level <=27. --- .../data/preference/PreferenceKeys.kt | 2 ++ .../data/preference/PreferencesHelper.kt | 2 ++ .../tachiyomi/ui/reader/ReaderActivity.kt | 5 ++- .../ui/reader/ReaderColorFilterSheet.kt | 11 +++++- .../ui/reader/ReaderColorFilterView.kt | 32 +++++++++++++++++ .../layout-land/reader_color_filter_sheet.xml | 2 +- app/src/main/res/layout/reader_activity.xml | 2 +- .../main/res/layout/reader_color_filter.xml | 36 ++++++++++++++++++- .../res/layout/reader_color_filter_sheet.xml | 2 +- app/src/main/res/values-v28/arrays.xml | 15 ++++++++ app/src/main/res/values/arrays.xml | 6 ++++ app/src/main/res/values/strings.xml | 7 ++++ 12 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt create mode 100644 app/src/main/res/values-v28/arrays.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 1b2e6bb322..eb5f9d4a1e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -29,6 +29,8 @@ object PreferenceKeys { const val colorFilterValue = "color_filter_value" + const val colorFilterMode = "color_filter_mode" + const val defaultViewer = "pref_default_viewer_key" const val imageScaleType = "pref_image_scale_type_key" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 58ad2b0aff..6545b4a39e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -57,6 +57,8 @@ class PreferencesHelper(val context: Context) { fun colorFilterValue() = rxPrefs.getInteger(Keys.colorFilterValue, 0) + fun colorFilterMode() = rxPrefs.getInteger(Keys.colorFilterMode, 0) + fun defaultViewer() = prefs.getInt(Keys.defaultViewer, 1) fun imageScaleType() = rxPrefs.getInteger(Keys.imageScaleType, 1) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index c3b8aefd80..ee324e8966 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -574,6 +574,9 @@ class ReaderActivity : BaseRxActivity() { subscriptions += preferences.colorFilter().asObservable() .subscribe { setColorFilter(it) } + + subscriptions += preferences.colorFilterMode().asObservable() + .subscribe { setColorFilter(preferences.colorFilter().getOrDefault()) } } /** @@ -722,7 +725,7 @@ class ReaderActivity : BaseRxActivity() { */ private fun setColorFilterValue(value: Int) { color_overlay.visibility = View.VISIBLE - color_overlay.setBackgroundColor(value) + color_overlay.setFilterColor(value, preferences.colorFilterMode().getOrDefault()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt index 263bd5de2c..a0579cdccf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt @@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.util.plusAssign +import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import eu.kanade.tachiyomi.widget.SimpleSeekBarListener import kotlinx.android.synthetic.main.reader_color_filter.* import kotlinx.android.synthetic.main.reader_color_filter_sheet.* @@ -54,6 +55,9 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ subscriptions += preferences.colorFilter().asObservable() .subscribe { setColorFilter(it, view) } + subscriptions += preferences.colorFilterMode().asObservable() + .subscribe { setColorFilter(preferences.colorFilter().getOrDefault(), view) } + subscriptions += preferences.customBrightness().asObservable() .subscribe { setCustomBrightness(it, view) } @@ -84,6 +88,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ preferences.customBrightness().set(isChecked) } + color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> + preferences.colorFilterMode().set(position) + } + color_filter_mode.setSelection(preferences.colorFilterMode().getOrDefault(), false) + seekbar_color_filter_alpha.setOnSeekBarChangeListener(object : SimpleSeekBarListener() { override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { if (fromUser) { @@ -248,7 +257,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ */ private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) { color_overlay.visibility = View.VISIBLE - color_overlay.setBackgroundColor(color) + color_overlay.setFilterColor(color, preferences.colorFilterMode().getOrDefault()) setValues(color, view) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt new file mode 100644 index 0000000000..01d91a3b4a --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt @@ -0,0 +1,32 @@ +package eu.kanade.tachiyomi.ui.reader + +import android.content.Context +import android.graphics.* +import android.util.AttributeSet +import android.view.View + +class ReaderColorFilterView( + context: Context, + attrs: AttributeSet? = null +) : View(context, attrs) { + + private val colorFilterPaint: Paint = Paint() + + fun setFilterColor(color: Int, filterMode: Int) { + colorFilterPaint.setColor(color) + colorFilterPaint.xfermode = PorterDuffXfermode(when (filterMode) { + 1 -> PorterDuff.Mode.MULTIPLY + 2 -> PorterDuff.Mode.SCREEN + 3 -> PorterDuff.Mode.OVERLAY + 4 -> PorterDuff.Mode.LIGHTEN + 5 -> PorterDuff.Mode.DARKEN + else -> PorterDuff.Mode.SRC_OVER + }) + invalidate() + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + canvas.drawPaint(colorFilterPaint) + } +} diff --git a/app/src/main/res/layout-land/reader_color_filter_sheet.xml b/app/src/main/res/layout-land/reader_color_filter_sheet.xml index ba4d45e406..761c279928 100644 --- a/app/src/main/res/layout-land/reader_color_filter_sheet.xml +++ b/app/src/main/res/layout-land/reader_color_filter_sheet.xml @@ -29,7 +29,7 @@ android:layout_height="wrap_content" android:visibility="gone" /> - - + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/color_filter_mode_text"/> @@ -202,4 +229,11 @@ app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar" app:layout_constraintRight_toRightOf="parent"/> + + diff --git a/app/src/main/res/layout/reader_color_filter_sheet.xml b/app/src/main/res/layout/reader_color_filter_sheet.xml index 618a8a77f0..3155bc15cb 100644 --- a/app/src/main/res/layout/reader_color_filter_sheet.xml +++ b/app/src/main/res/layout/reader_color_filter_sheet.xml @@ -21,7 +21,7 @@ android:layout_height="match_parent" android:visibility="gone" /> - + + + + @string/filter_mode_default + @string/filter_mode_multiply + @string/filter_mode_screen + + + @string/filter_mode_overlay + @string/filter_mode_lighten + @string/filter_mode_darken + + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 9018a31f7c..76bd9430ce 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -102,4 +102,10 @@ 2 + + @string/filter_mode_default + @string/filter_mode_multiply + @string/filter_mode_screen + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2388bdc1f8..14ab046b10 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -178,6 +178,13 @@ Crop borders Use custom brightness Use custom color filter + Color filter blend mode + Default + Overlay + Multiply + Screen + Dodge / Lighten + Burn / Darken Keep screen on Skip chapters marked read Navigation From 5c1770247c71901db2455cc2b079263e2718a0c3 Mon Sep 17 00:00:00 2001 From: DarKCroX Date: Fri, 3 May 2019 19:32:31 +0800 Subject: [PATCH 05/13] Update README.md mangafox has been broken for months --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b21282d6b..294bb39cea 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Tachiyomi is a free and open source manga reader for Android. ## Features Features include: -* Online reading from sources such as KissManga, MangaFox, [and more](https://github.com/inorichi/tachiyomi-extensions) +* Online reading from sources such as KissManga, MangaDex, [and more](https://github.com/inorichi/tachiyomi-extensions) * Local reading of downloaded manga * Configurable reader with multiple viewers, reading directions and other settings * [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), and [Kitsu](https://kitsu.io/explore/anime) support From 003dca9d45ff122cb24f176b314389e57b4ad7f1 Mon Sep 17 00:00:00 2001 From: Pavka Date: Tue, 7 May 2019 12:06:38 +0300 Subject: [PATCH 06/13] Bugfix. Sharing images with very long name (#1999) * Fix sharing with very long images name * Fix dropLast to take --- .../main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index fbb2f4bbfe..e24feb8e35 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -434,7 +434,8 @@ class ReaderPresenter( // Build destination file. val filename = DiskUtil.buildValidFilename( - "${manga.title} - ${chapter.name}") + " - ${page.number}.${type.extension}" + "${manga.title} - ${chapter.name}".take(225) + ) + " - ${page.number}.${type.extension}" val destFile = File(directory, filename) stream().use { input -> From a0939e1c482e11bccb4a3e72e5aa510ea3ebfb31 Mon Sep 17 00:00:00 2001 From: BlueCat300 <42893969+BlueCat300@users.noreply.github.com> Date: Thu, 16 May 2019 19:21:54 +0300 Subject: [PATCH 07/13] Update Shikimori (#2038) Domain name change due to blocking by local authorities. --- .../kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index 35dbb532b5..0180e015eb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -172,10 +172,10 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter private const val clientId = "1aaf4cf232372708e98b5abc813d795b539c5a916dbbfe9ac61bf02a360832cc" private const val clientSecret = "229942c742dd4cde803125d17d64501d91c0b12e14cb1e5120184d77d67024c0" - private const val baseUrl = "https://shikimori.org" - private const val apiUrl = "https://shikimori.org/api" - private const val oauthUrl = "https://shikimori.org/oauth/token" - private const val loginUrl = "https://shikimori.org/oauth/authorize" + private const val baseUrl = "https://shikimori.one" + private const val apiUrl = "https://shikimori.one/api" + private const val oauthUrl = "https://shikimori.one/oauth/token" + private const val loginUrl = "https://shikimori.one/oauth/authorize" private const val redirectUrl = "tachiyomi://shikimori-auth" private const val baseMangaUrl = "$apiUrl/mangas" From be3ed9b6af3f3207935191da4b72bcab323e501e Mon Sep 17 00:00:00 2001 From: inorichi Date: Fri, 24 May 2019 09:56:31 +0200 Subject: [PATCH 08/13] Create FUNDING.yml --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..410a50bd97 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: inorichi +ko_fi: inorichi From a32572fc96b3700e4c9b6781eb3a2e6c6de113b9 Mon Sep 17 00:00:00 2001 From: Harsh Parekh Date: Fri, 24 May 2019 03:57:05 -0400 Subject: [PATCH 09/13] Ignore case while sorting Library (#2048) * Ignore case while sorting Library * Simplify code As suggested by @arkon --- .../java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index eb3999ffcf..17ac0cba58 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -185,7 +185,7 @@ class LibraryPresenter( val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 -> when (sortingMode) { - LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title) + LibrarySort.ALPHA -> i1.manga.title.compareTo(i2.manga.title, true) LibrarySort.LAST_READ -> { // Get index of manga, set equal to list if size unknown. val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size From 15f225537ec1ea67939002b12f6ad61920f2709e Mon Sep 17 00:00:00 2001 From: Jannis Becker <31903525+moka491@users.noreply.github.com> Date: Sat, 25 May 2019 13:46:20 +0200 Subject: [PATCH 10/13] Update tracking sites after finishing chapter (#2044) * Added second updateTrackLastChapterRead() called whenever a chapter has been read in the reader * Removed old updateTrackLastChapterRead() so that it's not called twice. --- .../java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index e24feb8e35..b2aafa0a23 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -147,10 +147,9 @@ class ReaderPresenter( /** * Called when the user pressed the back button and is going to leave the reader. Used to - * update tracking services and trigger deletion of the downloaded chapters. + * trigger deletion of the downloaded chapters. */ fun onBackPressed() { - updateTrackLastChapterRead() deletePendingChapters() } @@ -308,7 +307,7 @@ class ReaderPresenter( /** * Called every time a page changes on the reader. Used to mark the flag of chapters being - * read, enqueue downloaded chapter deletion, and updating the active chapter if this + * read, update tracking services, enqueue downloaded chapter deletion, and updating the active chapter if this * [page]'s chapter is different from the currently active. */ fun onPageSelected(page: ReaderPage) { @@ -320,6 +319,7 @@ class ReaderPresenter( selectedChapter.chapter.last_page_read = page.index if (selectedChapter.pages?.lastIndex == page.index) { selectedChapter.chapter.read = true + updateTrackLastChapterRead() enqueueDeleteReadChapters(selectedChapter) } From 974a24d03b27a6a09b99e650be6ca0211dd572f6 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sat, 25 May 2019 07:46:42 -0400 Subject: [PATCH 11/13] Add help link to nav drawer (#2049) --- .../main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt | 6 ++++++ app/src/main/res/menu/menu_navigation.xml | 5 +++++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 12 insertions(+) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 00acfa494a..9fc4fa6ccf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -24,6 +24,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController import eu.kanade.tachiyomi.ui.setting.SettingsMainController +import eu.kanade.tachiyomi.util.openInBrowser import kotlinx.android.synthetic.main.main_activity.* import uy.kohesive.injekt.injectLazy @@ -91,6 +92,9 @@ class MainActivity : BaseActivity() { R.id.nav_drawer_settings -> { router.pushController(SettingsMainController().withFadeTransaction()) } + R.id.nav_drawer_help -> { + openInBrowser(URL_HELP) + } } } drawer.closeDrawer(GravityCompat.START) @@ -271,6 +275,8 @@ class MainActivity : BaseActivity() { const val INTENT_SEARCH = "eu.kanade.tachiyomi.SEARCH" const val INTENT_SEARCH_QUERY = "query" const val INTENT_SEARCH_FILTER = "filter" + + private const val URL_HELP = "https://github.com/inorichi/tachiyomi/wiki" } } diff --git a/app/src/main/res/menu/menu_navigation.xml b/app/src/main/res/menu/menu_navigation.xml index 7703c6ef83..1ea7a65415 100644 --- a/app/src/main/res/menu/menu_navigation.xml +++ b/app/src/main/res/menu/menu_navigation.xml @@ -36,5 +36,10 @@ android:icon="@drawable/ic_settings_black_24dp" android:title="@string/label_settings" android:checkable="false" /> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 14ab046b10..78b2350f83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,6 +24,7 @@ Source migration Extensions Extension info + Help From 47f14e8555f518eae6a81fcffe6876f40e536547 Mon Sep 17 00:00:00 2001 From: Harsh Parekh Date: Sat, 25 May 2019 07:47:53 -0400 Subject: [PATCH 12/13] Long click to manage categories (#2045) --- .../ui/manga/info/MangaInfoController.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index b3bb48289a..0a3a409733 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -88,6 +88,9 @@ class MangaInfoController : NucleusController(), // Set onclickListener to toggle favorite when FAB clicked. fab_favorite.clicks().subscribeUntilDestroy { onFabClick() } + // Set onLongClickListener to manage categories when FAB is clicked. + fab_favorite.longClicks().subscribeUntilDestroy{ onFabLongClick() } + // Set SwipeRefresh to refresh manga data. swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() } @@ -400,6 +403,33 @@ class MangaInfoController : NucleusController(), } } + /** + * Called when the fab is long clicked. + */ + private fun onFabLongClick() { + val manga = presenter.manga + if (!manga.favorite) { + toggleFavorite() + activity?.toast(activity?.getString(R.string.manga_added_library)) + } + val categories = presenter.getCategories() + val defaultCategory = categories.find { it.id == preferences.defaultCategory() } + when { + defaultCategory != null -> presenter.moveMangaToCategory(manga, defaultCategory) + categories.size <= 1 -> // default or the one from the user + presenter.moveMangaToCategory(manga, categories.firstOrNull()) + else -> { + val ids = presenter.getMangaCategoryIds(manga) + val preselected = ids.mapNotNull { id -> + categories.indexOfFirst { it.id == id }.takeIf { it != -1 } + }.toTypedArray() + + ChangeMangaCategoriesDialog(this, listOf(manga), categories, preselected) + .showDialog(router) + } + } + } + override fun updateCategoriesForMangas(mangas: List, categories: List) { val manga = mangas.firstOrNull() ?: return presenter.moveMangaToCategories(manga, categories) From 8ebda219c4b45a24c83e7c40c8ab218ec2fd07f2 Mon Sep 17 00:00:00 2001 From: Harsh Parekh Date: Sun, 26 May 2019 05:37:47 -0400 Subject: [PATCH 13/13] Fix the category selection bug (#2052) Fixes #2051 --- .../ui/manga/info/MangaInfoController.kt | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt index 0a3a409733..5340627072 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt @@ -413,20 +413,17 @@ class MangaInfoController : NucleusController(), activity?.toast(activity?.getString(R.string.manga_added_library)) } val categories = presenter.getCategories() - val defaultCategory = categories.find { it.id == preferences.defaultCategory() } - when { - defaultCategory != null -> presenter.moveMangaToCategory(manga, defaultCategory) - categories.size <= 1 -> // default or the one from the user - presenter.moveMangaToCategory(manga, categories.firstOrNull()) - else -> { - val ids = presenter.getMangaCategoryIds(manga) - val preselected = ids.mapNotNull { id -> - categories.indexOfFirst { it.id == id }.takeIf { it != -1 } - }.toTypedArray() + if (categories.size <= 1) { + // default or the one from the user then just add to favorite. + presenter.moveMangaToCategory(manga, categories.firstOrNull()) + } else { + val ids = presenter.getMangaCategoryIds(manga) + val preselected = ids.mapNotNull { id -> + categories.indexOfFirst { it.id == id }.takeIf { it != -1 } + }.toTypedArray() - ChangeMangaCategoriesDialog(this, listOf(manga), categories, preselected) - .showDialog(router) - } + ChangeMangaCategoriesDialog(this, listOf(manga), categories, preselected) + .showDialog(router) } }