Running kotlinter

This commit is contained in:
Jays2Kings 2021-03-25 14:58:46 -04:00
parent 7914b26488
commit fccd3a0ddb
145 changed files with 678 additions and 668 deletions

View File

@ -25,7 +25,6 @@ import uy.kohesive.injekt.api.get
class AppModule(val app: Application) : InjektModule {
override fun InjektRegistrar.registerInjectables() {
addSingleton(app)
addSingletonFactory { PreferencesHelper(app) }

View File

@ -70,8 +70,9 @@ object Migrations {
}
}
}
if (oldVersion < 54)
if (oldVersion < 54) {
DownloadProvider(context).renameChapters()
}
if (oldVersion < 62) {
LibraryPresenter.updateDB()
// Restore jobs after migrating from Evernote's job scheduler to WorkManager.

View File

@ -79,8 +79,9 @@ class ChapterCache(private val context: Context) {
*/
fun removeFileFromCache(file: String): Boolean {
// Make sure we don't delete the journal file (keeps track of cache).
if (file == "journal" || file.startsWith("journal."))
if (file == "journal" || file.startsWith("journal.")) {
return false
}
try {
// Remove the extension from the file to get the key of the cache

View File

@ -41,9 +41,9 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
put(COL_NAME, obj.name)
put(COL_ORDER, obj.order)
put(COL_FLAGS, obj.flags)
if (obj.mangaSort != null)
if (obj.mangaSort != null) {
put(COL_MANGA_ORDER, obj.mangaSort.toString())
else {
} else {
val orderString = obj.mangaOrder.joinToString("/")
put(COL_MANGA_ORDER, orderString)
}

View File

@ -105,17 +105,17 @@ interface Manga : SManga {
{ tag ->
tag == "long strip" || tag == "manhwa" || tag.contains("webtoon")
} == true || isWebtoonSource(sourceName)
)
) {
ReaderActivity.WEBTOON
else if (currentTags?.any
} else if (currentTags?.any
{ tag ->
tag == "chinese" || tag == "manhua" ||
tag.startsWith("english") || tag == "comic"
} == true || (isComicSource(sourceName) && !sourceName.contains("tapas", true)) ||
sourceName.contains("manhua", true)
)
) {
ReaderActivity.LEFT_TO_RIGHT
else 0
} else 0
}
fun isMangaTag(tag: String): Boolean {
@ -127,7 +127,7 @@ interface Manga : SManga {
}
fun isManhwaTag(tag: String): Boolean {
return tag in listOf("long strip", "manhwa", "манхва", "kr") || tag.startsWith("korean")
return tag in listOf("long strip", "manhwa", "манхва", "kr") || tag.startsWith("korean")
}
fun isComicTag(tag: String): Boolean {

View File

@ -90,7 +90,6 @@ class DownloadCache(
checkRenew()
if (forceCheckFolder) {
val source = sourceManager.get(manga.source) ?: return 0
val mangaDir = provider.findMangaDir(manga, source)
@ -173,7 +172,6 @@ class DownloadCache(
*/
@Synchronized
fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
val id = manga.id ?: return
val files = mangaFiles[id]
if (files == null) {

View File

@ -110,10 +110,11 @@ class DownloadManager(val context: Context) {
queue.add(0, download)
reorderQueue(queue)
if (isPaused()) {
if (DownloadService.isRunning(context))
if (DownloadService.isRunning(context)) {
downloader.start()
else
} else {
DownloadService.start(context)
}
}
}

View File

@ -55,8 +55,9 @@ internal class DownloadNotifier(private val context: Context) {
* Clear old actions if they exist.
*/
private fun clearActions() = with(notification) {
if (!mActions.isEmpty())
if (!mActions.isEmpty()) {
mActions.clear()
}
}
/**

View File

@ -201,10 +201,11 @@ class DownloadService : Service() {
*/
private fun listenDownloaderState() {
subscriptions += downloadManager.runningRelay.subscribe { running ->
if (running)
if (running) {
wakeLock.acquireIfNeeded()
else
} else {
wakeLock.releaseIfNeeded()
}
}
}

View File

@ -469,7 +469,6 @@ class Downloader(
tmpDir: UniFile,
dirname: String
) {
// Ensure that the chapter folder has all the images.
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }

View File

@ -11,11 +11,14 @@ class Download(val source: HttpSource, val manga: Manga, val chapter: Chapter) {
var pages: List<Page>? = null
@Volatile @Transient var totalProgress: Int = 0
@Volatile @Transient
var totalProgress: Int = 0
@Volatile @Transient var downloadedImages: Int = 0
@Volatile @Transient
var downloadedImages: Int = 0
@Volatile @Transient var status: Int = 0
@Volatile @Transient
var status: Int = 0
set(status) {
field = status
statusSubject?.onNext(this)

View File

@ -37,8 +37,9 @@ class DownloadQueue(
store.remove(download)
download.setStatusSubject(null)
download.setStatusCallback(null)
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE)
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
download.status = Download.NOT_DOWNLOADED
}
downloadListeners.forEach { it.updateDownload(download) }
if (removed) {
updatedRelay.call(Unit)
@ -65,8 +66,9 @@ class DownloadQueue(
queue.forEach { download ->
download.setStatusSubject(null)
download.setStatusCallback(null)
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE)
if (download.status == Download.DOWNLOADING || download.status == Download.QUEUE) {
download.status = Download.NOT_DOWNLOADED
}
downloadListeners.forEach { it.updateDownload(download) }
}
queue.clear()
@ -85,11 +87,12 @@ class DownloadQueue(
private fun setPagesFor(download: Download) {
if (download.status == Download.DOWNLOADING) {
if (download.pages != null)
if (download.pages != null) {
for (page in download.pages!!)
page.setStatusCallback {
callListeners(download)
}
}
downloadListeners.forEach { it.updateDownload(download) }
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
setPagesSubject(download.pages, null)

View File

@ -31,10 +31,11 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
if (interval > 0) {
val restrictions = preferences.libraryUpdateRestriction()!!
val acRestriction = "ac" in restrictions
val wifiRestriction = if ("wifi" in restrictions)
val wifiRestriction = if ("wifi" in restrictions) {
NetworkType.UNMETERED
else
} else {
NetworkType.CONNECTED
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(wifiRestriction)

View File

@ -195,7 +195,6 @@ class LibraryUpdateNotifier(private val context: Context) {
}
NotificationManagerCompat.from(context).apply {
notify(
Notifications.ID_NEW_CHAPTERS,
context.notification(Notifications.CHANNEL_NEW_CHAPTERS) {

View File

@ -114,7 +114,9 @@ class LibraryUpdateService(
enum class Target {
CHAPTERS, // Manga chapters
DETAILS, // Manga metadata
TRACKING // Tracking metadata
}
@ -172,8 +174,9 @@ class LibraryUpdateService(
*/
override fun onDestroy() {
job?.cancel()
if (instance == this)
if (instance == this) {
instance = null
}
if (wakeLock.isHeld) {
wakeLock.release()
}
@ -380,47 +383,47 @@ class LibraryUpdateService(
shouldDownload: Boolean
):
Boolean {
try {
var hasDownloads = false
if (job?.isCancelled == true) {
return false
}
notifier.showProgressNotification(manga, progress, mangaToUpdate.size)
val source = sourceManager.get(manga.source) as? HttpSource ?: return false
val fetchedChapters = withContext(Dispatchers.IO) {
source.fetchChapterList(manga).toBlocking().single()
} ?: emptyList()
if (fetchedChapters.isNotEmpty()) {
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source)
if (newChapters.first.isNotEmpty()) {
if (shouldDownload) {
downloadChapters(manga, newChapters.first.sortedBy { it.chapter_number })
hasDownloads = true
}
newUpdates[manga] =
newChapters.first.sortedBy { it.chapter_number }.toTypedArray()
}
if (deleteRemoved && newChapters.second.isNotEmpty()) {
val removedChapters = newChapters.second.filter {
downloadManager.isChapterDownloaded(it, manga)
}
if (removedChapters.isNotEmpty()) {
downloadManager.deleteChapters(removedChapters, manga, source)
}
}
if (newChapters.first.size + newChapters.second.size > 0) listener?.onUpdateManga(
manga
)
}
return hasDownloads
} catch (e: Exception) {
if (e !is CancellationException) {
failedUpdates[manga] = e.message
Timber.e("Failed updating: ${manga.title}: $e")
}
try {
var hasDownloads = false
if (job?.isCancelled == true) {
return false
}
notifier.showProgressNotification(manga, progress, mangaToUpdate.size)
val source = sourceManager.get(manga.source) as? HttpSource ?: return false
val fetchedChapters = withContext(Dispatchers.IO) {
source.fetchChapterList(manga).toBlocking().single()
} ?: emptyList()
if (fetchedChapters.isNotEmpty()) {
val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source)
if (newChapters.first.isNotEmpty()) {
if (shouldDownload) {
downloadChapters(manga, newChapters.first.sortedBy { it.chapter_number })
hasDownloads = true
}
newUpdates[manga] =
newChapters.first.sortedBy { it.chapter_number }.toTypedArray()
}
if (deleteRemoved && newChapters.second.isNotEmpty()) {
val removedChapters = newChapters.second.filter {
downloadManager.isChapterDownloaded(it, manga)
}
if (removedChapters.isNotEmpty()) {
downloadManager.deleteChapters(removedChapters, manga, source)
}
}
if (newChapters.first.size + newChapters.second.size > 0) listener?.onUpdateManga(
manga
)
}
return hasDownloads
} catch (e: Exception) {
if (e !is CancellationException) {
failedUpdates[manga] = e.message
Timber.e("Failed updating: ${manga.title}: $e")
}
return false
}
}
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
// We don't want to start downloading while the library is updating, because websites

View File

@ -448,19 +448,19 @@ class NotificationReceiver : BroadcastReceiver() {
*/
internal fun openChapterPendingActivity(context: Context, manga: Manga, groupId: Int):
PendingIntent {
val newIntent =
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
.putExtra("notificationId", manga.id.hashCode())
.putExtra("groupId", groupId)
return PendingIntent.getActivity(
context,
manga.id.hashCode(),
newIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
val newIntent =
Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(MangaDetailsController.MANGA_EXTRA, manga.id)
.putExtra("notificationId", manga.id.hashCode())
.putExtra("groupId", groupId)
return PendingIntent.getActivity(
context,
manga.id.hashCode(),
newIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
/**
* Returns [PendingIntent] that opens the error log file in an external viewer
@ -522,15 +522,15 @@ class NotificationReceiver : BroadcastReceiver() {
groupId: Int
):
PendingIntent {
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
action = ACTION_MARK_AS_READ
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
putExtra(EXTRA_MANGA_ID, manga.id)
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
putExtra(EXTRA_GROUP_ID, groupId)
}
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
action = ACTION_MARK_AS_READ
putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
putExtra(EXTRA_MANGA_ID, manga.id)
putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
putExtra(EXTRA_GROUP_ID, groupId)
}
return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
* Returns [PendingIntent] that starts a service which stops the library update

View File

@ -6,11 +6,9 @@ import androidx.annotation.StringRes
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.anilist.Anilist
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.manga.track.SetTrackReadingDatesDialog
import eu.kanade.tachiyomi.util.system.executeOnIO
import okhttp3.OkHttpClient
import uy.kohesive.injekt.injectLazy

View File

@ -25,7 +25,6 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import timber.log.Timber
import java.util.Calendar
import java.util.Date
import java.util.concurrent.TimeUnit
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
@ -34,7 +33,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
suspend fun addLibManga(track: Track): Track {
return withContext(Dispatchers.IO) {
val variables = jsonObject(
"mangaId" to track.media_id,
"progress" to track.last_chapter_read,
@ -105,7 +103,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
}
suspend fun findLibManga(track: Track, userid: Int): Track? {
return withContext(Dispatchers.IO) {
val variables = jsonObject(
"id" to userid,
@ -141,7 +138,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
suspend fun remove(track: Track): Boolean {
return withContext(Dispatchers.IO) {
try {
val variables = jsonObject(
"listId" to track.library_id
)

View File

@ -114,7 +114,6 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) {
suspend fun login(code: String): Boolean {
try {
val oauth = api.accessToken(code)
interceptor.newAuth(oauth)
saveCredentials(oauth.user_id.toString(), oauth.access_token)

View File

@ -5,14 +5,12 @@ import android.graphics.Color
import androidx.annotation.StringRes
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.data.track.updateNewTrackInfo
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
@ -89,7 +87,6 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
// Set default fields if it's not found in the list
add(track)
}
}
override fun canRemoveFromService(): Boolean = true

View File

@ -8,17 +8,11 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.consumeBody
import eu.kanade.tachiyomi.network.consumeXmlBody
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.PkceUtil
import eu.kanade.tachiyomi.util.selectInt
import eu.kanade.tachiyomi.util.selectText
import eu.kanade.tachiyomi.util.system.withIOContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.boolean
import kotlinx.serialization.json.contentOrNull
@ -27,17 +21,9 @@ import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.parser.Parser
import retrofit2.http.DELETE
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.*
@ -49,91 +35,90 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
suspend fun getAccessToken(authCode: String): OAuth {
return withIOContext {
val formBody: RequestBody = FormBody.Builder()
.add("client_id", clientId)
.add("code", authCode)
.add("code_verifier", codeVerifier)
.add("grant_type", "authorization_code")
.build()
.add("client_id", clientId)
.add("code", authCode)
.add("code_verifier", codeVerifier)
.add("grant_type", "authorization_code")
.build()
client.newCall(POST("$baseOAuthUrl/token", body = formBody))
.await()
.parseAs()
.await()
.parseAs()
}
}
suspend fun getCurrentUser(): String {
return withIOContext {
val request = Request.Builder()
.url("$baseApiUrl/users/@me")
.get()
.build()
.url("$baseApiUrl/users/@me")
.get()
.build()
authClient.newCall(request)
.await()
.parseAs<JsonObject>()
.let { it["name"]!!.jsonPrimitive.content }
.await()
.parseAs<JsonObject>()
.let { it["name"]!!.jsonPrimitive.content }
}
}
suspend fun search(query: String): List<TrackSearch> {
return withIOContext {
val url = "$baseApiUrl/manga".toUri().buildUpon()
.appendQueryParameter("q", query)
.appendQueryParameter("nsfw", "true")
.build()
.appendQueryParameter("q", query)
.appendQueryParameter("nsfw", "true")
.build()
authClient.newCall(GET(url.toString()))
.await()
.parseAs<JsonObject>()
.let {
it["data"]!!.jsonArray
.map { data -> data.jsonObject["node"]!!.jsonObject }
.map { node ->
val id = node["id"]!!.jsonPrimitive.int
async { getMangaDetails(id) }
}
.awaitAll()
.filter { trackSearch -> trackSearch.publishing_type != "novel" }
}
.await()
.parseAs<JsonObject>()
.let {
it["data"]!!.jsonArray
.map { data -> data.jsonObject["node"]!!.jsonObject }
.map { node ->
val id = node["id"]!!.jsonPrimitive.int
async { getMangaDetails(id) }
}
.awaitAll()
.filter { trackSearch -> trackSearch.publishing_type != "novel" }
}
}
}
suspend fun getMangaDetails(id: Int): TrackSearch {
return withIOContext {
val url = "$baseApiUrl/manga".toUri().buildUpon()
.appendPath(id.toString())
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
.build()
.appendPath(id.toString())
.appendQueryParameter("fields", "id,title,synopsis,num_chapters,main_picture,status,media_type,start_date")
.build()
authClient.newCall(GET(url.toString()))
.await()
.parseAs<JsonObject>()
.let {
val obj = it.jsonObject
TrackSearch.create(TrackManager.MYANIMELIST).apply {
media_id = obj["id"]!!.jsonPrimitive.int
title = obj["title"]!!.jsonPrimitive.content
summary = obj["synopsis"]?.jsonPrimitive?.content ?: ""
total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
cover_url = obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content ?: ""
tracking_url = "https://myanimelist.net/manga/$media_id"
publishing_status = obj["status"]!!.jsonPrimitive.content.replace("_", " ")
publishing_type = obj["media_type"]!!.jsonPrimitive.content.replace("_", " ")
start_date = try {
val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
outputDf.format(obj["start_date"]!!)
} catch (e: Exception) {
""
}
.await()
.parseAs<JsonObject>()
.let {
val obj = it.jsonObject
TrackSearch.create(TrackManager.MYANIMELIST).apply {
media_id = obj["id"]!!.jsonPrimitive.int
title = obj["title"]!!.jsonPrimitive.content
summary = obj["synopsis"]?.jsonPrimitive?.content ?: ""
total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
cover_url = obj["main_picture"]?.jsonObject?.get("large")?.jsonPrimitive?.content ?: ""
tracking_url = "https://myanimelist.net/manga/$media_id"
publishing_status = obj["status"]!!.jsonPrimitive.content.replace("_", " ")
publishing_type = obj["media_type"]!!.jsonPrimitive.content.replace("_", " ")
start_date = try {
val outputDf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
outputDf.format(obj["start_date"]!!)
} catch (e: Exception) {
""
}
}
}
}
}
suspend fun updateItem(track: Track): Track {
return withIOContext {
val formBodyBuilder = FormBody.Builder()
.add("status", track.toMyAnimeListStatus() ?: "reading")
.add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
.add("score", track.score.toString())
.add("num_chapters_read", track.last_chapter_read.toString())
.add("status", track.toMyAnimeListStatus() ?: "reading")
.add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
.add("score", track.score.toString())
.add("num_chapters_read", track.last_chapter_read.toString())
convertToIsoDate(track.started_reading_date)?.let {
formBodyBuilder.add("start_date", it)
}
@ -142,32 +127,31 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
}
val request = Request.Builder()
.url(mangaUrl(track.media_id).toString())
.put(formBodyBuilder.build())
.build()
.url(mangaUrl(track.media_id).toString())
.put(formBodyBuilder.build())
.build()
authClient.newCall(request)
.await()
.parseAs<JsonObject>()
.let { parseMangaItem(it, track) }
.await()
.parseAs<JsonObject>()
.let { parseMangaItem(it, track) }
}
}
suspend fun findListItem(track: Track): Track? {
return withIOContext {
val uri = "$baseApiUrl/manga".toUri().buildUpon()
.appendPath(track.media_id.toString())
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
.build()
.appendPath(track.media_id.toString())
.appendQueryParameter("fields", "num_chapters,my_list_status{start_date,finish_date}")
.build()
authClient.newCall(GET(uri.toString()))
.await()
.parseAs<JsonObject>()
.let { obj ->
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
obj.jsonObject["my_list_status"]?.jsonObject?.let {
parseMangaItem(it, track)
}
.await()
.parseAs<JsonObject>()
.let { obj ->
track.total_chapters = obj["num_chapters"]!!.jsonPrimitive.int
obj.jsonObject["my_list_status"]?.jsonObject?.let {
parseMangaItem(it, track)
}
}
}
}
@ -177,17 +161,17 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
val obj = json.jsonObject
val matches = obj["data"]!!.jsonArray
.filter {
it.jsonObject["node"]!!.jsonObject["title"]!!.jsonPrimitive.content.contains(
query,
ignoreCase = true
)
}
.map {
val id = it.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int
async { getMangaDetails(id) }
}
.awaitAll()
.filter {
it.jsonObject["node"]!!.jsonObject["title"]!!.jsonPrimitive.content.contains(
query,
ignoreCase = true
)
}
.map {
val id = it.jsonObject["node"]!!.jsonObject["id"]!!.jsonPrimitive.int
async { getMangaDetails(id) }
}
.awaitAll()
// Check next page if there's more
if (!obj["paging"]!!.jsonObject["next"]?.jsonPrimitive?.contentOrNull.isNullOrBlank()) {
@ -201,19 +185,19 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
private suspend fun getListPage(offset: Int): JsonObject {
return withIOContext {
val urlBuilder = "$baseApiUrl/users/@me/mangalist".toUri().buildUpon()
.appendQueryParameter("fields", "list_status{start_date,finish_date}")
.appendQueryParameter("limit", listPaginationAmount.toString())
.appendQueryParameter("fields", "list_status{start_date,finish_date}")
.appendQueryParameter("limit", listPaginationAmount.toString())
if (offset > 0) {
urlBuilder.appendQueryParameter("offset", offset.toString())
}
val request = Request.Builder()
.url(urlBuilder.build().toString())
.get()
.build()
.url(urlBuilder.build().toString())
.get()
.build()
authClient.newCall(request)
.await()
.parseAs()
.await()
.parseAs()
}
}
@ -251,7 +235,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
suspend fun remove(track: Track): Boolean {
return withIOContext {
try {
try {
val request = Request.Builder()
.url(mangaUrl(track.media_id).toString())
.delete()
@ -277,22 +261,22 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
private var codeVerifier: String = ""
fun authUrl(): Uri = "$baseOAuthUrl/authorize".toUri().buildUpon()
.appendQueryParameter("client_id", clientId)
.appendQueryParameter("code_challenge", getPkceChallengeCode())
.appendQueryParameter("response_type", "code")
.build()
.appendQueryParameter("client_id", clientId)
.appendQueryParameter("code_challenge", getPkceChallengeCode())
.appendQueryParameter("response_type", "code")
.build()
fun mangaUrl(id: Int): Uri = "$baseApiUrl/manga".toUri().buildUpon()
.appendPath(id.toString())
.appendPath("my_list_status")
.build()
.appendPath(id.toString())
.appendPath("my_list_status")
.build()
fun refreshTokenRequest(refreshToken: String): Request {
val formBody: RequestBody = FormBody.Builder()
.add("client_id", clientId)
.add("refresh_token", refreshToken)
.add("grant_type", "refresh_token")
.build()
.add("client_id", clientId)
.add("refresh_token", refreshToken)
.add("grant_type", "refresh_token")
.build()
return POST("$baseOAuthUrl/token", body = formBody)
}

View File

@ -3,16 +3,10 @@ package eu.kanade.tachiyomi.data.track.myanimelist
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okio.Buffer
import org.json.JSONObject
import uy.kohesive.injekt.injectLazy
class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var token: String?) : Interceptor {
@ -51,8 +45,8 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var t
// Add the authorization header to the original request.
val authRequest = originalRequest.newBuilder()
.addHeader("Authorization", "Bearer ${oauth!!.access_token}")
.build()
.addHeader("Authorization", "Bearer ${oauth!!.access_token}")
.build()
return chain.proceed(authRequest)
}

View File

@ -69,8 +69,9 @@ class ExtensionManager(
}
fun removeListener(listener: ExtensionsChangedListener) {
if (this.listener == listener)
if (this.listener == listener) {
this.listener = null
}
}
fun getAppIconForSource(source: Source): Drawable? {

View File

@ -62,17 +62,17 @@ internal class ExtensionGithubApi {
libVersion >= ExtensionLoader.LIB_VERSION_MIN && libVersion <= ExtensionLoader.LIB_VERSION_MAX
}
.map { element ->
val name = element.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("Tachiyomi: ")
val pkgName = element.jsonObject["pkg"]!!.jsonPrimitive.content
val apkName = element.jsonObject["apk"]!!.jsonPrimitive.content
val versionName = element.jsonObject["version"]!!.jsonPrimitive.content
val versionCode = element.jsonObject["code"]!!.jsonPrimitive.int
val lang = element.jsonObject["lang"]!!.jsonPrimitive.content
val nsfw = element.jsonObject["nsfw"]!!.jsonPrimitive.int == 1
val icon = "${REPO_URL_PREFIX}icon/${apkName.replace(".apk", ".png")}"
val name = element.jsonObject["name"]!!.jsonPrimitive.content.substringAfter("Tachiyomi: ")
val pkgName = element.jsonObject["pkg"]!!.jsonPrimitive.content
val apkName = element.jsonObject["apk"]!!.jsonPrimitive.content
val versionName = element.jsonObject["version"]!!.jsonPrimitive.content
val versionCode = element.jsonObject["code"]!!.jsonPrimitive.int
val lang = element.jsonObject["lang"]!!.jsonPrimitive.content
val nsfw = element.jsonObject["nsfw"]!!.jsonPrimitive.int == 1
val icon = "${REPO_URL_PREFIX}icon/${apkName.replace(".apk", ".png")}"
Extension.Available(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon)
}
Extension.Available(name, pkgName, versionName, versionCode, lang, nsfw, apkName, icon)
}
}
fun getApkUrl(extension: Extension.Available): String {

View File

@ -144,10 +144,11 @@ internal object ExtensionLoader {
.split(";")
.map {
val sourceClass = it.trim()
if (sourceClass.startsWith("."))
if (sourceClass.startsWith(".")) {
pkgInfo.packageName + sourceClass
else
} else {
sourceClass
}
}
.flatMap {
try {

View File

@ -16,7 +16,6 @@ fun GET(
headers: Headers = DEFAULT_HEADERS,
cache: CacheControl = DEFAULT_CACHE_CONTROL
): Request {
return Request.Builder()
.url(url)
.headers(headers)
@ -30,7 +29,6 @@ fun POST(
body: RequestBody = DEFAULT_BODY,
cache: CacheControl = DEFAULT_CACHE_CONTROL
): Request {
return Request.Builder()
.url(url)
.post(body)

View File

@ -61,8 +61,9 @@ class SmartSearchEngine(
} else title
val searchResults = source.fetchSearchManga(1, searchQuery, FilterList()).toSingle().await(Schedulers.io())
if (searchResults.mangas.size == 1)
if (searchResults.mangas.size == 1) {
return@supervisorScope listOf(SearchEntry(searchResults.mangas.first(), 0.0))
}
searchResults.mangas.map {
val normalizedDistance = normalizedLevenshtein.similarity(title, it.title)

View File

@ -15,14 +15,16 @@ open class Page(
val number: Int
get() = index + 1
@Transient @Volatile var status: Int = 0
@Transient @Volatile
var status: Int = 0
set(value) {
field = value
statusSubject?.onNext(value)
statusCallback?.invoke(this)
}
@Transient @Volatile var progress: Int = 0
@Transient @Volatile
var progress: Int = 0
set(value) {
field = value
statusCallback?.invoke(this)

View File

@ -36,25 +36,31 @@ interface SManga : Serializable {
get() = (this as? MangaImpl)?.ogGenre ?: genre
fun copyFrom(other: SManga) {
if (other.author != null)
if (other.author != null) {
author = other.originalAuthor
}
if (other.artist != null)
if (other.artist != null) {
artist = other.originalArtist
}
if (other.description != null)
if (other.description != null) {
description = other.originalDescription
}
if (other.genre != null)
if (other.genre != null) {
genre = other.originalGenre
}
if (other.thumbnail_url != null)
if (other.thumbnail_url != null) {
thumbnail_url = other.thumbnail_url
}
status = other.status
if (!initialized)
if (!initialized) {
initialized = other.initialized
}
}
companion object {

View File

@ -29,7 +29,8 @@ abstract class BaseActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
if (this !is BiometricActivity && this !is SearchActivity)
if (this !is BiometricActivity && this !is SearchActivity) {
SecureActivityDelegate.promptLockIfNeeded(this)
}
}
}

View File

@ -84,8 +84,9 @@ abstract class BaseController(bundle: Bundle? = null) :
parentController = parentController.parentController
}
if (router.backstack.lastOrNull()?.controller() == this)
if (router.backstack.lastOrNull()?.controller() == this) {
(activity as? AppCompatActivity)?.supportActionBar?.title = getTitle()
}
}
private fun Controller.instance(): String {

View File

@ -43,12 +43,10 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
}
fun <T> Observable<T>.subscribeUntilDetach(): Subscription {
return subscribe().also { untilDetachSubscriptions.add(it) }
}
fun <T> Observable<T>.subscribeUntilDetach(onNext: (T) -> Unit): Subscription {
return subscribe(onNext).also { untilDetachSubscriptions.add(it) }
}
@ -56,7 +54,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
onNext: (T) -> Unit,
onError: (Throwable) -> Unit
): Subscription {
return subscribe(onNext, onError).also { untilDetachSubscriptions.add(it) }
}
@ -65,17 +62,14 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
onError: (Throwable) -> Unit,
onCompleted: () -> Unit
): Subscription {
return subscribe(onNext, onError, onCompleted).also { untilDetachSubscriptions.add(it) }
}
fun <T> Observable<T>.subscribeUntilDestroy(): Subscription {
return subscribe().also { untilDestroySubscriptions.add(it) }
}
fun <T> Observable<T>.subscribeUntilDestroy(onNext: (T) -> Unit): Subscription {
return subscribe(onNext).also { untilDestroySubscriptions.add(it) }
}
@ -83,7 +77,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
onNext: (T) -> Unit,
onError: (Throwable) -> Unit
): Subscription {
return subscribe(onNext, onError).also { untilDestroySubscriptions.add(it) }
}
@ -92,7 +85,6 @@ abstract class RxController(bundle: Bundle? = null) : BaseController(bundle) {
onError: (Throwable) -> Unit,
onCompleted: () -> Unit
): Subscription {
return subscribe(onNext, onError, onCompleted).also { untilDestroySubscriptions.add(it) }
}
}

View File

@ -122,8 +122,9 @@ class CategoryController(bundle: Bundle? = null) :
override fun onCategoryRename(position: Int, newName: String): Boolean {
val category = adapter?.getItem(position)?.category ?: return false
if (category.order == CREATE_CATEGORY_ORDER)
if (category.order == CREATE_CATEGORY_ORDER) {
return (presenter.createCategory(newName))
}
return (presenter.renameCategory(category, newName))
}
@ -185,6 +186,7 @@ class CategoryController(bundle: Bundle? = null) :
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
return toPosition > 0
}
/**
* Called from the presenter when a category with the given name already exists.
*/

View File

@ -121,8 +121,9 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
) {
isEditing(false)
edit_text.inputType = InputType.TYPE_NULL
if (!createCategory)
if (!createCategory) {
title.text = edit_text.text.toString()
}
}
} else {
itemView.performClick()

View File

@ -105,10 +105,11 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
preferences.downloadNewCategories(),
true
)
if (downloadNew && preferences.downloadNewCategories().get().isEmpty())
if (downloadNew && preferences.downloadNewCategories().get().isEmpty()) {
view.download_new.gone()
else if (!downloadNew)
} else if (!downloadNew) {
view.download_new.visible()
}
view.download_new.isChecked =
preferences.downloadNew().get() && view.download_new.isChecked
setCheckbox(
@ -132,9 +133,9 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
}
private fun setCheckbox(
box: CompoundButton,
categories: Preference<Set<String>>,
shouldShow: Boolean
box: CompoundButton,
categories: Preference<Set<String>>,
shouldShow: Boolean
) {
val updateCategories = categories.get()
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)

View File

@ -202,8 +202,9 @@ class DownloadBottomSheet @JvmOverloads constructor(
val adapter = adapter ?: return false
val items = adapter.currentItems.sortedBy { it.download.chapter.date_upload }
.toMutableList()
if (item.itemId == R.id.newest)
if (item.itemId == R.id.newest) {
items.reverse()
}
adapter.updateDataSet(items)
val downloads = items.mapNotNull { it.download }
presenter.reorder(downloads)
@ -266,10 +267,11 @@ class DownloadBottomSheet @JvmOverloads constructor(
val items = adapter?.currentItems?.toMutableList() ?: return
val item = items[position]
items.remove(item)
if (menuItem.itemId == R.id.move_to_top)
if (menuItem.itemId == R.id.move_to_top) {
items.add(0, item)
else
} else {
items.add(item)
}
adapter?.updateDataSet(items)
val downloads = items.mapNotNull { it.download }
presenter.reorder(downloads)

View File

@ -59,8 +59,9 @@ class DownloadButton @JvmOverloads constructor(context: Context, attrs: Attribut
isAnimating = false
}
download_icon.setImageDrawable(
if (state == Download.CHECKED)
checkDrawable else downloadDrawable
if (state == Download.CHECKED) {
checkDrawable
} else downloadDrawable
)
when (state) {
Download.CHECKED -> {

View File

@ -15,7 +15,6 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.migration.MangaItem
import eu.kanade.tachiyomi.ui.migration.SelectionHeader
import eu.kanade.tachiyomi.ui.migration.SourceItem
import eu.kanade.tachiyomi.util.lang.combineLatest
import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.system.executeOnIO
import kotlinx.coroutines.CoroutineScope
@ -26,8 +25,6 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -76,14 +73,15 @@ class ExtensionBottomPresenter(
val migrationJob = async {
val favs = db.getFavoriteMangas().executeOnIO()
sourceItems = findSourcesWithManga(favs)
mangaItems = HashMap(sourceItems.associate {
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
})
mangaItems = HashMap(
sourceItems.associate {
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
}
)
withContext(Dispatchers.Main) {
if (selectedSource != null) {
bottomSheet.setMigrationManga(mangaItems[selectedSource])
}
else {
} else {
bottomSheet.setMigrationSources(sourceItems)
}
}
@ -125,14 +123,15 @@ class ExtensionBottomPresenter(
scope.launch {
val favs = db.getFavoriteMangas().executeOnIO()
sourceItems = findSourcesWithManga(favs)
mangaItems = HashMap(sourceItems.associate {
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
})
mangaItems = HashMap(
sourceItems.associate {
it.source.id to this@ExtensionBottomPresenter.libraryToMigrationItem(favs, it.source.id)
}
)
withContext(Dispatchers.Main) {
if (selectedSource != null) {
bottomSheet.setMigrationManga(mangaItems[selectedSource])
}
else {
} else {
bottomSheet.setMigrationSources(sourceItems)
}
}

View File

@ -308,10 +308,12 @@ class ExtensionBottomSheet @JvmOverloads constructor(context: Context, attrs: At
}
override fun getPageTitle(position: Int): CharSequence {
return context.getString(when (position) {
0 -> R.string.extensions
else -> R.string.migration
})
return context.getString(
when (position) {
0 -> R.string.extensions
else -> R.string.migration
}
)
}
}
}

View File

@ -38,7 +38,6 @@ data class ExtensionGroupItem(val name: String, val size: Int) : AbstractHeaderI
position: Int,
payloads: MutableList<Any?>?
) {
holder.bind(this)
}

View File

@ -46,7 +46,6 @@ data class ExtensionItem(
position: Int,
payloads: MutableList<Any?>?
) {
if (payloads == null || payloads.isEmpty()) {
holder.bind(this)
} else {

View File

@ -3,7 +3,6 @@ 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

View File

@ -125,7 +125,8 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
screen.setShouldUseGeneratedIds(true)
val extHeaderAdapter = ExtensionDetailsHeaderAdapter(presenter)
extHeaderAdapter.setHasStableIds(true)
extension_prefs_recycler.adapter = ConcatAdapter(concatAdapterConfig,
extension_prefs_recycler.adapter = ConcatAdapter(
concatAdapterConfig,
extHeaderAdapter,
PreferenceGroupAdapter(screen)
)
@ -151,7 +152,6 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
lastOpenPreferencePosition = savedInstanceState.get(LASTOPENPREFERENCE_KEY) as? Int
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.extension_details, menu)
@ -208,8 +208,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
toggleSource(source, checked)
prefs.forEach { it.isVisible = checked }
true
}
else {
} else {
coordinator.snack(context.getString(R.string._must_be_enabled_first, title), Snackbar.LENGTH_LONG) {
setAction(R.string.enable) {
preferences.enabledLanguages() += source.lang
@ -308,7 +307,6 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
return id.toString() !in preferences.hiddenSources().get() && isLangEnabled()
}
private fun Source.isLangEnabled(langs: Set<String>? = null): Boolean {
return (lang in langs ?: preferences.enabledLanguages().get())
}

View File

@ -45,7 +45,7 @@ class ExtensionDetailsHeaderAdapter(private val presenter: ExtensionDetailsPrese
view.extension_pkg.text = extension.pkgName
view.extension_uninstall_button.setOnClickListener {
presenter.uninstallExtension()
presenter.uninstallExtension()
}
if (extension.isObsolete) {

View File

@ -51,4 +51,4 @@ class ExtensionSettingsDividerItemDecoration(context: Context) : androidx.recycl
) {
outRect.set(0, 0, 0, divider.intrinsicHeight)
}
}
}

View File

@ -41,7 +41,6 @@ class AddToLibraryCategoriesDialog<T>(bundle: Bundle? = null) :
}
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog(activity!!).title(R.string.add_to_library).message(R.string.add_to_categories)
.listItemsMultiChoice(
items = categories.map { it.name },

View File

@ -29,6 +29,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
init {
setDisplayHeadersAtStartUp(true)
}
/**
* The list of manga in this category.
*/

View File

@ -619,13 +619,12 @@ class LibraryController(
(listOfYs.minOrNull() ?: filter_bottom_sheet.y) +
hopperOffset
if (view.height - insetBottom < category_hopper_frame.y) {
jumper_category_text.translationY = -(category_hopper_frame.y - (view.height - insetBottom))
jumper_category_text.translationY = -(category_hopper_frame.y - (view.height - insetBottom))
} else {
jumper_category_text.translationY = 0f
}
}
fun resetHopperY() {
hopperOffset = 0f
}
@ -821,10 +820,11 @@ class LibraryController(
)
}
adapter.setItems(mangaMap)
if (recycler.itemAnimator == null)
if (recycler.itemAnimator == null) {
recycler.post {
recycler.itemAnimator = DefaultItemAnimator()
}
}
singleCategory = presenter.categories.size <= 1
showDropdown()
progress.gone()

View File

@ -70,8 +70,9 @@ class LibraryGridHolder(
if (cover_thumbnail.height == 0) {
val oldPos = adapterPosition
adapter.recyclerView.post {
if (oldPos == adapterPosition)
if (oldPos == adapterPosition) {
setCover(item.manga)
}
}
} else setCover(item.manga)
}

View File

@ -44,8 +44,9 @@ abstract class LibraryHolder(
}
fun setReadingButton(item: LibraryItem) {
play_layout?.visibility = if (item.manga.unread > 0 && item.unreadType > 0 && !item.hideReadingButton)
View.VISIBLE else View.GONE
play_layout?.visibility = if (item.manga.unread > 0 && item.unreadType > 0 && !item.hideReadingButton) {
View.VISIBLE
} else View.GONE
}
/**

View File

@ -46,10 +46,11 @@ class LibraryItem(
get() = preferences.hideStartReadingButton().getOrDefault()
override fun getLayoutRes(): Int {
return if (libraryLayout == 0 || manga.isBlank())
return if (libraryLayout == 0 || manga.isBlank()) {
R.layout.manga_list_item
else
} else {
R.layout.manga_grid_item
}
}
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder {
@ -141,11 +142,13 @@ class LibraryItem(
* @return true if the manga should be included, false otherwise.
*/
override fun filter(constraint: String): Boolean {
if (manga.isBlank() && manga.title.isBlank())
if (manga.isBlank() && manga.title.isBlank()) {
return constraint.isEmpty()
}
val sourceManager by injectLazy<SourceManager>()
val sourceName = if (manga.source == 0L) "Local" else
val sourceName = if (manga.source == 0L) "Local" else {
sourceManager.getOrStub(manga.source).name
}
return manga.title.contains(constraint, true) ||
(manga.author?.contains(constraint, true) ?: false) ||
(manga.artist?.contains(constraint, true) ?: false) ||
@ -159,14 +162,15 @@ class LibraryItem(
@SuppressLint("DefaultLocale")
private fun containsGenre(tag: String, genres: List<String>?): Boolean {
if (tag.trim().isEmpty()) return true
return if (tag.startsWith("-"))
return if (tag.startsWith("-")) {
genres?.find {
it.trim().toLowerCase() == tag.substringAfter("-").toLowerCase()
} == null
else
} else {
genres?.find {
it.trim().toLowerCase() == tag.toLowerCase()
} != null
}
}
override fun equals(other: Any?): Boolean {

View File

@ -36,7 +36,6 @@ class LibraryListHolder(
* @param item the manga item to bind.
*/
override fun onSetValues(item: LibraryItem) {
title.visible()
constraint_layout.minHeight = 56.dpToPx
if (item.manga.isBlank()) {
@ -47,8 +46,9 @@ class LibraryListHolder(
if (item.manga.status == -1) {
title.text = null
title.gone()
} else
} else {
title.text = itemView.context.getString(R.string.category_is_empty)
}
title.textAlignment = View.TEXT_ALIGNMENT_CENTER
card.gone()
badge_view.gone()

View File

@ -729,8 +729,9 @@ class LibraryPresenter(
db.resetMangaInfo(manga).executeOnIO()
coverCache.deleteFromCache(manga)
val source = sourceManager.get(manga.source) as? HttpSource
if (source != null)
if (source != null) {
downloadManager.deleteManga(manga, source)
}
}
}
}
@ -825,9 +826,10 @@ class LibraryPresenter(
val mc = ArrayList<MangaCategory>()
val categories =
if (catId == 0) emptyList()
else
else {
db.getCategoriesForManga(manga).executeOnIO()
.filter { it.id != oldCatId } + listOf(category)
}
for (cat in categories) {
mc.add(MangaCategory.create(manga, cat))
@ -858,10 +860,11 @@ class LibraryPresenter(
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
it.toIntOrNull()
}.toMutableSet()
if (categoryId in categoriesHidden)
if (categoryId in categoriesHidden) {
categoriesHidden.remove(categoryId)
else
} else {
categoriesHidden.add(categoryId)
}
preferences.collapsedCategories().set(categoriesHidden.map { it.toString() }.toMutableSet())
getLibrary()
}

View File

@ -47,8 +47,9 @@ class CategoryRecyclerView @JvmOverloads constructor(
}
)
fastAdapter.onClickListener = { _, _, item, _ ->
if (item.category.id != -1)
if (item.category.id != -1) {
onCategoryClicked(item.category.order)
}
true
}
}

View File

@ -20,4 +20,4 @@ class LibraryBadgesView @JvmOverloads constructor(context: Context, attrs: Attri
controller.presenter.requestDownloadBadgesUpdate()
}
}
}
}

View File

@ -25,4 +25,4 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
controller.resetHopperY()
}
}
}
}

View File

@ -20,4 +20,4 @@ class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: Attr
controller.reattachAdapter()
}
}
}
}

View File

@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
open class TabbedLibraryDisplaySheet(controller: LibraryController):
open class TabbedLibraryDisplaySheet(controller: LibraryController) :
TabbedBottomSheetDialog(controller.activity!!) {
private val displayView: LibraryDisplayView = inflate(controller.activity!!, R.layout.library_display_layout, null) as LibraryDisplayView
@ -26,10 +26,12 @@ open class TabbedLibraryDisplaySheet(controller: LibraryController):
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
menu.tooltipText = context.getString(R.string.more_library_settings)
}
menu.setImageDrawable(ContextCompat.getDrawable(
context,
R.drawable.ic_settings_24dp
))
menu.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.ic_settings_24dp
)
)
menu.setOnClickListener {
controller.router.pushController(SettingsLibraryController().withFadeTransaction())
dismiss()
@ -47,4 +49,4 @@ open class TabbedLibraryDisplaySheet(controller: LibraryController):
R.string.badges,
R.string.categories
)
}
}

View File

@ -90,8 +90,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
list.add(unread)
list.add(downloaded)
list.add(completed)
if (hasTracking)
if (hasTracking) {
tracked?.let { list.add(it) }
}
list
}
@ -152,8 +153,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
val activeFilters = hasActiveFiltersFromPref()
if (activeFilters && sheetBehavior.isHidden() && sheetBehavior?.skipCollapsed == false)
if (activeFilters && sheetBehavior.isHidden() && sheetBehavior?.skipCollapsed == false) {
sheetBehavior?.collapse()
}
post {
updateRootPadding(
@ -218,10 +220,11 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
?: if (sheetBehavior.isExpanded()) 1f else 0f
val percent = (trueProgress * 100).roundToInt()
val value = (percent * (maxHeight - minHeight) / 100) + minHeight
if (trueProgress >= 0)
if (trueProgress >= 0) {
libraryRecyler?.updatePaddingRelative(bottom = value + 10.dpToPx + bottomBarHeight)
else
} else {
libraryRecyler?.updatePaddingRelative(bottom = (minHeight * (1 + trueProgress)).toInt() + bottomBarHeight)
}
}
fun hasActiveFilters() = filterItems.any { it.isActivated }
@ -235,7 +238,6 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
private fun createTags() {
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
downloaded.setup(this, R.string.downloaded, R.string.not_downloaded)
@ -372,8 +374,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
fun manageFilterPopup() {
val recycler = RecyclerView(context)
if (filterOrder.count() != 6)
if (filterOrder.count() != 6) {
filterOrder = "urdcmt"
}
val adapter = FlexibleAdapter(
filterOrder.toCharArray().map(::ManageFilterItem),
this,
@ -493,8 +496,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
private fun reSortViews() {
filter_layout.removeAllViews()
if (filterItems.any { it.isActivated })
if (filterItems.any { it.isActivated }) {
filter_layout.addView(clearButton)
}
filterItems.filter { it.isActivated }.forEach {
filter_layout.addView(it)
}

View File

@ -84,8 +84,9 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute
private fun toggleButton(index: Int, callBack: Boolean = true) {
if (index < 0 || itemCount == 0 ||
(isActivated && index != buttons.indexOfFirst { it.isActivated })
)
) {
return
}
if (callBack) {
val transition = androidx.transition.AutoTransition()
transition.duration = 150

View File

@ -268,7 +268,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
container: ViewGroup,
handler: ControllerChangeHandler
) {
syncActivityViewWithController(to, from, isPush)
appbar.y = 0f
bottom_nav.translationY = 0f
@ -318,9 +317,9 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
window.navigationBarColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
// basically if in landscape on a phone
// For lollipop, draw opaque nav bar
if (insets.hasSideNavBar())
if (insets.hasSideNavBar()) {
Color.BLACK
else Color.argb(179, 0, 0, 0)
} else Color.argb(179, 0, 0, 0)
}
// if the android q+ device has gesture nav, transparent nav bar
// this is here in case some crazy with a notch uses landscape
@ -515,10 +514,10 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
else !router.handleBack()
) {
if (preferences.backReturnsToStart().get() && this !is SearchActivity &&
startingTab() != bottom_nav?.selectedItemId) {
startingTab() != bottom_nav?.selectedItemId
) {
goToStartingTab()
}
else {
} else {
if (!preferences.backReturnsToStart().get() && this !is SearchActivity) {
setStartingTab()
}
@ -529,13 +528,17 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
private fun setStartingTab() {
if (bottom_nav?.selectedItemId != R.id.nav_browse
&& bottom_nav?.selectedItemId != null
&& preferences.startingTab().get() >= 0)
preferences.startingTab().set(when (bottom_nav?.selectedItemId) {
R.id.nav_library -> 0
else -> 1
})
if (bottom_nav?.selectedItemId != R.id.nav_browse &&
bottom_nav?.selectedItemId != null &&
preferences.startingTab().get() >= 0
) {
preferences.startingTab().set(
when (bottom_nav?.selectedItemId) {
R.id.nav_library -> 0
else -> 1
}
)
}
}
@IdRes

View File

@ -69,8 +69,9 @@ class EditMangaDialog : DialogController {
val isLocal = manga.source == LocalSource.ID
if (isLocal) {
if (manga.title != manga.url)
if (manga.title != manga.url) {
view.title.append(manga.title)
}
view.title.hint = "${resources?.getString(R.string.title)}: ${manga.url}"
view.manga_author.append(manga.author ?: "")
view.manga_artist.append(manga.artist ?: "")

View File

@ -434,8 +434,9 @@ class MangaDetailsController :
setActionBar(true)
setStatusBarAndToolbar()
} else if (type == ControllerChangeType.PUSH_EXIT || type == ControllerChangeType.POP_EXIT) {
if (router.backstack.lastOrNull()?.controller() is DialogController)
if (router.backstack.lastOrNull()?.controller() is DialogController) {
return
}
if (type == ControllerChangeType.POP_EXIT) {
setActionBar(false)
presenter.cancelScope()
@ -1042,10 +1043,11 @@ class MangaDetailsController :
if (chapter.status != Download.NOT_DOWNLOADED && chapter.status != Download.ERROR) {
presenter.deleteChapter(chapter)
} else {
if (chapter.status == Download.ERROR)
if (chapter.status == Download.ERROR) {
DownloadService.start(view.context)
else
} else {
downloadChapters(listOf(chapter))
}
}
}
@ -1279,8 +1281,9 @@ class MangaDetailsController :
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
mode?.title = view?.context?.getString(
if (startingDLChapterPos == null)
R.string.select_starting_chapter else R.string.select_ending_chapter
if (startingDLChapterPos == null) {
R.string.select_starting_chapter
} else R.string.select_ending_chapter
)
return false
}

View File

@ -4,7 +4,6 @@ import android.app.Application
import android.graphics.Bitmap
import android.net.Uri
import android.os.Environment
import coil.Coil
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@ -88,7 +87,6 @@ class MangaDetailsPresenter(
var headerItem = MangaHeaderItem(manga, controller.fromCatalogue)
fun onCreate() {
isLockedFromSearch = SecureActivityDelegate.shouldBeLocked()
headerItem.isLocked = isLockedFromSearch
downloadManager.addListener(this)
@ -218,8 +216,9 @@ class MangaDetailsPresenter(
* @return an observable of the list of chapters filtered and sorted.
*/
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
if (isLockedFromSearch)
if (isLockedFromSearch) {
return chapterList
}
val chapters = chapterFilter.filterChapters(chapterList, manga)
@ -357,8 +356,8 @@ class MangaDetailsPresenter(
if (newChapters.first.isNotEmpty()) {
if (manga.shouldDownloadNewChapters(db, preferences)) {
downloadChapters(
newChapters.first.sortedBy { it.chapter_number }
.map { it.toModel() }
newChapters.first.sortedBy { it.chapter_number }
.map { it.toModel() }
)
}
}
@ -867,8 +866,9 @@ class MangaDetailsPresenter(
fun setStatus(item: TrackItem, index: Int) {
val track = item.track!!
track.status = item.service.getStatusList()[index]
if (item.service.isCompletedStatus(index) && track.total_chapters > 0)
if (item.service.isCompletedStatus(index) && track.total_chapters > 0) {
track.last_chapter_read = track.total_chapters
}
updateRemote(track, item.service)
}

View File

@ -70,8 +70,8 @@ class MangaHeaderHolder(
}
if (event.actionMasked == MotionEvent.ACTION_UP) {
hadSelection = manga_summary.hasSelection()
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled =
true
(adapter.delegate as MangaDetailsController).swipe_refresh.isEnabled =
true
}
false
}
@ -320,9 +320,9 @@ class MangaHeaderHolder(
fun collapse() {
sub_item_group.gone()
start_reading_button.gone()
if (more_button.visibility == View.VISIBLE || more_button.visibility == View.INVISIBLE)
if (more_button.visibility == View.VISIBLE || more_button.visibility == View.INVISIBLE) {
more_button_group.invisible()
else {
} else {
less_button.gone()
manga_genres_tags.gone()
}

View File

@ -40,10 +40,11 @@ class ChaptersSortBottomSheet(controller: MangaDetailsController) : BottomSheetD
sheetBehavior.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) {
if (progress.isNaN())
if (progress.isNaN()) {
pill.alpha = 0f
else
} else {
pill.alpha = (1 - max(0f, progress)) * 0.25f
}
}
override fun onStateChanged(p0: View, state: Int) {
@ -92,14 +93,16 @@ class ChaptersSortBottomSheet(controller: MangaDetailsController) : BottomSheetD
var defPref = presenter.globalSort()
sort_group.check(
if (presenter.manga.sortDescending(defPref)) R.id.sort_newest else
if (presenter.manga.sortDescending(defPref)) R.id.sort_newest else {
R.id.sort_oldest
}
)
hide_titles.isChecked = presenter.manga.displayMode != Manga.DISPLAY_NAME
sort_method_group.check(
if (presenter.manga.sorting == Manga.SORTING_SOURCE) R.id.sort_by_source else
if (presenter.manga.sorting == Manga.SORTING_SOURCE) R.id.sort_by_source else {
R.id.sort_by_number
}
)
set_as_default_sort.visInvisIf(

View File

@ -70,12 +70,14 @@ class SetTrackReadingDatesDialog<T> : DialogController
listener.setReadingDate(item, dateToUpdate, 0L)
}.apply {
getSuggestedDate()?.let {
message(text = it,
applySettings = {
messageTextView.setOnClickListener {
this@apply.setDate(suggestedDate ?: 0L)
message(
text = it,
applySettings = {
messageTextView.setOnClickListener {
this@apply.setDate(suggestedDate ?: 0L)
}
}
})
)
}
}
}
@ -93,9 +95,11 @@ class SetTrackReadingDatesDialog<T> : DialogController
val suggestedCalendar = Calendar.getInstance()
suggestedCalendar.timeInMillis = suggestedDate
return if (date > suggestedDate &&
(suggestedCalendar.year != calendar.year ||
suggestedCalendar.month != calendar.month ||
suggestedCalendar.dayOfMonth != calendar.dayOfMonth)
(
suggestedCalendar.year != calendar.year ||
suggestedCalendar.month != calendar.month ||
suggestedCalendar.dayOfMonth != calendar.dayOfMonth
)
) {
activity?.getString(
R.string.suggested_date_,

View File

@ -72,9 +72,9 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
date_group.visibleIf(item.service.supportsReadingDates)
if (item.service.supportsReadingDates) {
track_start_date.text =
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
track_finish_date.text =
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
} else {
}
}

View File

@ -1,8 +1,6 @@
package eu.kanade.tachiyomi.ui.manga.track
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
@ -190,11 +188,13 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
if (item.track == null) return
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Start)
SetTrackReadingDatesDialog(controller,
SetTrackReadingDatesDialog(
controller,
this,
SetTrackReadingDatesDialog.ReadingDate.Start,
item,
suggestedDate)
suggestedDate
)
.showDialog(controller.router)
}
@ -203,11 +203,13 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
if (item.track == null) return
val suggestedDate = presenter.getSuggestedDate(SetTrackReadingDatesDialog.ReadingDate.Finish)
SetTrackReadingDatesDialog(controller,
SetTrackReadingDatesDialog(
controller,
this,
SetTrackReadingDatesDialog.ReadingDate.Finish,
item,
suggestedDate)
suggestedDate
)
.showDialog(controller.router)
}
@ -257,5 +259,4 @@ class TrackingBottomSheet(private val controller: MangaDetailsController) :
private companion object {
const val TAG_SEARCH_CONTROLLER = "track_search_controller"
}
}

View File

@ -24,7 +24,6 @@ class MangaItem(val manga: Manga) : AbstractFlexibleItem<MangaHolder>() {
position: Int,
payloads: MutableList<Any?>?
) {
holder.bind(this)
}

View File

@ -93,7 +93,6 @@ class MigrationPresenter(
manga: Manga,
replace: Boolean
) {
val flags = preferences.migrateFlags().getOrDefault()
val migrateChapters = MigrationFlags.hasChapters(flags)
val migrateCategories = MigrationFlags.hasCategories(flags)

View File

@ -42,8 +42,9 @@ class SearchController(
override fun getTitle(): String? {
if (totalProgress > 1) {
return "($progress/$totalProgress) ${super.getTitle()}"
} else
} else {
return super.getTitle()
}
}
override fun createPresenter(): GlobalSearchPresenter {

View File

@ -40,7 +40,6 @@ data class SourceItem(val source: Source, val header: SelectionHeader? = null) :
position: Int,
payloads: MutableList<Any?>?
) {
holder.bind(this)
}
}

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.migration.manga.design
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
import android.view.View
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.icon
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder

View File

@ -15,7 +15,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.BaseController

View File

@ -54,7 +54,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.withContext
import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
import java.util.concurrent.atomic.AtomicInteger
@ -99,7 +98,6 @@ class MigrationListController(bundle: Bundle? = null) :
}
override fun onViewCreated(view: View) {
super.onViewCreated(view)
liftAppbarWith(recycler)
setTitle()
@ -324,7 +322,6 @@ class MigrationListController(bundle: Bundle? = null) :
}
override fun onMenuItemClick(position: Int, item: MenuItem) {
when (item.itemId) {
R.id.action_search_manually -> {
launchUI {
@ -377,7 +374,7 @@ class MigrationListController(bundle: Bundle? = null) :
try {
val newManga =
sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
.toSManga()
.toSManga()
result.copyFrom(newManga)
db.insertManga(result).executeAsBlocking()

View File

@ -33,7 +33,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.SearchActivity
@ -283,8 +282,10 @@ class ReaderActivity :
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
val detailsItem = menu?.findItem(R.id.action_manga_details)
if (presenter.manga?.mangaType(this) != null) {
detailsItem?.title = getString(R.string._details,
presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: "")
detailsItem?.title = getString(
R.string._details,
presenter.manga?.mangaType(this)?.capitalize(Locale.ROOT) ?: ""
)
} else {
detailsItem?.title = getString(R.string.details)
}
@ -798,7 +799,6 @@ class ReaderActivity :
*/
private fun setNotchCutoutMode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val currentOrientation = resources.configuration.orientation
val params = window.attributes
@ -941,10 +941,11 @@ class ReaderActivity :
* Sets the 32-bit color mode according to [enabled].
*/
private fun setTrueColor(enabled: Boolean) {
if (enabled)
if (enabled) {
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.ARGB_8888)
else
} else {
SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.RGB_565)
}
}
/**

View File

@ -38,7 +38,6 @@ class SaveImageNotifier(private val context: Context) {
* @param file image file containing downloaded page image.
*/
fun onComplete(file: File) {
val request = LoadRequest.Builder(context).memoryCachePolicy(CachePolicy.DISABLED).diskCachePolicy(CachePolicy.DISABLED)
.data(file)
.size(720, 1280)
@ -64,8 +63,9 @@ class SaveImageNotifier(private val context: Context) {
setAutoCancel(true)
color = ContextCompat.getColor(context, R.color.colorAccent)
// Clear old actions if they exist
if (mActions.isNotEmpty())
if (mActions.isNotEmpty()) {
mActions.clear()
}
setContentIntent(NotificationHandler.openImagePendingActivity(context, file))
// Share action

View File

@ -192,10 +192,11 @@ class HttpPageLoader(
* @param page the page whose source image has to be downloaded.
*/
private fun HttpSource.fetchImageFromCacheThenNet(page: ReaderPage): Observable<ReaderPage> {
return if (page.imageUrl.isNullOrEmpty())
return if (page.imageUrl.isNullOrEmpty()) {
getImageUrl(page).flatMap { getCachedImage(it) }
else
} else {
getCachedImage(page)
}
}
private fun HttpSource.getImageUrl(page: ReaderPage): Observable<ReaderPage> {

View File

@ -5,9 +5,7 @@ import android.util.AttributeSet
import android.widget.SeekBar
import androidx.annotation.ColorInt
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
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.view.*
@ -115,7 +113,6 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
)
}
/**
* Set enabled status of seekBars belonging to color filter
* @param enabled determines if seekBar gets enabled
@ -202,7 +199,7 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
* Sets the color filter overlay of the screen. Determined by HEX of integer
* @param color hex of color.
*/
private fun setColorFilterValue(@ColorInt color: Int) {
private fun setColorFilterValue(@ColorInt color: Int) {
setValues(color)
}
@ -267,4 +264,4 @@ class ReaderFilterView @JvmOverloads constructor(context: Context, attrs: Attrib
*/
fun ReaderFilterView.getGreenFromColor(color: Int): Int {
return color shr 8 and 0xFF
}
}

View File

@ -4,9 +4,7 @@ import android.content.Context
import android.util.AttributeSet
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.view.RecyclerWindowInsetsListener
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import kotlinx.android.synthetic.main.reader_general_layout.view.*
class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
@ -43,4 +41,4 @@ class ReaderGeneralView @JvmOverloads constructor(context: Context, attrs: Attri
private fun initPagerPreferences() {
sheet.updateTabs(false)
}
}
}

View File

@ -44,4 +44,4 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
listOf(scale_type, zoom_start, crop_borders, page_transitions, pager_nav, pager_invert).forEach { it.visibleIf(show) }
listOf(crop_borders_webtoon, webtoon_side_padding, webtoon_enable_zoom_out, webtoon_nav, webtoon_invert).forEach { it.visibleIf(!show) }
}
}
}

View File

@ -12,16 +12,14 @@ import com.tfcporciuncula.flow.Preference
import eu.kanade.tachiyomi.R
import kotlinx.android.synthetic.main.reader_preference.view.*
class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet?) :
FrameLayout(context, attrs) {
private var entries = emptyList<String>()
private var selectedPosition = 0
private var pref: Preference<Int>? = null
private var prefOffset = 0
private var popup:PopupMenu? = null
private var popup: PopupMenu? = null
var onItemSelectedListener: ((Int) -> Unit)? = null
set(value) {
@ -159,11 +157,11 @@ class ReaderSpinnerView @JvmOverloads constructor(context: Context, attrs: Attri
fun popup(): PopupMenu {
val popup = PopupMenu(context, this, Gravity.END)
entries.forEachIndexed { index, entry ->
entries.forEachIndexed { index, entry ->
popup.menu.add(0, index, 0, entry)
}
popup.menu[selectedPosition].isCheckable = true
popup.menu[selectedPosition].isChecked = true
return popup
}
}
}

View File

@ -1,22 +1,19 @@
package eu.kanade.tachiyomi.ui.reader.settings
import android.view.View
import androidx.core.widget.NestedScrollView
import com.google.android.material.tabs.TabLayout
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.display.LibraryBadgesView
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.visInvisIf
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import kotlinx.android.synthetic.main.reader_activity.*
import kotlinx.android.synthetic.main.reader_color_filter.view.*
import kotlinx.android.synthetic.main.recycler_with_scroller.view.*
import kotlinx.android.synthetic.main.tabbed_bottom_sheet.*
class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity): TabbedBottomSheetDialog(
class TabbedReaderSettingsSheet(val readerActivity: ReaderActivity) : TabbedBottomSheetDialog(
readerActivity
) {
private val generalView: ReaderGeneralView = View.inflate(

View File

@ -27,7 +27,6 @@ abstract class ViewerConfig(preferences: PreferencesHelper) {
var volumeKeysInverted = false
var alwaysShowChapterTransition = true
var navigationOverlayForNewUser = false
var navigationMode = 0
protected set

View File

@ -17,8 +17,7 @@ abstract class ViewerNavigation {
fun directionalRegion(LTR: Boolean): NavigationRegion {
return if (this === LEFT || this === RIGHT) {
if (if (LTR) this === LEFT else this === RIGHT) NEXT else PREV
}
else this
} else this
}
}

View File

@ -45,9 +45,12 @@ class PagerConfig(private val viewer: PagerViewer, preferences: PreferencesHelpe
.register({ navigationMode = it }, { updateNavigation(navigationMode) })
preferences.pagerNavInverted()
.register({ tappingInverted = it }, {
navigator.invertMode = it
})
.register(
{ tappingInverted = it },
{
navigator.invertMode = it
}
)
preferences.pagerNavInverted().asFlow()
.drop(1)

View File

@ -340,7 +340,6 @@ class PagerPageHolder(
@SuppressLint("PrivateResource")
private fun createProgressBar(): ReaderProgressBar {
return ReaderProgressBar(context, null).apply {
val size = 48.dpToPx
layoutParams = LayoutParams(size, size).apply {
gravity = Gravity.CENTER

View File

@ -24,6 +24,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
private set
var currentChapter: ReaderChapter? = null
/**
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
* next/previous chapter to allow seamless transitions and inverting the pages if the viewer

View File

@ -22,6 +22,7 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
private set
var currentChapter: ReaderChapter? = null
/**
* Updates this adapter with the given [chapters]. It handles setting a few pages of the
* next/previous chapter to allow seamless transitions.

View File

@ -37,9 +37,12 @@ class WebtoonConfig(preferences: PreferencesHelper = Injekt.get()) : ViewerConfi
.register({ navigationMode = it }, { updateNavigation(it) })
preferences.webtoonNavInverted()
.register({ tappingInverted = it }, {
navigator.invertMode = it
})
.register(
{ tappingInverted = it },
{
navigator.invertMode = it
}
)
preferences.webtoonNavInverted().asFlow()
.drop(1)

View File

@ -42,12 +42,13 @@ class WebtoonLayoutManager(activity: ReaderActivity) : LinearLayoutManager(activ
val fromIndex = childCount - 1
val toIndex = -1
val child = if (mOrientation == HORIZONTAL)
val child = if (mOrientation == HORIZONTAL) {
mHorizontalBoundCheck
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
else
} else {
mVerticalBoundCheck
.findOneViewWithinBoundFlags(fromIndex, toIndex, preferredBoundsFlag, 0)
}
return if (child == null) NO_POSITION else getPosition(child)
}

View File

@ -98,7 +98,7 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
}
}
)
recycler.tapListener = f@{ event ->
recycler.tapListener = f@{ event ->
if (!config.tappingEnabled) {
activity.toggleMenu()
return@f

View File

@ -44,6 +44,7 @@ class RecentlyReadController(bundle: Bundle? = null) :
init {
setHasOptionsMenu(true)
}
/**
* Adapter containing the recent manga.
*/
@ -85,8 +86,9 @@ class RecentlyReadController(bundle: Bundle? = null) :
resetProgressItem()
scrollViewWith(recycler, padBottom = true)
if (recentItems != null)
if (recentItems != null) {
adapter?.updateDataSet(recentItems!!.toList())
}
launchUI {
val manga = presenter.refresh(query)
@ -106,6 +108,7 @@ class RecentlyReadController(bundle: Bundle? = null) :
observeLater = false
}
}
/**
* Populate adapter with chapters
*
@ -115,8 +118,9 @@ class RecentlyReadController(bundle: Bundle? = null) :
val adapter = adapter ?: return
adapter.updateDataSet(mangaHistory)
adapter.onLoadMoreComplete(null)
if (recentItems == null)
if (recentItems == null) {
resetProgressItem()
}
recentItems = mangaHistory.toMutableList()
}

View File

@ -24,7 +24,6 @@ class RecentlyReadItem(val mch: MangaChapterHistory) : AbstractFlexibleItem<Rece
position: Int,
payloads: MutableList<Any?>?
) {
holder.bind(mch)
}

View File

@ -40,7 +40,6 @@ import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.spToPx
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.isCollapsed
import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.util.view.scrollViewWith
@ -95,9 +94,9 @@ class RecentsController(bundle: Bundle? = null) :
var headerHeight = 0
override fun getTitle(): String? {
return if (showingDownloads)
return if (showingDownloads) {
resources?.getString(R.string.download_queue)
else resources?.getString(R.string.recents)
} else resources?.getString(R.string.recents)
}
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -243,8 +242,9 @@ class RecentsController(bundle: Bundle? = null) :
val pad = bottomBar.translationY - bottomBar.height
val padding = max(
(-pad).toInt(),
if (dl_bottom_sheet.sheetBehavior.isExpanded()) 0 else
if (dl_bottom_sheet.sheetBehavior.isExpanded()) 0 else {
view?.rootWindowInsets?.systemWindowInsetBottom ?: 0
}
)
shadow2.translationY = pad
dl_bottom_sheet.sheetBehavior?.peekHeight = 48.spToPx + padding
@ -303,8 +303,9 @@ class RecentsController(bundle: Bundle? = null) :
swipe_refresh.isRefreshing = LibraryUpdateService.isRunning()
adapter.updateItems(recents)
adapter.removeAllScrollableHeaders()
if (presenter.viewType > 0)
if (presenter.viewType > 0) {
adapter.addScrollableHeader(presenter.generalHeader)
}
if (lastChapterId != null) {
refreshItem(lastChapterId ?: 0L)
lastChapterId = null
@ -380,8 +381,9 @@ class RecentsController(bundle: Bundle? = null) :
val manga = item.mch.manga
val history = item.mch.history
val chapter = item.mch.chapter
if (history.id != null)
if (history.id != null) {
RemoveHistoryDialog(this, manga, history, chapter).showDialog(router)
}
}
override fun removeHistory(manga: Manga, history: History, all: Boolean) {
@ -476,7 +478,7 @@ class RecentsController(bundle: Bundle? = null) :
setBottomPadding()
}
override fun onChangeEnded(handler: ControllerChangeHandler, type: ControllerChangeType ) {
override fun onChangeEnded(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeEnded(handler, type)
if (type == ControllerChangeType.POP_ENTER) setBottomPadding()
}
@ -484,8 +486,9 @@ class RecentsController(bundle: Bundle? = null) :
fun hasQueue() = presenter.downloadManager.hasQueue()
override fun showSheet() {
if (dl_bottom_sheet.sheetBehavior?.isHideable == false || hasQueue())
if (dl_bottom_sheet.sheetBehavior?.isHideable == false || hasQueue()) {
dl_bottom_sheet.sheetBehavior?.expand()
}
}
override fun toggleSheet() {
@ -498,13 +501,15 @@ class RecentsController(bundle: Bundle? = null) :
override fun expandSearch() {
if (showingDownloads) {
dl_bottom_sheet.dismiss()
} else
} else {
activity?.toolbar?.menu?.findItem(R.id.action_search)?.expandActionView()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (showingDownloads)
if (showingDownloads) {
return dl_bottom_sheet.onOptionsItemSelected(item)
}
when (item.itemId) {
R.id.action_group_all, R.id.action_ungroup_all, R.id.action_only_history,
R.id.action_only_updates -> {
@ -516,8 +521,9 @@ class RecentsController(bundle: Bundle? = null) :
else -> 0
}
)
if (item.itemId == R.id.action_only_history)
if (item.itemId == R.id.action_only_history) {
activity?.toast(R.string.press_and_hold_to_reset_history, Toast.LENGTH_LONG)
}
activity?.invalidateOptionsMenu()
}
}

View File

@ -56,8 +56,9 @@ class RecentsPresenter(
downloadManager.addListener(this)
LibraryUpdateService.setListener(this)
if (lastRecents != null) {
if (recentItems.isEmpty())
if (recentItems.isEmpty()) {
recentItems = lastRecents ?: emptyList()
}
lastRecents = null
}
getRecents()
@ -95,14 +96,15 @@ class RecentsPresenter(
}
}
val cReading = if (viewType != 3)
if (query.isEmpty() && viewType != 2)
val cReading = if (viewType != 3) {
if (query.isEmpty() && viewType != 2) {
db.getRecentsWithUnread(cal.time, query, isUngrouped).executeOnIO()
else db.getRecentMangaLimit(
} else db.getRecentMangaLimit(
cal.time,
if (viewType == 2) 200 else 8,
query
).executeOnIO() else emptyList()
).executeOnIO()
} else emptyList()
val rUpdates = when {
viewType == 3 -> db.getRecentChapters(calWeek.time).executeOnIO().map {
MangaChapterHistory(it.manga, it.chapter, HistoryImpl())
@ -113,8 +115,9 @@ class RecentsPresenter(
rUpdates.forEach {
it.history.last_read = it.chapter.date_fetch
}
val nAdditions = if (viewType < 2)
db.getRecentlyAdded(calDay.time, query, isUngrouped).executeOnIO() else emptyList()
val nAdditions = if (viewType < 2) {
db.getRecentlyAdded(calDay.time, query, isUngrouped).executeOnIO()
} else emptyList()
nAdditions.forEach {
it.history.last_read = it.manga.date_added
}
@ -144,10 +147,11 @@ class RecentsPresenter(
Comparator<Pair<MangaChapterHistory, Chapter>> { f1, f2 ->
if (abs(f1.second.date_fetch - f2.second.date_fetch) <=
TimeUnit.HOURS.toMillis(12)
)
) {
f2.second.date_upload.compareTo(f1.second.date_upload)
else
} else {
f2.second.date_fetch.compareTo(f1.second.date_fetch)
}
}
)
.take(4).map {

View File

@ -10,7 +10,6 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.updater.UpdateChecker
import eu.kanade.tachiyomi.data.updater.UpdateResult
import eu.kanade.tachiyomi.data.updater.UpdaterService

View File

@ -46,8 +46,8 @@ inline fun PreferenceGroup.editTextPreference(block: (@DSL EditTextPreference).(
inline fun PreferenceGroup.dropDownPreference(block: (@DSL DropDownPreference).() -> Unit):
DropDownPreference {
return initThenAdd(DropDownPreference(context), block).also(::initDialog)
}
return initThenAdd(DropDownPreference(context), block).also(::initDialog)
}
inline fun PreferenceGroup.listPreference(
activity: Activity?,
@ -55,8 +55,8 @@ inline fun PreferenceGroup.listPreference(
-> Unit
):
ListMatPreference {
return initThenAdd(ListMatPreference(activity, context), block)
}
return initThenAdd(ListMatPreference(activity, context), block)
}
inline fun PreferenceGroup.intListPreference(
activity: Activity?,
@ -66,8 +66,8 @@ inline fun PreferenceGroup.intListPreference(
).() -> Unit
):
IntListMatPreference {
return initThenAdd(IntListMatPreference(activity, context), block)
}
return initThenAdd(IntListMatPreference(activity, context), block)
}
inline fun PreferenceGroup.multiSelectListPreferenceMat(
activity: Activity?,

View File

@ -186,9 +186,7 @@ class SettingsAdvancedController : SettingsController() {
class CleanupDownloadsDialogController() : DialogController() {
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog(activity!!).show {
title(R.string.clean_up_downloaded_chapters)
.listItemsMultiChoice(R.array.clean_up_downloads, disabledIndices = intArrayOf(0), initialSelection = intArrayOf(0, 1, 2)) { dialog, selections, items ->
val deleteRead = selections.contains(1)

Some files were not shown because too many files have changed in this diff Show More