diff --git a/.gitattributes b/.gitattributes index 7b9779ee53..1ca443da48 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,18 +4,16 @@ # Windows forced line-endings /.idea/* text eol=crlf +# Gradle wrapper +*.jar binary + +# Images *.webp binary *.png binary *.jpg binary *.jpeg binary *.gif binary *.ico binary -*.mov binary -*.mp4 binary -*.mp3 binary -*.flv binary -*.fla binary -*.swf binary *.gz binary *.zip binary *.7z binary @@ -23,7 +21,4 @@ *.eot binary *.woff binary *.pyc binary -*.pdf binary -*.ez binary -*.bz2 binary *.swp binary diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt index fde18a22d6..043d2653fe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt @@ -52,7 +52,7 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) { } } - override fun getLogo() = R.drawable.anilist + override fun getLogo() = R.drawable.tracker_anilist override fun getLogoColor() = Color.rgb(18, 25, 35) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt index 02e0b2efbb..d058a85f59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Avatar( - val large: String? = "", - val medium: String? = "", - val small: String? = "" -) \ No newline at end of file + val large: String? = "", + val medium: String? = "", + val small: String? = "" +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 0d93e1fb73..147dde6de6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -13,132 +13,132 @@ import uy.kohesive.injekt.injectLazy class Bangumi(private val context: Context, id: Int) : TrackService(id) { - override fun getScoreList(): List { - return IntRange(0, 10).map(Int::toString) - } + override val name = "Bangumi" - override fun displayScore(track: Track): String { - return track.score.toInt().toString() - } + private val gson: Gson by injectLazy() - override fun add(track: Track): Observable { - return api.addLibManga(track) - } + private val interceptor by lazy { BangumiInterceptor(this, gson) } - override fun update(track: Track): Observable { - if (track.total_chapters != 0 && track.last_chapter_read == track.total_chapters) { - track.status = COMPLETED + private val api by lazy { BangumiApi(client, interceptor) } + + override fun getScoreList(): List { + return IntRange(0, 10).map(Int::toString) } - return api.updateLibManga(track) - } - override fun bind(track: Track): Observable { - return api.statusLibManga(track) - .flatMap { - api.findLibManga(track).flatMap { remoteTrack -> - if (remoteTrack != null && it != null) { - track.copyPersonalFrom(remoteTrack) - track.library_id = remoteTrack.library_id - track.status = remoteTrack.status - track.last_chapter_read = remoteTrack.last_chapter_read - update(track) - } else { - // Set default fields if it's not found in the list - track.score = DEFAULT_SCORE.toFloat() - track.status = DEFAULT_STATUS - add(track) - update(track) - } + override fun displayScore(track: Track): String { + return track.score.toInt().toString() + } + + override fun add(track: Track): Observable { + return api.addLibManga(track) + } + + override fun update(track: Track): Observable { + if (track.total_chapters != 0 && track.last_chapter_read == track.total_chapters) { + track.status = COMPLETED } - } - } + return api.updateLibManga(track) + } - override fun search(query: String): Observable> { - return api.search(query) - } + override fun bind(track: Track): Observable { + return api.statusLibManga(track) + .flatMap { + api.findLibManga(track).flatMap { remoteTrack -> + if (remoteTrack != null && it != null) { + track.copyPersonalFrom(remoteTrack) + track.library_id = remoteTrack.library_id + track.status = remoteTrack.status + track.last_chapter_read = remoteTrack.last_chapter_read + refresh(track) + } else { + // Set default fields if it's not found in the list + track.score = DEFAULT_SCORE.toFloat() + track.status = DEFAULT_STATUS + add(track) + update(track) + } + } + } + } - override fun refresh(track: Track): Observable { - return api.statusLibManga(track) - .flatMap { - track.copyPersonalFrom(it!!) - api.findLibManga(track) - .map { remoteTrack -> - if (remoteTrack != null) { - track.total_chapters = remoteTrack.total_chapters - track.status = remoteTrack.status + override fun search(query: String): Observable> { + return api.search(query) + } + + override fun refresh(track: Track): Observable { + return api.statusLibManga(track) + .flatMap { + track.copyPersonalFrom(it!!) + api.findLibManga(track) + .map { remoteTrack -> + if (remoteTrack != null) { + track.total_chapters = remoteTrack.total_chapters + track.status = remoteTrack.status + } + track + } + } + } + + override fun getLogo() = R.drawable.tracker_bangumi + + override fun getLogoColor() = Color.rgb(0xF0, 0x91, 0x99) + + override fun getStatusList(): List { + return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLANNING) + } + + override fun getStatus(status: Int): String = with(context) { + when (status) { + READING -> getString(R.string.reading) + COMPLETED -> getString(R.string.completed) + ON_HOLD -> getString(R.string.on_hold) + DROPPED -> getString(R.string.dropped) + PLANNING -> getString(R.string.plan_to_read) + else -> "" + } + } + + override fun login(username: String, password: String) = login(password) + + fun login(code: String): Completable { + return api.accessToken(code).map { oauth: OAuth? -> + interceptor.newAuth(oauth) + if (oauth != null) { + saveCredentials(oauth.user_id.toString(), oauth.access_token) } - track - } - } - } - - companion object { - const val READING = 3 - const val COMPLETED = 2 - const val ON_HOLD = 4 - const val DROPPED = 5 - const val PLANNING = 1 - - const val DEFAULT_STATUS = READING - const val DEFAULT_SCORE = 0 - } - - override val name = "Bangumi" - - private val gson: Gson by injectLazy() - - private val interceptor by lazy { BangumiInterceptor(this, gson) } - - private val api by lazy { BangumiApi(client, interceptor) } - - override fun getLogo() = R.drawable.bangumi - - override fun getLogoColor() = Color.rgb(0xF0, 0x91, 0x99) - - override fun getStatusList(): List { - return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLANNING) - } - - override fun getStatus(status: Int): String = with(context) { - when (status) { - READING -> getString(R.string.reading) - COMPLETED -> getString(R.string.completed) - ON_HOLD -> getString(R.string.on_hold) - DROPPED -> getString(R.string.dropped) - PLANNING -> getString(R.string.plan_to_read) - else -> "" + }.doOnError { + logout() + }.toCompletable() } - } - override fun login(username: String, password: String) = login(password) - - fun login(code: String): Completable { - return api.accessToken(code).map { oauth: OAuth? -> - interceptor.newAuth(oauth) - if (oauth != null) { - saveCredentials(oauth.user_id.toString(), oauth.access_token) - } - }.doOnError { - logout() - }.toCompletable() - } - - fun saveToken(oauth: OAuth?) { - val json = gson.toJson(oauth) - preferences.trackToken(this).set(json) - } - - fun restoreToken(): OAuth? { - return try { - gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) - } catch (e: Exception) { - null + fun saveToken(oauth: OAuth?) { + val json = gson.toJson(oauth) + preferences.trackToken(this).set(json) } - } - override fun logout() { - super.logout() - preferences.trackToken(this).set(null) - interceptor.newAuth(null) - } + fun restoreToken(): OAuth? { + return try { + gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) + } catch (e: Exception) { + null + } + } + + override fun logout() { + super.logout() + preferences.trackToken(this).set(null) + interceptor.newAuth(null) + } + + companion object { + const val READING = 3 + const val COMPLETED = 2 + const val ON_HOLD = 4 + const val DROPPED = 5 + const val PLANNING = 1 + + const val DEFAULT_STATUS = READING + const val DEFAULT_SCORE = 0 + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt index 7180156aa3..3b356f6533 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt @@ -21,191 +21,191 @@ import java.net.URLEncoder class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) { - private val gson: Gson by injectLazy() - private val parser = JsonParser() - private val authClient = client.newBuilder().addInterceptor(interceptor).build() + private val gson: Gson by injectLazy() + private val parser = JsonParser() + private val authClient = client.newBuilder().addInterceptor(interceptor).build() - fun addLibManga(track: Track): Observable { - val body = FormBody.Builder() - .add("rating", track.score.toInt().toString()) - .add("status", track.toBangumiStatus()) - .build() - val request = Request.Builder() - .url("$apiUrl/collection/${track.media_id}/update") - .post(body) - .build() - return authClient.newCall(request) - .asObservableSuccess() - .map { - track - } - } + fun addLibManga(track: Track): Observable { + val body = FormBody.Builder() + .add("rating", track.score.toInt().toString()) + .add("status", track.toBangumiStatus()) + .build() + val request = Request.Builder() + .url("$apiUrl/collection/${track.media_id}/update") + .post(body) + .build() + return authClient.newCall(request) + .asObservableSuccess() + .map { + track + } + } - fun updateLibManga(track: Track): Observable { - // chapter update - val body = FormBody.Builder() - .add("watched_eps", track.last_chapter_read.toString()) - .build() - val request = Request.Builder() - .url("$apiUrl/subject/${track.media_id}/update/watched_eps") - .post(body) - .build() + fun updateLibManga(track: Track): Observable { + // chapter update + val body = FormBody.Builder() + .add("watched_eps", track.last_chapter_read.toString()) + .build() + val request = Request.Builder() + .url("$apiUrl/subject/${track.media_id}/update/watched_eps") + .post(body) + .build() - // read status update - val sbody = FormBody.Builder() - .add("status", track.toBangumiStatus()) - .build() - val srequest = Request.Builder() - .url("$apiUrl/collection/${track.media_id}/update") - .post(sbody) - .build() - return authClient.newCall(request) - .asObservableSuccess() - .map { - track - }.flatMap { - authClient.newCall(srequest) - .asObservableSuccess() - .map { - track - } - } - } + // read status update + val sbody = FormBody.Builder() + .add("status", track.toBangumiStatus()) + .build() + val srequest = Request.Builder() + .url("$apiUrl/collection/${track.media_id}/update") + .post(sbody) + .build() + return authClient.newCall(srequest) + .asObservableSuccess() + .map { + track + }.flatMap { + authClient.newCall(request) + .asObservableSuccess() + .map { + track + } + } + } - fun search(search: String): Observable> { - val url = Uri.parse( - "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}").buildUpon() - .appendQueryParameter("max_results", "20") - .build() - val request = Request.Builder() - .url(url.toString()) - .get() - .build() - return authClient.newCall(request) - .asObservableSuccess() - .map { netResponse -> - var responseBody = netResponse.body?.string().orEmpty() - if (responseBody.isEmpty()) { - throw Exception("Null Response") + fun search(search: String): Observable> { + val url = Uri.parse( + "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}").buildUpon() + .appendQueryParameter("max_results", "20") + .build() + val request = Request.Builder() + .url(url.toString()) + .get() + .build() + return authClient.newCall(request) + .asObservableSuccess() + .map { netResponse -> + var responseBody = netResponse.body?.string().orEmpty() + if (responseBody.isEmpty()) { + throw Exception("Null Response") + } + if (responseBody.contains("\"code\":404")) { + responseBody = "{\"results\":0,\"list\":[]}" + } + val response = parser.parse(responseBody).obj["list"]?.array + response?.filter { it.obj["type"].asInt == 1 }?.map { jsonToSearch(it.obj) } + } + + } + + private fun jsonToSearch(obj: JsonObject): TrackSearch { + return TrackSearch.create(TrackManager.BANGUMI).apply { + media_id = obj["id"].asInt + title = obj["name_cn"].asString + cover_url = obj["images"].obj["common"].asString + summary = obj["name"].asString + tracking_url = obj["url"].asString } - if(responseBody.contains("\"code\":404")){ - responseBody = "{\"results\":0,\"list\":[]}" + } + + private fun jsonToTrack(mangas: JsonObject): Track { + return Track.create(TrackManager.BANGUMI).apply { + title = mangas["name"].asString + media_id = mangas["id"].asInt + score = if (mangas["rating"] != null) + (if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f) + else 0f + status = Bangumi.DEFAULT_STATUS + tracking_url = mangas["url"].asString } - val response = parser.parse(responseBody).obj["list"]?.array - response?.filter { it.obj["type"].asInt == 1 }?.map { jsonToSearch(it.obj) } - } - - } - - private fun jsonToSearch(obj: JsonObject): TrackSearch { - return TrackSearch.create(TrackManager.BANGUMI).apply { - media_id = obj["id"].asInt - title = obj["name_cn"].asString - cover_url = obj["images"].obj["common"].asString - summary = obj["name"].asString - tracking_url = obj["url"].asString - } - } - - private fun jsonToTrack(mangas: JsonObject): Track { - return Track.create(TrackManager.BANGUMI).apply { - title = mangas["name"].asString - media_id = mangas["id"].asInt - score = if (mangas["rating"] != null) - (if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f) - else 0f - status = Bangumi.DEFAULT_STATUS - tracking_url = mangas["url"].asString - } - } - - fun findLibManga(track: Track): Observable { - val urlMangas = "$apiUrl/subject/${track.media_id}" - val requestMangas = Request.Builder() - .url(urlMangas) - .get() - .build() - - return authClient.newCall(requestMangas) - .asObservableSuccess() - .map { netResponse -> - // get comic info - val responseBody = netResponse.body?.string().orEmpty() - jsonToTrack(parser.parse(responseBody).obj) - } - } - - fun statusLibManga(track: Track): Observable { - val urlUserRead = "$apiUrl/collection/${track.media_id}" - val requestUserRead = Request.Builder() - .url(urlUserRead) - .cacheControl(CacheControl.FORCE_NETWORK) - .get() - .build() - - // todo get user readed chapter here - return authClient.newCall(requestUserRead) - .asObservableSuccess() - .map { netResponse -> - val resp = netResponse.body?.string() - val coll = gson.fromJson(resp, Collection::class.java) - track.status = coll.status?.id!! - track.last_chapter_read = coll.ep_status!! - track - } - } - - fun accessToken(code: String): Observable { - return client.newCall(accessTokenRequest(code)).asObservableSuccess().map { netResponse -> - val responseBody = netResponse.body?.string().orEmpty() - if (responseBody.isEmpty()) { - throw Exception("Null Response") - } - gson.fromJson(responseBody, OAuth::class.java) - } - } - - private fun accessTokenRequest(code: String) = POST(oauthUrl, - body = FormBody.Builder() - .add("grant_type", "authorization_code") - .add("client_id", clientId) - .add("client_secret", clientSecret) - .add("code", code) - .add("redirect_uri", redirectUrl) - .build() - ) - - companion object { - private const val clientId = "bgm10555cda0762e80ca" - private const val clientSecret = "8fff394a8627b4c388cbf349ec865775" - - private const val baseUrl = "https://bangumi.org" - private const val apiUrl = "https://api.bgm.tv" - private const val oauthUrl = "https://bgm.tv/oauth/access_token" - private const val loginUrl = "https://bgm.tv/oauth/authorize" - - private const val redirectUrl = "tachiyomi://bangumi-auth" - private const val baseMangaUrl = "$apiUrl/mangas" - - fun mangaUrl(remoteId: Int): String { - return "$baseMangaUrl/$remoteId" } - fun authUrl() = - Uri.parse(loginUrl).buildUpon() - .appendQueryParameter("client_id", clientId) - .appendQueryParameter("response_type", "code") - .appendQueryParameter("redirect_uri", redirectUrl) - .build() + fun findLibManga(track: Track): Observable { + val urlMangas = "$apiUrl/subject/${track.media_id}" + val requestMangas = Request.Builder() + .url(urlMangas) + .get() + .build() - fun refreshTokenRequest(token: String) = POST(oauthUrl, - body = FormBody.Builder() - .add("grant_type", "refresh_token") - .add("client_id", clientId) - .add("client_secret", clientSecret) - .add("refresh_token", token) - .add("redirect_uri", redirectUrl) - .build()) - } + return authClient.newCall(requestMangas) + .asObservableSuccess() + .map { netResponse -> + // get comic info + val responseBody = netResponse.body?.string().orEmpty() + jsonToTrack(parser.parse(responseBody).obj) + } + } + + fun statusLibManga(track: Track): Observable { + val urlUserRead = "$apiUrl/collection/${track.media_id}" + val requestUserRead = Request.Builder() + .url(urlUserRead) + .cacheControl(CacheControl.FORCE_NETWORK) + .get() + .build() + + // todo get user readed chapter here + return authClient.newCall(requestUserRead) + .asObservableSuccess() + .map { netResponse -> + val resp = netResponse.body?.string() + val coll = gson.fromJson(resp, Collection::class.java) + track.status = coll.status?.id!! + track.last_chapter_read = coll.ep_status!! + track + } + } + + fun accessToken(code: String): Observable { + return client.newCall(accessTokenRequest(code)).asObservableSuccess().map { netResponse -> + val responseBody = netResponse.body?.string().orEmpty() + if (responseBody.isEmpty()) { + throw Exception("Null Response") + } + gson.fromJson(responseBody, OAuth::class.java) + } + } + + private fun accessTokenRequest(code: String) = POST(oauthUrl, + body = FormBody.Builder() + .add("grant_type", "authorization_code") + .add("client_id", clientId) + .add("client_secret", clientSecret) + .add("code", code) + .add("redirect_uri", redirectUrl) + .build() + ) + + companion object { + private const val clientId = "bgm10555cda0762e80ca" + private const val clientSecret = "8fff394a8627b4c388cbf349ec865775" + + private const val baseUrl = "https://bangumi.org" + private const val apiUrl = "https://api.bgm.tv" + private const val oauthUrl = "https://bgm.tv/oauth/access_token" + private const val loginUrl = "https://bgm.tv/oauth/authorize" + + private const val redirectUrl = "tachiyomi://bangumi-auth" + private const val baseMangaUrl = "$apiUrl/mangas" + + fun mangaUrl(remoteId: Int): String { + return "$baseMangaUrl/$remoteId" + } + + fun authUrl() = + Uri.parse(loginUrl).buildUpon() + .appendQueryParameter("client_id", clientId) + .appendQueryParameter("response_type", "code") + .appendQueryParameter("redirect_uri", redirectUrl) + .build() + + fun refreshTokenRequest(token: String) = POST(oauthUrl, + body = FormBody.Builder() + .add("grant_type", "refresh_token") + .add("client_id", clientId) + .add("client_secret", clientSecret) + .add("refresh_token", token) + .add("redirect_uri", redirectUrl) + .build()) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt index d51c6d7862..add168201e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt @@ -7,55 +7,55 @@ import okhttp3.Response class BangumiInterceptor(val bangumi: Bangumi, val gson: Gson) : Interceptor { - /** - * OAuth object used for authenticated requests. - */ - private var oauth: OAuth? = bangumi.restoreToken() + /** + * OAuth object used for authenticated requests. + */ + private var oauth: OAuth? = bangumi.restoreToken() - fun addTocken(tocken: String, oidFormBody: FormBody): FormBody { - val newFormBody = FormBody.Builder() - for (i in 0 until oidFormBody.size) { - newFormBody.add(oidFormBody.name(i), oidFormBody.value(i)) - } - newFormBody.add("access_token", tocken) - return newFormBody.build() - } - - override fun intercept(chain: Interceptor.Chain): Response { - val originalRequest = chain.request() - - val currAuth = oauth ?: throw Exception("Not authenticated with Bangumi") - - if (currAuth.isExpired()) { - val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!)) - if (response.isSuccessful) { - newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java)) - } else { - response.close() - } + fun addTocken(tocken: String, oidFormBody: FormBody): FormBody { + val newFormBody = FormBody.Builder() + for (i in 0 until oidFormBody.size) { + newFormBody.add(oidFormBody.name(i), oidFormBody.value(i)) + } + newFormBody.add("access_token", tocken) + return newFormBody.build() } - val authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder() - .header("User-Agent", "Tachiyomi") - .url(originalRequest.url.newBuilder() - .addQueryParameter("access_token", currAuth.access_token).build()) - .build() else originalRequest.newBuilder() - .post(addTocken(currAuth.access_token, originalRequest.body as FormBody)) - .header("User-Agent", "Tachiyomi") - .build() + override fun intercept(chain: Interceptor.Chain): Response { + val originalRequest = chain.request() - return chain.proceed(authRequest) - } + val currAuth = oauth ?: throw Exception("Not authenticated with Bangumi") - fun newAuth(oauth: OAuth?) { - this.oauth = if (oauth == null) null else OAuth( - oauth.access_token, - oauth.token_type, - System.currentTimeMillis() / 1000, - oauth.expires_in, - oauth.refresh_token, - this.oauth?.user_id) + if (currAuth.isExpired()) { + val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!)) + if (response.isSuccessful) { + newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java)) + } else { + response.close() + } + } - bangumi.saveToken(oauth) - } + val authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder() + .header("User-Agent", "Tachiyomi") + .url(originalRequest.url.newBuilder() + .addQueryParameter("access_token", currAuth.access_token).build()) + .build() else originalRequest.newBuilder() + .post(addTocken(currAuth.access_token, originalRequest.body as FormBody)) + .header("User-Agent", "Tachiyomi") + .build() + + return chain.proceed(authRequest) + } + + fun newAuth(oauth: OAuth?) { + this.oauth = if (oauth == null) null else OAuth( + oauth.access_token, + oauth.token_type, + System.currentTimeMillis() / 1000, + oauth.expires_in, + oauth.refresh_token, + this.oauth?.user_id) + + bangumi.saveToken(oauth) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt index 83b9ce3054..0b02f2b2ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt @@ -3,20 +3,20 @@ package eu.kanade.tachiyomi.data.track.bangumi import eu.kanade.tachiyomi.data.database.models.Track fun Track.toBangumiStatus() = when (status) { - Bangumi.READING -> "do" - Bangumi.COMPLETED -> "collect" - Bangumi.ON_HOLD -> "on_hold" - Bangumi.DROPPED -> "dropped" - Bangumi.PLANNING -> "wish" - else -> throw NotImplementedError("Unknown status") + Bangumi.READING -> "do" + Bangumi.COMPLETED -> "collect" + Bangumi.ON_HOLD -> "on_hold" + Bangumi.DROPPED -> "dropped" + Bangumi.PLANNING -> "wish" + else -> throw NotImplementedError("Unknown status") } fun toTrackStatus(status: String) = when (status) { - "do" -> Bangumi.READING - "collect" -> Bangumi.COMPLETED - "on_hold" -> Bangumi.ON_HOLD - "dropped" -> Bangumi.DROPPED - "wish" -> Bangumi.PLANNING + "do" -> Bangumi.READING + "collect" -> Bangumi.COMPLETED + "on_hold" -> Bangumi.ON_HOLD + "dropped" -> Bangumi.DROPPED + "wish" -> Bangumi.PLANNING - else -> throw Exception("Unknown status") + else -> throw Exception("Unknown status") } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt index 732676bf31..03143d19f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt @@ -1,13 +1,13 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Collection( - val `private`: Int? = 0, - val comment: String? = "", - val ep_status: Int? = 0, - val lasttouch: Int? = 0, - val rating: Int? = 0, - val status: Status? = Status(), - val tag: List? = listOf(), - val user: User? = User(), - val vol_status: Int? = 0 -) \ No newline at end of file + val `private`: Int? = 0, + val comment: String? = "", + val ep_status: Int? = 0, + val lasttouch: Int? = 0, + val rating: Int? = 0, + val status: Status? = Status(), + val tag: List? = listOf(), + val user: User? = User(), + val vol_status: Int? = 0 +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt index b46276d167..811d0fd459 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt @@ -1,16 +1,16 @@ package eu.kanade.tachiyomi.data.track.bangumi data class OAuth( - val access_token: String, - val token_type: String, - val created_at: Long, - val expires_in: Long, - val refresh_token: String?, - val user_id: Long? + val access_token: String, + val token_type: String, + val created_at: Long, + val expires_in: Long, + val refresh_token: String?, + val user_id: Long? ) { - // Access token refresh before expired - fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600) + // Access token refresh before expired + fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt index 78e22e882c..3d2ea3c14b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Status( - val id: Int? = 0, - val name: String? = "", - val type: String? = "" -) \ No newline at end of file + val id: Int? = 0, + val name: String? = "", + val type: String? = "" +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt index 808e4860a6..9e82f533e3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt @@ -1,11 +1,11 @@ package eu.kanade.tachiyomi.data.track.bangumi data class User( - val avatar: Avatar? = Avatar(), - val id: Int? = 0, - val nickname: String? = "", - val sign: String? = "", - val url: String? = "", - val usergroup: Int? = 0, - val username: String? = "" -) \ No newline at end of file + val avatar: Avatar? = Avatar(), + val id: Int? = 0, + val nickname: String? = "", + val sign: String? = "", + val url: String? = "", + val usergroup: Int? = 0, + val username: String? = "" +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt index 97741fd54e..a6f49c401e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt @@ -34,7 +34,7 @@ class Kitsu(private val context: Context, id: Int) : TrackService(id) { private val api by lazy { KitsuApi(client, interceptor) } override fun getLogo(): Int { - return R.drawable.kitsu + return R.drawable.tracker_kitsu } override fun getLogoColor(): Int { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt index 85a29193bd..db14187fc0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt @@ -35,7 +35,7 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) { override val name: String get() = "MyAnimeList" - override fun getLogo() = R.drawable.mal + override fun getLogo() = R.drawable.tracker_mal override fun getLogoColor() = Color.rgb(46, 81, 162) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index 4c818d5fce..00f7a517ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -2,7 +2,6 @@ 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 @@ -84,7 +83,7 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { private val api by lazy { ShikimoriApi(client, interceptor) } - override fun getLogo() = R.drawable.shikimori + override fun getLogo() = R.drawable.tracker_shikimori override fun getLogoColor() = Color.rgb(40, 40, 40) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt index f65bf39ba6..4e4d7feca2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt @@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.data.updater.Release /** * Release object. - * Contains information about the latest release from Github. + * Contains information about the latest release from GitHub. * * @param version version of latest release. * @param info log of latest release. diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt index 1831157860..052684bd03 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt @@ -10,7 +10,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get /** - * Used to connect with the Github API. + * Used to connect with the GitHub API. */ interface GithubService { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt index 8dfcb27a40..bfb3381fa0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt @@ -71,7 +71,7 @@ class ExtensionManager( private set(value) { field = value availableExtensionsRelay.call(value) - setUpdateFieldOfInstalledExtensions(value) + updatedInstalledExtensionsStatuses(value) } /** @@ -158,18 +158,25 @@ class ExtensionManager( * * @param availableExtensions The list of extensions given by the [api]. */ - private fun setUpdateFieldOfInstalledExtensions(availableExtensions: List) { + private fun updatedInstalledExtensionsStatuses(availableExtensions: List) { val mutInstalledExtensions = installedExtensions.toMutableList() var changed = false for ((index, installedExt) in mutInstalledExtensions.withIndex()) { val pkgName = installedExt.pkgName - val availableExt = availableExtensions.find { it.pkgName == pkgName } ?: continue + val availableExt = availableExtensions.find { it.pkgName == pkgName } - val hasUpdate = availableExt.versionCode > installedExt.versionCode - if (installedExt.hasUpdate != hasUpdate) { - mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate) - changed = true + if (availableExt == null) { + if (!installedExt.isObsolete) { + mutInstalledExtensions[index] = installedExt.copy(isObsolete = true) + changed = true + } + } else { + val hasUpdate = availableExt.versionCode > installedExt.versionCode + if (installedExt.hasUpdate != hasUpdate) { + mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate) + changed = true + } } } if (changed) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt index ef4c245684..f0a53690f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt @@ -16,7 +16,8 @@ sealed class Extension { override val versionCode: Int, val sources: List, override val lang: String, - val hasUpdate: Boolean = false) : Extension() + val hasUpdate: Boolean = false, + val isObsolete: Boolean = false) : Extension() data class Available(override val name: String, override val pkgName: String, diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt index 1630e723d7..b02c79ae1e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt @@ -1,6 +1,8 @@ package eu.kanade.tachiyomi.source import android.content.Context +import com.google.gson.Gson +import com.google.gson.JsonObject import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList @@ -21,6 +23,7 @@ import java.io.File import java.io.FileInputStream import java.io.InputStream import java.util.Locale +import java.util.Scanner import java.util.concurrent.TimeUnit import java.util.zip.ZipEntry import java.util.zip.ZipFile @@ -117,8 +120,6 @@ class LocalSource(private val context: Context) : CatalogueSource { } } } - - initialized = true } } return Observable.just(MangasPage(mangas, false)) @@ -126,7 +127,26 @@ class LocalSource(private val context: Context) : CatalogueSource { override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS) - override fun fetchMangaDetails(manga: SManga) = Observable.just(manga) + override fun fetchMangaDetails(manga: SManga): Observable { + getBaseDirectories(context) + .mapNotNull { File(it, manga.url).listFiles()?.toList() } + .flatten() + .filter { it.extension.equals("json") } + .firstOrNull() + ?.apply { + val json = Gson().fromJson(Scanner(this).useDelimiter("\\Z").next(), JsonObject::class.java) + manga.title = json["title"]?.asString ?: manga.title + manga.author = json["author"]?.asString ?: manga.author + manga.artist = json["artist"]?.asString ?: manga.artist + manga.description = json["description"]?.asString ?: manga.description + manga.genre = json["genre"]?.asJsonArray + ?.map { it.asString } + ?.joinToString(", ") + ?: manga.genre + manga.status = json["status"]?.asInt ?: manga.status + } + return Observable.just(manga) + } override fun fetchChapterList(manga: SManga): Observable> { val chapters = getBaseDirectories(context) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt index 292bf2e326..860c4d5908 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt @@ -89,15 +89,16 @@ abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateContr * This method should be removed when fixed upstream. * Issue link: https://issuetracker.google.com/issues/37657375 */ - fun MenuItem.fixExpand() { + fun MenuItem.fixExpand(onExpand: ((MenuItem) -> Boolean)? = null, onCollapse: ((MenuItem) -> Boolean)? = null) { setOnActionExpandListener(object : MenuItem.OnActionExpandListener { override fun onMenuItemActionExpand(item: MenuItem): Boolean { - return true + return onExpand?.invoke(item) ?: true } override fun onMenuItemActionCollapse(item: MenuItem): Boolean { activity?.invalidateOptionsMenu() - return true + + return onCollapse?.invoke(item) ?: true } }) } 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 c0e92b17ad..014e8bc428 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 @@ -53,7 +53,6 @@ import kotlinx.android.synthetic.main.main_activity.* import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers -import rx.subscriptions.Subscriptions import timber.log.Timber import uy.kohesive.injekt.injectLazy import java.util.concurrent.TimeUnit @@ -274,6 +273,7 @@ open class BrowseCatalogueController(bundle: Bundle) : val searchEventsObservable = searchView.queryTextChangeEvents() .skip(1) + .filter { router.backstack.lastOrNull()?.controller() == this@BrowseCatalogueController } .share() val writingObservable = searchEventsObservable .filter { !it.isSubmitted } @@ -284,11 +284,12 @@ open class BrowseCatalogueController(bundle: Bundle) : searchViewSubscription?.unsubscribe() searchViewSubscription = Observable.merge(writingObservable, submitObservable) .map { it.queryText().toString() } - .distinctUntilChanged() .subscribeUntilDestroy { searchWithQuery(it) } - untilDestroySubscriptions.add( - Subscriptions.create { if (isActionViewExpanded) collapseActionView() }) + fixExpand(onCollapse = { + searchWithQuery("") + true + }) } // Setup filters button @@ -356,11 +357,6 @@ open class BrowseCatalogueController(bundle: Bundle) : if (presenter.query == newQuery) return - // FIXME dirty fix to restore the toolbar buttons after closing search mode. - if (newQuery == "") { - activity?.invalidateOptionsMenu() - } - showProgressBar() adapter?.clear() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt index f1283a8e24..862f42add2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt @@ -78,6 +78,10 @@ class ExtensionDetailsController(bundle: Bundle? = null) : presenter.uninstallExtension() } + if (extension.isObsolete) { + extension_obsolete.visibility = View.VISIBLE + } + val themedContext by lazy { getPreferenceThemeContext() } val manager = PreferenceManager(themedContext) manager.preferenceDataStore = EmptyPreferenceDataStore() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt new file mode 100644 index 0000000000..7c2be136f3 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt @@ -0,0 +1,52 @@ +package eu.kanade.tachiyomi.ui.extension + +import androidx.preference.PreferenceScreen +import androidx.preference.SwitchPreference +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.extension.ExtensionManager +import eu.kanade.tachiyomi.ui.setting.SettingsController +import eu.kanade.tachiyomi.ui.setting.onChange +import eu.kanade.tachiyomi.ui.setting.titleRes +import eu.kanade.tachiyomi.util.LocaleHelper +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +class ExtensionFilterController: SettingsController() { + + override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) { + titleRes = R.string.action_filter + + val activeLangs = preferences.enabledLanguages().getOrDefault() + + val availableLangs = + Injekt.get().availableExtensions.groupBy { + it.lang + }.keys.minus("all").partition { + it in activeLangs + }.let { + it.first + it.second + } + + availableLangs.forEach { + SwitchPreference(context).apply { + preferenceScreen.addPreference(this) + title = LocaleHelper.getDisplayName(it, context) + isPersistent = false + isChecked = it in activeLangs + + onChange { newValue -> + val checked = newValue as Boolean + val currentActiveLangs = preferences.enabledLanguages().getOrDefault() + + if (checked) { + preferences.enabledLanguages().set(currentActiveLangs + it) + } else { + preferences.enabledLanguages().set(currentActiveLangs - it) + } + true + } + } + } + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt index bcf6b3a131..a1425da46b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt @@ -1,6 +1,8 @@ package eu.kanade.tachiyomi.ui.extension import android.view.View +import androidx.core.content.ContextCompat +import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.extension.model.Extension @@ -52,11 +54,15 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) : bindButton(item) } + @Suppress("ResourceType") fun bindButton(item: ExtensionItem) = with(ext_button) { isEnabled = true isClickable = true isActivated = false + background = VectorDrawableCompat.create(resources!!, R.drawable.button_bg_transparent, null) + setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_transparent)) + val extension = item.extension val installStep = item.installStep @@ -73,11 +79,21 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) : isClickable = false } } else if (extension is Extension.Installed) { - if (extension.hasUpdate) { - isActivated = true - setText(R.string.ext_update) - } else { - setText(R.string.ext_details) + when { + extension.hasUpdate -> { + isActivated = true + setText(R.string.ext_update) + } + extension.isObsolete -> { + // Red outline + background = VectorDrawableCompat.create(resources, R.drawable.button_bg_error, null) + setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_error)) + + setText(R.string.ext_obsolete) + } + else -> { + setText(R.string.ext_details) + } } } else if (extension is Extension.Untrusted) { setText(R.string.ext_trust) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt index 3dd819bfb6..8b576bacab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt @@ -62,7 +62,7 @@ open class ExtensionPresenter( val items = mutableListOf() - val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { it.pkgName })) + val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { !it.isObsolete }, { it.pkgName })) val untrustedSorted = untrusted.sortedBy { it.pkgName } val availableSorted = available // Filter out already installed extensions and disabled languages diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index bc35f6a1ad..dd5524ce85 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -1,13 +1,13 @@ package eu.kanade.tachiyomi.ui.library import android.content.Context -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.widget.FrameLayout +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.SelectableAdapter import eu.kanade.tachiyomi.R diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index b9754fea84..da476e4f99 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -465,7 +465,6 @@ class ChaptersController() : NucleusController(), } } - private fun showDeleteChaptersConfirmationDialog() { DeleteChaptersDialog(this).showDialog(router) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt index 539d1c03ed..451fb3518b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt @@ -117,10 +117,11 @@ class SettingsLibraryController : SettingsController() { selectedCategories.joinToString { it.name } } } - intListPreference{ + intListPreference { key = Keys.libraryUpdatePrioritization titleRes = R.string.pref_library_update_prioritization - // The following arrays are to be lined up with the list rankingScheme in: + + // The following array lines up with the list rankingScheme in: // ../../data/library/LibraryUpdateRanker.kt entriesRes = arrayOf( R.string.action_sort_alpha, @@ -138,14 +139,13 @@ class SettingsLibraryController : SettingsController() { titleRes = R.string.default_category val categories = listOf(Category.createDefault()) + dbCategories - - val selectedCategory = categories.find { it.id == preferences.defaultCategory() } entries = arrayOf(context.getString(R.string.default_category_summary)) + categories.map { it.name }.toTypedArray() entryValues = arrayOf("-1") + categories.map { it.id.toString() }.toTypedArray() defaultValue = "-1" - summary = selectedCategory?.name ?: context.getString(R.string.default_category_summary) + val selectedCategory = categories.find { it.id == preferences.defaultCategory() } + summary = selectedCategory?.name ?: context.getString(R.string.default_category_summary) onChange { newValue -> summary = categories.find { it.id == (newValue as String).toInt() diff --git a/app/src/main/res/anim/fab_hide_to_bottom.xml b/app/src/main/res/anim/fab_hide_to_bottom.xml deleted file mode 100644 index b5f8d63bd2..0000000000 --- a/app/src/main/res/anim/fab_hide_to_bottom.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/anim/fab_show_from_bottom.xml b/app/src/main/res/anim/fab_show_from_bottom.xml deleted file mode 100644 index eea12e8c42..0000000000 --- a/app/src/main/res/anim/fab_show_from_bottom.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/drawable-xxxhdpi/anilist.webp b/app/src/main/res/drawable-xxxhdpi/tracker_anilist.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/anilist.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_anilist.webp diff --git a/app/src/main/res/drawable-xxxhdpi/bangumi.webp b/app/src/main/res/drawable-xxxhdpi/tracker_bangumi.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/bangumi.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_bangumi.webp diff --git a/app/src/main/res/drawable-xxxhdpi/kitsu.webp b/app/src/main/res/drawable-xxxhdpi/tracker_kitsu.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/kitsu.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_kitsu.webp diff --git a/app/src/main/res/drawable-xxxhdpi/mal.webp b/app/src/main/res/drawable-xxxhdpi/tracker_mal.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/mal.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_mal.webp diff --git a/app/src/main/res/drawable-xxxhdpi/shikimori.webp b/app/src/main/res/drawable-xxxhdpi/tracker_shikimori.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/shikimori.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_shikimori.webp diff --git a/app/src/main/res/drawable/button_bg_error.xml b/app/src/main/res/drawable/button_bg_error.xml new file mode 100644 index 0000000000..3edb3611bb --- /dev/null +++ b/app/src/main/res/drawable/button_bg_error.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/extension_detail_controller.xml b/app/src/main/res/layout/extension_detail_controller.xml index d3c4757383..6d00d114cf 100644 --- a/app/src/main/res/layout/extension_detail_controller.xml +++ b/app/src/main/res/layout/extension_detail_controller.xml @@ -60,6 +60,22 @@ app:layout_constraintEnd_toEndOf="parent" tools:text="eu.kanade.tachiyomi.extension.en.myext"/> + +