Minor code cleanup

This commit is contained in:
arkon 2020-01-07 19:20:08 -05:00
parent 0d5099f230
commit 5cddb269d6
67 changed files with 184 additions and 184 deletions

View file

@ -22,7 +22,7 @@ import uy.kohesive.injekt.registry.default.DefaultRegistrar
reportType = org.acra.sender.HttpSender.Type.JSON, reportType = org.acra.sender.HttpSender.Type.JSON,
httpMethod = org.acra.sender.HttpSender.Method.PUT, httpMethod = org.acra.sender.HttpSender.Method.PUT,
buildConfigClass = BuildConfig::class, buildConfigClass = BuildConfig::class,
excludeMatchingSharedPreferencesKeys = arrayOf(".*username.*", ".*password.*", ".*token.*") excludeMatchingSharedPreferencesKeys = [".*username.*", ".*password.*", ".*token.*"]
) )
open class App : Application() { open class App : Application() {

View file

@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.util.syncChaptersWithSource
import rx.Observable import rx.Observable
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import kotlin.math.max
class BackupManager(val context: Context, version: Int = CURRENT_VERSION) { class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
@ -204,7 +205,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) { if (options and BACKUP_CHAPTER_MASK == BACKUP_CHAPTER) {
// Backup all the chapters // Backup all the chapters
val chapters = databaseHelper.getChapters(manga).executeAsBlocking() val chapters = databaseHelper.getChapters(manga).executeAsBlocking()
if (!chapters.isEmpty()) { if (chapters.isNotEmpty()) {
val chaptersJson = parser.toJsonTree(chapters) val chaptersJson = parser.toJsonTree(chapters)
if (chaptersJson.asJsonArray.size() > 0) { if (chaptersJson.asJsonArray.size() > 0) {
entry[CHAPTERS] = chaptersJson entry[CHAPTERS] = chaptersJson
@ -216,7 +217,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) { if (options and BACKUP_CATEGORY_MASK == BACKUP_CATEGORY) {
// Backup categories for this manga // Backup categories for this manga
val categoriesForManga = databaseHelper.getCategoriesForManga(manga).executeAsBlocking() val categoriesForManga = databaseHelper.getCategoriesForManga(manga).executeAsBlocking()
if (!categoriesForManga.isEmpty()) { if (categoriesForManga.isNotEmpty()) {
val categoriesNames = categoriesForManga.map { it.name } val categoriesNames = categoriesForManga.map { it.name }
entry[CATEGORIES] = parser.toJsonTree(categoriesNames) entry[CATEGORIES] = parser.toJsonTree(categoriesNames)
} }
@ -225,7 +226,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
// Check if user wants track information in backup // Check if user wants track information in backup
if (options and BACKUP_TRACK_MASK == BACKUP_TRACK) { if (options and BACKUP_TRACK_MASK == BACKUP_TRACK) {
val tracks = databaseHelper.getTracks(manga).executeAsBlocking() val tracks = databaseHelper.getTracks(manga).executeAsBlocking()
if (!tracks.isEmpty()) { if (tracks.isNotEmpty()) {
entry[TRACK] = parser.toJsonTree(tracks) entry[TRACK] = parser.toJsonTree(tracks)
} }
} }
@ -233,7 +234,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
// Check if user wants history information in backup // Check if user wants history information in backup
if (options and BACKUP_HISTORY_MASK == BACKUP_HISTORY) { if (options and BACKUP_HISTORY_MASK == BACKUP_HISTORY) {
val historyForManga = databaseHelper.getHistoryByMangaId(manga.id!!).executeAsBlocking() val historyForManga = databaseHelper.getHistoryByMangaId(manga.id!!).executeAsBlocking()
if (!historyForManga.isEmpty()) { if (historyForManga.isNotEmpty()) {
val historyData = historyForManga.mapNotNull { history -> val historyData = historyForManga.mapNotNull { history ->
val url = databaseHelper.getChapter(history.chapter_id).executeAsBlocking()?.url val url = databaseHelper.getChapter(history.chapter_id).executeAsBlocking()?.url
url?.let { DHistory(url, history.last_read) } url?.let { DHistory(url, history.last_read) }
@ -344,7 +345,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
} }
// Update database // Update database
if (!mangaCategoriesToUpdate.isEmpty()) { if (mangaCategoriesToUpdate.isNotEmpty()) {
val mangaAsList = ArrayList<Manga>() val mangaAsList = ArrayList<Manga>()
mangaAsList.add(manga) mangaAsList.add(manga)
databaseHelper.deleteOldMangasCategories(mangaAsList).executeAsBlocking() databaseHelper.deleteOldMangasCategories(mangaAsList).executeAsBlocking()
@ -365,7 +366,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
// Check if history already in database and update // Check if history already in database and update
if (dbHistory != null) { if (dbHistory != null) {
dbHistory.apply { dbHistory.apply {
last_read = Math.max(lastRead, dbHistory.last_read) last_read = max(lastRead, dbHistory.last_read)
} }
historyToBeUpdated.add(dbHistory) historyToBeUpdated.add(dbHistory)
} else { } else {
@ -408,7 +409,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
if (track.library_id != dbTrack.library_id) { if (track.library_id != dbTrack.library_id) {
dbTrack.library_id = track.library_id dbTrack.library_id = track.library_id
} }
dbTrack.last_chapter_read = Math.max(dbTrack.last_chapter_read, track.last_chapter_read) dbTrack.last_chapter_read = max(dbTrack.last_chapter_read, track.last_chapter_read)
isInDatabase = true isInDatabase = true
trackToUpdate.add(dbTrack) trackToUpdate.add(dbTrack)
break break
@ -422,7 +423,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
} }
} }
// Update database // Update database
if (!trackToUpdate.isEmpty()) { if (trackToUpdate.isNotEmpty()) {
databaseHelper.insertTracks(trackToUpdate).executeAsBlocking() databaseHelper.insertTracks(trackToUpdate).executeAsBlocking()
} }
} }

View file

@ -43,9 +43,7 @@ object ChapterTypeAdapter {
beginObject() beginObject()
while (hasNext()) { while (hasNext()) {
if (peek() == JsonToken.NAME) { if (peek() == JsonToken.NAME) {
val name = nextName() when (nextName()) {
when (name) {
URL -> chapter.url = nextString() URL -> chapter.url = nextString()
READ -> chapter.read = nextInt() == 1 READ -> chapter.read = nextInt() == 1
BOOKMARK -> chapter.bookmark = nextInt() == 1 BOOKMARK -> chapter.bookmark = nextInt() == 1

View file

@ -42,9 +42,7 @@ object TrackTypeAdapter {
beginObject() beginObject()
while (hasNext()) { while (hasNext()) {
if (peek() == JsonToken.NAME) { if (peek() == JsonToken.NAME) {
val name = nextName() when (nextName()) {
when (name) {
TITLE -> track.title = nextString() TITLE -> track.title = nextString()
SYNC -> track.sync_id = nextInt() SYNC -> track.sync_id = nextInt()
MEDIA -> track.media_id = nextInt() MEDIA -> track.media_id = nextInt()

View file

@ -263,7 +263,7 @@ class DownloadCache(
for (element in this) { for (element in this) {
val (key, value) = transform(element) val (key, value) = transform(element)
if (key != null) { if (key != null) {
destination.put(key, value) destination[key] = value
} }
} }
return destination return destination

View file

@ -57,8 +57,8 @@ abstract class TrackService(val id: Int) {
} }
open val isLogged: Boolean open val isLogged: Boolean
get() = !getUsername().isEmpty() && get() = getUsername().isNotEmpty() &&
!getPassword().isEmpty() getPassword().isNotEmpty()
fun getUsername() = preferences.trackUsername(this)!! fun getUsername() = preferences.trackUsername(this)!!

View file

@ -16,6 +16,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import rx.Observable import rx.Observable
import java.util.Calendar import java.util.Calendar
@ -44,7 +45,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
"query" to query, "query" to query,
"variables" to variables "variables" to variables
) )
val body = RequestBody.create(jsonMime, payload.toString()) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
.post(body) .post(body)
@ -83,7 +84,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
"query" to query, "query" to query,
"variables" to variables "variables" to variables
) )
val body = RequestBody.create(jsonMime, payload.toString()) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
.post(body) .post(body)
@ -127,7 +128,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
"query" to query, "query" to query,
"variables" to variables "variables" to variables
) )
val body = RequestBody.create(jsonMime, payload.toString()) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
.post(body) .post(body)
@ -188,7 +189,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
"query" to query, "query" to query,
"variables" to variables "variables" to variables
) )
val body = RequestBody.create(jsonMime, payload.toString()) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
.post(body) .post(body)
@ -233,7 +234,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
val payload = jsonObject( val payload = jsonObject(
"query" to query "query" to query
) )
val body = RequestBody.create(jsonMime, payload.toString()) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
.post(body) .post(body)

View file

@ -35,7 +35,7 @@ class BangumiInterceptor(val bangumi: Bangumi, val gson: Gson) : Interceptor {
} }
} }
var authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder() val authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder()
.header("User-Agent", "Tachiyomi") .header("User-Agent", "Tachiyomi")
.url(originalRequest.url.newBuilder() .url(originalRequest.url.newBuilder()
.addQueryParameter("access_token", currAuth.access_token).build()) .addQueryParameter("access_token", currAuth.access_token).build())

View file

@ -9,7 +9,7 @@ data class OAuth(
val user_id: Long? val user_id: Long?
) { ) {
// Access token refersh before expired // Access token refresh before expired
fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600) fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
} }

View file

@ -29,7 +29,7 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) {
} }
private val interceptor by lazy { MyAnimeListInterceptor(this) } private val interceptor by lazy { MyAnimeListInterceptor(this) }
private val api by lazy { MyanimelistApi(client, interceptor) } private val api by lazy { MyAnimeListApi(client, interceptor) }
override val name: String override val name: String
get() = "MyAnimeList" get() = "MyAnimeList"

View file

@ -14,6 +14,7 @@ import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.Jsoup import org.jsoup.Jsoup
@ -26,7 +27,7 @@ import java.io.InputStreamReader
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListInterceptor) { class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListInterceptor) {
private val authClient = client.newBuilder().addInterceptor(interceptor).build() private val authClient = client.newBuilder().addInterceptor(interceptor).build()
@ -37,8 +38,7 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.flatMap { Observable.from(it) } .flatMap { Observable.from(it) }
.filter { it.title.contains(realQuery, true) } .filter { it.title.contains(realQuery, true) }
.toList() .toList()
} } else {
else {
client.newCall(GET(searchUrl(query))) client.newCall(GET(searchUrl(query)))
.asObservable() .asObservable()
.flatMap { response -> .flatMap { response ->
@ -266,7 +266,7 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.put("score", track.score) .put("score", track.score)
.put("num_read_chapters", track.last_chapter_read) .put("num_read_chapters", track.last_chapter_read)
return RequestBody.create("application/json; charset=utf-8".toMediaTypeOrNull(), body.toString()) return body.toString().toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
} }
private fun Element.searchTitle() = select("strong").text()!! private fun Element.searchTitle() = select("strong").text()!!

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.track.myanimelist
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import okio.Buffer import okio.Buffer
import org.json.JSONObject import org.json.JSONObject
@ -45,15 +46,14 @@ class MyAnimeListInterceptor(private val myanimelist: Myanimelist): Interceptor
private fun updateFormBody(requestBody: RequestBody): RequestBody { private fun updateFormBody(requestBody: RequestBody): RequestBody {
val formString = bodyToString(requestBody) val formString = bodyToString(requestBody)
return RequestBody.create(requestBody.contentType(), return "$formString${if (formString.isNotEmpty()) "&" else ""}${MyAnimeListApi.CSRF}=${myanimelist.getCSRF()}".toRequestBody(requestBody.contentType())
"$formString${if (formString.isNotEmpty()) "&" else ""}${MyanimelistApi.CSRF}=${myanimelist.getCSRF()}")
} }
private fun updateJsonBody(requestBody: RequestBody): RequestBody { private fun updateJsonBody(requestBody: RequestBody): RequestBody {
val jsonString = bodyToString(requestBody) val jsonString = bodyToString(requestBody)
val newBody = JSONObject(jsonString) val newBody = JSONObject(jsonString)
.put(MyanimelistApi.CSRF, myanimelist.getCSRF()) .put(MyAnimeListApi.CSRF, myanimelist.getCSRF())
return RequestBody.create(requestBody.contentType(), newBody.toString()) return newBody.toString().toRequestBody(requestBody.contentType())
} }
} }

View file

@ -19,6 +19,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import rx.Observable import rx.Observable
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -40,7 +41,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
"status" to track.toShikimoriStatus() "status" to track.toShikimoriStatus()
) )
) )
val body = RequestBody.create(jsonime, payload.toString()) val body = payload.toString().toRequestBody(jsonime)
val request = Request.Builder() val request = Request.Builder()
.url("$apiUrl/v2/user_rates") .url("$apiUrl/v2/user_rates")
.post(body) .post(body)

View file

@ -94,7 +94,7 @@ internal class ExtensionInstallReceiver(private val listener: Listener) :
private suspend fun getExtensionFromIntent(context: Context, intent: Intent?): LoadResult { private suspend fun getExtensionFromIntent(context: Context, intent: Intent?): LoadResult {
val pkgName = getPackageNameFromIntent(intent) ?: val pkgName = getPackageNameFromIntent(intent) ?:
return LoadResult.Error("Package name not found") return LoadResult.Error("Package name not found")
return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT, { ExtensionLoader.loadExtensionFromPkgName(context, pkgName) }).await() return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT) { ExtensionLoader.loadExtensionFromPkgName(context, pkgName) }.await()
} }
/** /**

View file

@ -173,7 +173,7 @@ internal object ExtensionLoader {
*/ */
private fun getSignatureHash(pkgInfo: PackageInfo): String? { private fun getSignatureHash(pkgInfo: PackageInfo): String? {
val signatures = pkgInfo.signatures val signatures = pkgInfo.signatures
return if (signatures != null && !signatures.isEmpty()) { return if (signatures != null && signatures.isNotEmpty()) {
Hash.sha256(signatures.first().toByteArray()) Hash.sha256(signatures.first().toByteArray())
} else { } else {
null null

View file

@ -37,7 +37,6 @@ open class Page(
} }
companion object { companion object {
const val QUEUE = 0 const val QUEUE = 0
const val LOAD_PAGE = 1 const val LOAD_PAGE = 1
const val DOWNLOAD_IMAGE = 2 const val DOWNLOAD_IMAGE = 2

View file

@ -363,7 +363,7 @@ open class BrowseCataloguePresenter(
* @param selectedCategories selected categories * @param selectedCategories selected categories
*/ */
fun updateMangaCategories(manga: Manga, selectedCategories: List<Category>) { fun updateMangaCategories(manga: Manga, selectedCategories: List<Category>) {
if (!selectedCategories.isEmpty()) { if (selectedCategories.isNotEmpty()) {
if (!manga.favorite) if (!manga.favorite)
changeMangaFavorite(manga) changeMangaFavorite(manga)

View file

@ -24,7 +24,7 @@ abstract class Pager(var currentPage: Int = 1) {
fun onPageReceived(mangasPage: MangasPage) { fun onPageReceived(mangasPage: MangasPage) {
val page = currentPage val page = currentPage
currentPage++ currentPage++
hasNextPage = mangasPage.hasNextPage && !mangasPage.mangas.isEmpty() hasNextPage = mangasPage.hasNextPage && mangasPage.mangas.isNotEmpty()
results.call(Pair(page, mangasPage.mangas)) results.call(Pair(page, mangasPage.mangas))
} }

View file

@ -205,7 +205,6 @@ open class CatalogueSearchPresenter(
.map { Pair(source as CatalogueSource, it) } .map { Pair(source as CatalogueSource, it) }
} }
.onBackpressureBuffer() .onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ (source, manga) -> .subscribe({ (source, manga) ->

View file

@ -207,11 +207,11 @@ class CategoryController : NucleusController<CategoryPresenter>(),
*/ */
override fun onItemClick(view: View, position: Int): Boolean { override fun onItemClick(view: View, position: Int): Boolean {
// Check if action mode is initialized and selected item exist. // Check if action mode is initialized and selected item exist.
if (actionMode != null && position != RecyclerView.NO_POSITION) { return if (actionMode != null && position != RecyclerView.NO_POSITION) {
toggleSelection(position) toggleSelection(position)
return true true
} else { } else {
return false false
} }
} }

View file

@ -33,9 +33,9 @@ class CategoryCreateDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
.title(R.string.action_add_category) .title(R.string.action_add_category)
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)
.alwaysCallInputCallback() .alwaysCallInputCallback()
.input(resources?.getString(R.string.name), currentName, false, { _, input -> .input(resources?.getString(R.string.name), currentName, false) { _, input ->
currentName = input.toString() currentName = input.toString()
}) }
.onPositive { _, _ -> (targetController as? Listener)?.createCategory(currentName) } .onPositive { _, _ -> (targetController as? Listener)?.createCategory(currentName) }
.build() .build()
} }

View file

@ -38,9 +38,9 @@ class CategoryRenameDialog<T>(bundle: Bundle? = null) : DialogController(bundle)
.title(R.string.action_rename_category) .title(R.string.action_rename_category)
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)
.alwaysCallInputCallback() .alwaysCallInputCallback()
.input(resources!!.getString(R.string.name), currentName, false, { _, input -> .input(resources!!.getString(R.string.name), currentName, false) { _, input ->
currentName = input.toString() currentName = input.toString()
}) }
.onPositive { _, _ -> onPositive() } .onPositive { _, _ -> onPositive() }
.build() .build()
} }

View file

@ -33,9 +33,9 @@ class DownloadPresenter : BasePresenter<DownloadController>() {
downloadQueue.getUpdatedObservable() downloadQueue.getUpdatedObservable()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.map { ArrayList(it) } .map { ArrayList(it) }
.subscribeLatestCache(DownloadController::onNextDownloads, { _, error -> .subscribeLatestCache(DownloadController::onNextDownloads) { _, error ->
Timber.e(error) Timber.e(error)
}) }
} }
fun getDownloadStatusObservable(): Observable<Download> { fun getDownloadStatusObservable(): Observable<Download> {

View file

@ -99,7 +99,7 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
val searchView = searchItem.actionView as SearchView val searchView = searchItem.actionView as SearchView
searchView.maxWidth = Int.MAX_VALUE searchView.maxWidth = Int.MAX_VALUE
if (!query.isEmpty()) { if (query.isNotEmpty()) {
searchItem.expandActionView() searchItem.expandActionView()
searchView.setQuery(query, true) searchView.setQuery(query, true)
searchView.clearFocus() searchView.clearFocus()

View file

@ -178,7 +178,7 @@ class LibraryController(
override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup { override fun createSecondaryDrawer(drawer: DrawerLayout): ViewGroup {
val view = drawer.inflate(R.layout.library_drawer) as LibraryNavigationView val view = drawer.inflate(R.layout.library_drawer) as LibraryNavigationView
navView = view navView = view
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END) drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, GravityCompat.END)
navView?.onGroupClicked = { group -> navView?.onGroupClicked = { group ->
when (group) { when (group) {

View file

@ -209,7 +209,7 @@ class LibraryNavigationView @JvmOverloads constructor(context: Context, attrs: A
item.group.items.forEach { (it as Item.Radio).checked = false } item.group.items.forEach { (it as Item.Radio).checked = false }
item.checked = true item.checked = true
preferences.libraryAsList().set(if (item == list) true else false) preferences.libraryAsList().set(item == list)
item.group.items.forEach { adapter.notifyItemChanged(it) } item.group.items.forEach { adapter.notifyItemChanged(it) }
} }

View file

@ -89,12 +89,15 @@ class LibraryPresenter(
fun subscribeLibrary() { fun subscribeLibrary() {
if (librarySubscription.isNullOrUnsubscribed()) { if (librarySubscription.isNullOrUnsubscribed()) {
librarySubscription = getLibraryObservable() librarySubscription = getLibraryObservable()
.combineLatest(downloadTriggerRelay.observeOn(Schedulers.io()), .combineLatest(downloadTriggerRelay.observeOn(Schedulers.io())) {
{ lib, _ -> lib.apply { setDownloadCount(mangaMap) } }) lib, _ -> lib.apply { setDownloadCount(mangaMap) }
.combineLatest(filterTriggerRelay.observeOn(Schedulers.io()), }
{ lib, _ -> lib.copy(mangaMap = applyFilters(lib.mangaMap)) }) .combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) {
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io()), lib, _ -> lib.copy(mangaMap = applyFilters(lib.mangaMap))
{ lib, _ -> lib.copy(mangaMap = applySort(lib.mangaMap)) }) }
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) {
lib, _ -> lib.copy(mangaMap = applySort(lib.mangaMap))
}
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache({ view, (categories, mangaMap) -> .subscribeLatestCache({ view, (categories, mangaMap) ->
view.onNextLibraryUpdate(categories, mangaMap) view.onNextLibraryUpdate(categories, mangaMap)
@ -222,8 +225,8 @@ class LibraryPresenter(
* @return an observable of the categories and its manga. * @return an observable of the categories and its manga.
*/ */
private fun getLibraryObservable(): Observable<Library> { private fun getLibraryObservable(): Observable<Library> {
return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable(), return Observable.combineLatest(getCategoriesObservable(), getLibraryMangasObservable()) {
{ dbCategories, libraryManga -> dbCategories, libraryManga ->
val categories = if (libraryManga.containsKey(0)) val categories = if (libraryManga.containsKey(0))
arrayListOf(Category.createDefault()) + dbCategories arrayListOf(Category.createDefault()) + dbCategories
else else
@ -231,7 +234,7 @@ class LibraryPresenter(
this.categories = categories this.categories = categories
Library(categories, libraryManga) Library(categories, libraryManga)
}) }
} }
/** /**

View file

@ -12,7 +12,7 @@ import it.gmariotti.changelibs.library.view.ChangeLogRecyclerView
class ChangelogDialogController : DialogController() { class ChangelogDialogController : DialogController() {
override fun onCreateDialog(savedState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val activity = activity!! val activity = activity!!
val view = WhatsNewRecyclerView(activity) val view = WhatsNewRecyclerView(activity)
return MaterialDialog.Builder(activity) return MaterialDialog.Builder(activity)

View file

@ -170,7 +170,7 @@ class MainActivity : BaseActivity() {
//Get the search query provided in extras, and if not null, perform a global search with it. //Get the search query provided in extras, and if not null, perform a global search with it.
val query = intent.getStringExtra(SearchManager.QUERY) val query = intent.getStringExtra(SearchManager.QUERY)
if (query != null && !query.isEmpty()) { if (query != null && query.isNotEmpty()) {
if (router.backstackSize > 1) { if (router.backstackSize > 1) {
router.popToRoot() router.popToRoot()
} }
@ -180,7 +180,7 @@ class MainActivity : BaseActivity() {
INTENT_SEARCH -> { INTENT_SEARCH -> {
val query = intent.getStringExtra(INTENT_SEARCH_QUERY) val query = intent.getStringExtra(INTENT_SEARCH_QUERY)
val filter = intent.getStringExtra(INTENT_SEARCH_FILTER) val filter = intent.getStringExtra(INTENT_SEARCH_FILTER)
if (query != null && !query.isEmpty()) { if (query != null && query.isNotEmpty()) {
if (router.backstackSize > 1) { if (router.backstackSize > 1) {
router.popToRoot() router.popToRoot()
} }

View file

@ -109,8 +109,9 @@ class ChaptersPresenter(
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.filter { download -> download.manga.id == manga.id } .filter { download -> download.manga.id == manga.id }
.doOnNext { onDownloadStatusChange(it) } .doOnNext { onDownloadStatusChange(it) }
.subscribeLatestCache(ChaptersController::onChapterStatusChange, .subscribeLatestCache(ChaptersController::onChapterStatusChange) {
{ _, error -> Timber.e(error) }) _, error -> Timber.e(error)
}
} }
/** /**

View file

@ -13,7 +13,7 @@ class DeletingChaptersDialog(bundle: Bundle? = null) : DialogController(bundle)
const val TAG = "deleting_dialog" const val TAG = "deleting_dialog"
} }
override fun onCreateDialog(savedState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog.Builder(activity!!) return MaterialDialog.Builder(activity!!)
.progress(true, 0) .progress(true, 0)
.content(R.string.deleting) .content(R.string.deleting)

View file

@ -195,11 +195,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
} }
// If manga source is known update source TextView. // If manga source is known update source TextView.
manga_source.text = if (source == null) { manga_source.text = source?.toString() ?: view.context.getString(R.string.unknown)
view.context.getString(R.string.unknown)
} else {
source.toString()
}
// Update genres list // Update genres list
if (manga.genre.isNullOrBlank().not()) { if (manga.genre.isNullOrBlank().not()) {

View file

@ -32,7 +32,7 @@ class SetTrackStatusDialog<T> : DialogController
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val item = item val item = item
val statusList = item.service.getStatusList().orEmpty() val statusList = item.service.getStatusList()
val statusString = statusList.mapNotNull { item.service.getStatus(it) } val statusString = statusList.mapNotNull { item.service.getStatus(it) }
val selectedIndex = statusList.indexOf(item.track?.status) val selectedIndex = statusList.indexOf(item.track?.status)
@ -40,10 +40,10 @@ class SetTrackStatusDialog<T> : DialogController
.title(R.string.status) .title(R.string.status)
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)
.items(statusString) .items(statusString)
.itemsCallbackSingleChoice(selectedIndex, { _, _, i, _ -> .itemsCallbackSingleChoice(selectedIndex) { _, _, i, _ ->
(targetController as? Listener)?.setStatus(item, i) (targetController as? Listener)?.setStatus(item, i)
true true
}) }
.build() .build()
} }

View file

@ -25,7 +25,7 @@ class TrackHolder(view: View, adapter: TrackAdapter) : BaseViewHolder(view) {
logo_container.setBackgroundColor(item.service.getLogoColor()) logo_container.setBackgroundColor(item.service.getLogoColor())
if (track != null) { if (track != null) {
track_title.setTextAppearance(itemView.context, R.style.TextAppearance_Regular_Body1_Secondary) track_title.setTextAppearance(itemView.context, R.style.TextAppearance_Regular_Body1_Secondary)
track_title.setAllCaps(false) track_title.isAllCaps = false
track_title.text = track.title track_title.text = track.title
track_chapters.text = "${track.last_chapter_read}/" + track_chapters.text = "${track.last_chapter_read}/" +
if (track.total_chapters > 0) track.total_chapters else "-" if (track.total_chapters > 0) track.total_chapters else "-"

View file

@ -50,7 +50,7 @@ class TrackSearchDialog : DialogController {
service = Injekt.get<TrackManager>().getService(bundle.getInt(KEY_SERVICE))!! service = Injekt.get<TrackManager>().getService(bundle.getInt(KEY_SERVICE))!!
} }
override fun onCreateDialog(savedState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val dialog = MaterialDialog.Builder(activity!!) val dialog = MaterialDialog.Builder(activity!!)
.customView(R.layout.track_search_dialog, false) .customView(R.layout.track_search_dialog, false)
.positiveText(android.R.string.ok) .positiveText(android.R.string.ok)
@ -63,7 +63,7 @@ class TrackSearchDialog : DialogController {
} }
dialogView = dialog.view dialogView = dialog.view
onViewCreated(dialog.view, savedState) onViewCreated(dialog.view, savedViewState)
return dialog return dialog
} }

View file

@ -42,8 +42,8 @@ class MigrationPresenter(
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnNext { state = state.copy(sourcesWithManga = findSourcesWithManga(it)) } .doOnNext { state = state.copy(sourcesWithManga = findSourcesWithManga(it)) }
.combineLatest(stateRelay.map { it.selectedSource } .combineLatest(stateRelay.map { it.selectedSource }
.distinctUntilChanged(), .distinctUntilChanged()
{ library, source -> library to source }) ) { library, source -> library to source }
.filter { (_, source) -> source != null } .filter { (_, source) -> source != null }
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.map { (library, source) -> libraryToMigrationItem(library, source!!.id) } .map { (library, source) -> libraryToMigrationItem(library, source!!.id) }

View file

@ -77,13 +77,13 @@ class SearchController(
.content(R.string.migration_dialog_what_to_include) .content(R.string.migration_dialog_what_to_include)
.items(MigrationFlags.titles.map { resources?.getString(it) }) .items(MigrationFlags.titles.map { resources?.getString(it) })
.alwaysCallMultiChoiceCallback() .alwaysCallMultiChoiceCallback()
.itemsCallbackMultiChoice(preselected.toTypedArray(), { _, positions, _ -> .itemsCallbackMultiChoice(preselected.toTypedArray()) { _, positions, _ ->
// Save current settings for the next time // Save current settings for the next time
val newValue = MigrationFlags.getFlagsFromPositions(positions) val newValue = MigrationFlags.getFlagsFromPositions(positions)
preferences.migrateFlags().set(newValue) preferences.migrateFlags().set(newValue)
true true
}) }
.positiveText(R.string.migrate) .positiveText(R.string.migrate)
.negativeText(R.string.copy) .negativeText(R.string.copy)
.neutralText(android.R.string.cancel) .neutralText(android.R.string.cancel)

View file

@ -43,6 +43,7 @@ import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.abs
/** /**
* Activity containing the reader of Tachiyomi. This activity is mostly a container of the * Activity containing the reader of Tachiyomi. This activity is mostly a container of the
@ -692,18 +693,22 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
*/ */
private fun setCustomBrightnessValue(value: Int) { private fun setCustomBrightnessValue(value: Int) {
// Calculate and set reader brightness. // Calculate and set reader brightness.
val readerBrightness = if (value > 0) { val readerBrightness = when {
value > 0 -> {
value / 100f value / 100f
} else if (value < 0) { }
value < 0 -> {
0.01f 0.01f
} else WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE }
else -> WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
}
window.attributes = window.attributes.apply { screenBrightness = readerBrightness } window.attributes = window.attributes.apply { screenBrightness = readerBrightness }
// Set black overlay visibility. // Set black overlay visibility.
if (value < 0) { if (value < 0) {
brightness_overlay.visibility = View.VISIBLE brightness_overlay.visibility = View.VISIBLE
val alpha = (Math.abs(value) * 2.56).toInt() val alpha = (abs(value) * 2.56).toInt()
brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0)) brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
} else { } else {
brightness_overlay.visibility = View.GONE brightness_overlay.visibility = View.GONE

View file

@ -1,12 +1,12 @@
package eu.kanade.tachiyomi.ui.reader package eu.kanade.tachiyomi.ui.reader
import android.graphics.Color import android.graphics.Color
import androidx.annotation.ColorInt
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.SeekBar import android.widget.SeekBar
import androidx.annotation.ColorInt
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
@ -14,12 +14,14 @@ import eu.kanade.tachiyomi.util.plusAssign
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
import kotlinx.android.synthetic.main.reader_color_filter.* import kotlinx.android.synthetic.main.reader_color_filter.*
import kotlinx.android.synthetic.main.reader_color_filter_sheet.* import kotlinx.android.synthetic.main.reader_color_filter_sheet.brightness_overlay
import kotlinx.android.synthetic.main.reader_color_filter_sheet.color_overlay
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.abs
/** /**
* Color filter sheet to toggle custom filter and brightness overlay. * Color filter sheet to toggle custom filter and brightness overlay.
@ -221,7 +223,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
// Set black overlay visibility. // Set black overlay visibility.
if (value < 0) { if (value < 0) {
brightness_overlay.visibility = View.VISIBLE brightness_overlay.visibility = View.VISIBLE
val alpha = (Math.abs(value) * 2.56).toInt() val alpha = (abs(value) * 2.56).toInt()
brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0)) brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
} else { } else {
brightness_overlay.visibility = View.GONE brightness_overlay.visibility = View.GONE

View file

@ -13,7 +13,7 @@ class ReaderColorFilterView(
private val colorFilterPaint: Paint = Paint() private val colorFilterPaint: Paint = Paint()
fun setFilterColor(color: Int, filterMode: Int) { fun setFilterColor(color: Int, filterMode: Int) {
colorFilterPaint.setColor(color) colorFilterPaint.color = color
colorFilterPaint.xfermode = PorterDuffXfermode(when (filterMode) { colorFilterPaint.xfermode = PorterDuffXfermode(when (filterMode) {
1 -> PorterDuff.Mode.MULTIPLY 1 -> PorterDuff.Mode.MULTIPLY
2 -> PorterDuff.Mode.SCREEN 2 -> PorterDuff.Mode.SCREEN

View file

@ -90,7 +90,7 @@ class ReaderPresenter(
val chaptersForReader = val chaptersForReader =
if (preferences.skipRead()) { if (preferences.skipRead()) {
var list = dbChapters.filter { it -> !it.read }.toMutableList() val list = dbChapters.filter { !it.read }.toMutableList()
val find = list.find { it.id == chapterId } val find = list.find { it.id == chapterId }
if (find == null) { if (find == null) {
list.add(selectedChapter) list.add(selectedChapter)

View file

@ -57,8 +57,9 @@ class SaveImageNotifier(private val context: Context) {
setStyle(NotificationCompat.BigPictureStyle().bigPicture(image)) setStyle(NotificationCompat.BigPictureStyle().bigPicture(image))
setLargeIcon(image) setLargeIcon(image)
setAutoCancel(true) setAutoCancel(true)
// Clear old actions if they exist // Clear old actions if they exist
if (!mActions.isEmpty()) if (mActions.isNotEmpty())
mActions.clear() mActions.clear()
setContentIntent(NotificationHandler.openImagePendingActivity(context, file)) setContentIntent(NotificationHandler.openImagePendingActivity(context, file))
@ -70,8 +71,8 @@ class SaveImageNotifier(private val context: Context) {
addAction(R.drawable.ic_delete_grey_24dp, addAction(R.drawable.ic_delete_grey_24dp,
context.getString(R.string.action_delete), context.getString(R.string.action_delete),
NotificationReceiver.deleteImagePendingBroadcast(context, file.absolutePath, notificationId)) NotificationReceiver.deleteImagePendingBroadcast(context, file.absolutePath, notificationId))
updateNotification()
updateNotification()
} }
} }
@ -87,7 +88,6 @@ class SaveImageNotifier(private val context: Context) {
context.notificationManager.notify(notificationId, notificationBuilder.build()) context.notificationManager.notify(notificationId, notificationBuilder.build())
} }
/** /**
* Called on error while downloading image. * Called on error while downloading image.
* @param error string containing error information. * @param error string containing error information.

View file

@ -12,20 +12,6 @@ sealed class ChapterTransition {
override val from: ReaderChapter, override val to: ReaderChapter? override val from: ReaderChapter, override val to: ReaderChapter?
) : ChapterTransition() ) : ChapterTransition()
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ChapterTransition) return false
if (from == other.from && to == other.to) return true
if (from == other.to && to == other.from) return true
return false
}
override fun hashCode(): Int {
var result = from.hashCode()
result = 31 * result + (to?.hashCode() ?: 0)
return result
}
override fun toString(): String { override fun toString(): String {
return "${javaClass.simpleName}(from=${from.chapter.url}, to=${to?.chapter?.url})" return "${javaClass.simpleName}(from=${from.chapter.url}, to=${to?.chapter?.url})"
} }

View file

@ -5,6 +5,7 @@ import android.os.Handler
import android.view.GestureDetector import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
import android.view.ViewConfiguration import android.view.ViewConfiguration
import kotlin.math.abs
/** /**
* A custom gesture detector that also implements an on long tap confirmed, because the built-in * A custom gesture detector that also implements an on long tap confirmed, because the built-in
@ -45,7 +46,7 @@ open class GestureDetectorWithLongTap(
} }
} }
MotionEvent.ACTION_MOVE -> { MotionEvent.ACTION_MOVE -> {
if (Math.abs(ev.rawX - downX) > slop || Math.abs(ev.rawY - downY) > slop) { if (abs(ev.rawX - downX) > slop || abs(ev.rawY - downY) > slop) {
handler.removeCallbacks(longTapFn) handler.removeCallbacks(longTapFn)
} }
} }

View file

@ -16,6 +16,7 @@ import android.view.animation.LinearInterpolator
import android.view.animation.RotateAnimation import android.view.animation.RotateAnimation
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.getResourceColor import eu.kanade.tachiyomi.util.getResourceColor
import kotlin.math.min
/** /**
* A custom progress bar that always rotates while being determinate. By always rotating we give * A custom progress bar that always rotates while being determinate. By always rotating we give
@ -75,7 +76,7 @@ class ReaderProgressBar @JvmOverloads constructor(
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom) super.onLayout(changed, left, top, right, bottom)
val diameter = Math.min(width, height) val diameter = min(width, height)
val thickness = diameter / 10f val thickness = diameter / 10f
val pad = thickness / 2f val pad = thickness / 2f
ovalRect.set(pad, pad, diameter - pad, diameter - pad) ovalRect.set(pad, pad, diameter - pad, diameter - pad)

View file

@ -12,6 +12,7 @@ import android.view.animation.DecelerateInterpolator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.ui.reader.viewer.GestureDetectorWithLongTap import eu.kanade.tachiyomi.ui.reader.viewer.GestureDetectorWithLongTap
import kotlin.math.abs
/** /**
* Implementation of a [RecyclerView] used by the webtoon reader. * Implementation of a [RecyclerView] used by the webtoon reader.
@ -267,7 +268,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
if (!isZoomDragging && currentScale > 1f) { if (!isZoomDragging && currentScale > 1f) {
var startScroll = false var startScroll = false
if (Math.abs(dx) > touchSlop) { if (abs(dx) > touchSlop) {
if (dx < 0) { if (dx < 0) {
dx += touchSlop dx += touchSlop
} else { } else {
@ -275,7 +276,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
} }
startScroll = true startScroll = true
} }
if (Math.abs(dy) > touchSlop) { if (abs(dy) > touchSlop) {
if (dy < 0) { if (dy < 0) {
dy += touchSlop dy += touchSlop
} else { } else {

View file

@ -13,7 +13,7 @@ class DeletingChaptersDialog(bundle: Bundle? = null) : DialogController(bundle)
const val TAG = "deleting_dialog" const val TAG = "deleting_dialog"
} }
override fun onCreateDialog(savedState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog.Builder(activity!!) return MaterialDialog.Builder(activity!!)
.progress(true, 0) .progress(true, 0)
.content(R.string.deleting) .content(R.string.deleting)

View file

@ -38,8 +38,9 @@ class RecentChaptersPresenter(
.subscribeLatestCache(RecentChaptersController::onNextRecentChapters) .subscribeLatestCache(RecentChaptersController::onNextRecentChapters)
getChapterStatusObservable() getChapterStatusObservable()
.subscribeLatestCache(RecentChaptersController::onChapterStatusChange, .subscribeLatestCache(RecentChaptersController::onChapterStatusChange) {
{ _, error -> Timber.e(error) }) _, error -> Timber.e(error)
}
} }
/** /**

View file

@ -31,7 +31,7 @@ class AnilistLoginActivity : AppCompatActivity() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
returnToSettings() returnToSettings()
}, { _ -> }, {
returnToSettings() returnToSettings()
}) })
} else { } else {

View file

@ -61,14 +61,16 @@ inline fun <P : Preference> PreferenceGroup.initThenAdd(p: P, block: P.() -> Uni
return p.apply { return p.apply {
block() block()
this.isIconSpaceReserved = false this.isIconSpaceReserved = false
addPreference(this) } addPreference(this)
}
} }
inline fun <P : Preference> PreferenceGroup.addThenInit(p: P, block: P.() -> Unit): P { inline fun <P : Preference> PreferenceGroup.addThenInit(p: P, block: P.() -> Unit): P {
return p.apply { return p.apply {
this.isIconSpaceReserved = false this.isIconSpaceReserved = false
addPreference(this) addPreference(this)
block() } block()
}
} }
inline fun Preference.onClick(crossinline block: () -> Unit) { inline fun Preference.onClick(crossinline block: () -> Unit) {

View file

@ -206,7 +206,7 @@ class SettingsBackupController : SettingsController() {
.content(R.string.backup_choice) .content(R.string.backup_choice)
.items(options) .items(options)
.itemsDisabledIndices(0) .itemsDisabledIndices(0)
.itemsCallbackMultiChoice(arrayOf(0, 1, 2, 3, 4), { _, positions, _ -> .itemsCallbackMultiChoice(arrayOf(0, 1, 2, 3, 4)) { _, positions, _ ->
var flags = 0 var flags = 0
for (i in 1 until positions.size) { for (i in 1 until positions.size) {
when (positions[i]) { when (positions[i]) {
@ -219,7 +219,7 @@ class SettingsBackupController : SettingsController() {
(targetController as? SettingsBackupController)?.createBackup(flags) (targetController as? SettingsBackupController)?.createBackup(flags)
true true
}) }
.positiveText(R.string.action_create) .positiveText(R.string.action_create)
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)
.build() .build()

View file

@ -147,7 +147,7 @@ class SettingsDownloadController : SettingsController() {
return MaterialDialog.Builder(activity) return MaterialDialog.Builder(activity)
.items(externalDirs) .items(externalDirs)
.itemsCallbackSingleChoice(selectedIndex, { _, _, which, text -> .itemsCallbackSingleChoice(selectedIndex) { _, _, which, text ->
val target = targetController as? SettingsDownloadController val target = targetController as? SettingsDownloadController
if (which == externalDirs.lastIndex) { if (which == externalDirs.lastIndex) {
target?.customDirectorySelected(currentDir) target?.customDirectorySelected(currentDir)
@ -155,7 +155,7 @@ class SettingsDownloadController : SettingsController() {
target?.predefinedDirectorySelected(text.toString()) target?.predefinedDirectorySelected(text.toString())
} }
true true
}) }
.build() .build()
} }

View file

@ -79,8 +79,8 @@ class SettingsGeneralController : SettingsController() {
Observable.combineLatest( Observable.combineLatest(
preferences.portraitColumns().asObservable(), preferences.portraitColumns().asObservable(),
preferences.landscapeColumns().asObservable(), preferences.landscapeColumns().asObservable()
{ portraitCols, landscapeCols -> Pair(portraitCols, landscapeCols) }) ) { portraitCols, landscapeCols -> Pair(portraitCols, landscapeCols) }
.subscribeUntilDestroy { (portraitCols, landscapeCols) -> .subscribeUntilDestroy { (portraitCols, landscapeCols) ->
val portrait = getColumnValue(portraitCols) val portrait = getColumnValue(portraitCols)
val landscape = getColumnValue(landscapeCols) val landscape = getColumnValue(landscapeCols)

View file

@ -92,7 +92,7 @@ fun syncChaptersWithSource(db: DatabaseHelper,
db.inTransaction { db.inTransaction {
val deletedChapterNumbers = TreeSet<Float>() val deletedChapterNumbers = TreeSet<Float>()
val deletedReadChapterNumbers = TreeSet<Float>() val deletedReadChapterNumbers = TreeSet<Float>()
if (!toDelete.isEmpty()) { if (toDelete.isNotEmpty()) {
for (c in toDelete) { for (c in toDelete) {
if (c.read) { if (c.read) {
deletedReadChapterNumbers.add(c.chapter_number) deletedReadChapterNumbers.add(c.chapter_number)
@ -102,7 +102,7 @@ fun syncChaptersWithSource(db: DatabaseHelper,
db.deleteChapters(toDelete).executeAsBlocking() db.deleteChapters(toDelete).executeAsBlocking()
} }
if (!toAdd.isEmpty()) { if (toAdd.isNotEmpty()) {
// Set the date fetch for new items in reverse order to allow another sorting method. // Set the date fetch for new items in reverse order to allow another sorting method.
// Sources MUST return the chapters from most to less recent, which is common. // Sources MUST return the chapters from most to less recent, which is common.
var now = Date().time var now = Date().time
@ -121,7 +121,7 @@ fun syncChaptersWithSource(db: DatabaseHelper,
db.insertChapters(toAdd).executeAsBlocking() db.insertChapters(toAdd).executeAsBlocking()
} }
if (!toChange.isEmpty()) { if (toChange.isNotEmpty()) {
db.insertChapters(toChange).executeAsBlocking() db.insertChapters(toChange).executeAsBlocking()
} }
@ -132,8 +132,8 @@ fun syncChaptersWithSource(db: DatabaseHelper,
manga.last_update = Date().time manga.last_update = Date().time
db.updateLastUpdated(manga).executeAsBlocking() db.updateLastUpdated(manga).executeAsBlocking()
} }
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
} }
//checks if the chapter in db needs updated //checks if the chapter in db needs updated

View file

@ -50,7 +50,7 @@ object ImageUtil {
} }
private fun ByteArray.compareWith(magic: ByteArray): Boolean { private fun ByteArray.compareWith(magic: ByteArray): Boolean {
for (i in 0 until magic.size) { for (i in magic.indices) {
if (this[i] != magic[i]) return false if (this[i] != magic[i]) return false
} }
return true return true
@ -58,7 +58,7 @@ object ImageUtil {
private fun charByteArrayOf(vararg bytes: Int): ByteArray { private fun charByteArrayOf(vararg bytes: Int): ByteArray {
return ByteArray(bytes.size).apply { return ByteArray(bytes.size).apply {
for (i in 0 until bytes.size) { for (i in bytes.indices) {
set(i, bytes[i].toByte()) set(i, bytes[i].toByte())
} }
} }

View file

@ -9,7 +9,7 @@ import android.view.ContextThemeWrapper
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.* import java.util.Locale
/** /**
* Utility class to change the application's language in runtime. * Utility class to change the application's language in runtime.
@ -90,7 +90,7 @@ object LocaleHelper {
* Updates the app's language to an activity. * Updates the app's language to an activity.
*/ */
fun updateConfiguration(wrapper: ContextThemeWrapper) { fun updateConfiguration(wrapper: ContextThemeWrapper) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && appLocale != null) { if (appLocale != null) {
val config = Configuration(preferences.context.resources.configuration) val config = Configuration(preferences.context.resources.configuration)
config.setLocale(appLocale) config.setLocale(appLocale)
wrapper.applyOverrideConfiguration(config) wrapper.applyOverrideConfiguration(config)

View file

@ -22,7 +22,7 @@ object SharedData {
* @param data the object to put. * @param data the object to put.
*/ */
fun <T : Any> put(data: T) { fun <T : Any> put(data: T) {
map.put(data.javaClass, data) map[data.javaClass] = data
} }
/** /**

View file

@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.util package eu.kanade.tachiyomi.util
import java.lang.Math.floor import kotlin.math.floor
/** /**
* Replaces the given string to have at most [count] characters using [replacement] at its end. * Replaces the given string to have at most [count] characters using [replacement] at its end.

View file

@ -5,11 +5,12 @@ package eu.kanade.tachiyomi.util
import android.graphics.Color import android.graphics.Color
import android.graphics.Point import android.graphics.Point
import android.graphics.Typeface import android.graphics.Typeface
import com.google.android.material.snackbar.Snackbar
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator import com.amulyakhare.textdrawable.util.ColorGenerator
import com.google.android.material.snackbar.Snackbar
import kotlin.math.min
/** /**
* Returns coordinates of view. * Returns coordinates of view.
@ -58,7 +59,7 @@ inline fun View.visibleIf(block: () -> Boolean) {
* @param random random color * @param random random color
*/ */
fun View.getRound(text: String, random : Boolean = true): TextDrawable { fun View.getRound(text: String, random : Boolean = true): TextDrawable {
val size = Math.min(this.width, this.height) val size = min(this.width, this.height)
return TextDrawable.builder() return TextDrawable.builder()
.beginConfig() .beginConfig()
.width(size) .width(size)

View file

@ -1,9 +1,10 @@
package eu.kanade.tachiyomi.widget package eu.kanade.tachiyomi.widget
import android.content.Context import android.content.Context
import android.util.AttributeSet
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import android.util.AttributeSet import kotlin.math.max
class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
RecyclerView(context, attrs) { RecyclerView(context, attrs) {
@ -37,7 +38,7 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
override fun onMeasure(widthSpec: Int, heightSpec: Int) { override fun onMeasure(widthSpec: Int, heightSpec: Int) {
super.onMeasure(widthSpec, heightSpec) super.onMeasure(widthSpec, heightSpec)
if (spanCount == 0 && columnWidth > 0) { if (spanCount == 0 && columnWidth > 0) {
val count = Math.max(1, measuredWidth / columnWidth) val count = max(1, measuredWidth / columnWidth)
spanCount = count spanCount = count
} }
} }

View file

@ -22,12 +22,12 @@ class CustomLayoutPickerActivity : FilePickerActivity() {
class CustomLayoutFilePickerFragment : FilePickerFragment() { class CustomLayoutFilePickerFragment : FilePickerFragment() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) { return when (viewType) {
LogicHandler.VIEWTYPE_DIR -> { LogicHandler.VIEWTYPE_DIR -> {
val view = parent.inflate(R.layout.common_listitem_dir) val view = parent.inflate(R.layout.common_listitem_dir)
return DirViewHolder(view) DirViewHolder(view)
} }
else -> return super.onCreateViewHolder(parent, viewType) else -> super.onCreateViewHolder(parent, viewType)
} }
} }
} }

View file

@ -13,7 +13,7 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.getResourceColor import eu.kanade.tachiyomi.util.getResourceColor
/** /**
* An alternative implementation of [android.support.design.widget.NavigationView], without menu * An alternative implementation of [com.google.android.material.navigation.NavigationView], without menu
* inflation and allowing customizable items (multiple selections, custom views, etc). * inflation and allowing customizable items (multiple selections, custom views, etc).
*/ */
open class ExtendedNavigationView @JvmOverloads constructor( open class ExtendedNavigationView @JvmOverloads constructor(
@ -179,8 +179,7 @@ open class ExtendedNavigationView @JvmOverloads constructor(
@CallSuper @CallSuper
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
val item = items[position] return when (items[position]) {
return when (item) {
is Item.Header -> VIEW_TYPE_HEADER is Item.Header -> VIEW_TYPE_HEADER
is Item.Separator -> VIEW_TYPE_SEPARATOR is Item.Separator -> VIEW_TYPE_SEPARATOR
is Item.Radio -> VIEW_TYPE_RADIO is Item.Radio -> VIEW_TYPE_RADIO

View file

@ -20,6 +20,7 @@ abstract class FABAnimationBase : FloatingActionButton.Behavior() {
target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int,
dyUnconsumed: Int, type: Int) { dyUnconsumed: Int, type: Int) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type) super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type)
if (dyConsumed > 0 && !isAnimatingOut && child.visibility == View.VISIBLE) { if (dyConsumed > 0 && !isAnimatingOut && child.visibility == View.VISIBLE) {
// User scrolled down and the FAB is currently visible -> hide the FAB // User scrolled down and the FAB is currently visible -> hide the FAB
animateOut(child) animateOut(child)

View file

@ -5,6 +5,7 @@ import android.os.Parcelable
import android.util.AttributeSet import android.util.AttributeSet
import android.widget.SeekBar import android.widget.SeekBar
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import kotlin.math.abs
class NegativeSeekBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class NegativeSeekBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
@ -28,21 +29,21 @@ class NegativeSeekBar @JvmOverloads constructor(context: Context, attrs: Attribu
super.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { super.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, value: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar?, value: Int, fromUser: Boolean) {
listener?.let { it.onProgressChanged(seekBar, minValue + value, fromUser) } listener?.onProgressChanged(seekBar, minValue + value, fromUser)
} }
override fun onStartTrackingTouch(p0: SeekBar?) { override fun onStartTrackingTouch(p0: SeekBar?) {
listener?.let { it.onStartTrackingTouch(p0) } listener?.onStartTrackingTouch(p0)
} }
override fun onStopTrackingTouch(p0: SeekBar?) { override fun onStopTrackingTouch(p0: SeekBar?) {
listener?.let { it.onStopTrackingTouch(p0) } listener?.onStopTrackingTouch(p0)
} }
}) })
} }
override fun setProgress(progress: Int) { override fun setProgress(progress: Int) {
super.setProgress(Math.abs(minValue) + progress) super.setProgress(abs(minValue) + progress)
} }
fun setMinSeek(minValue: Int) { fun setMinSeek(minValue: Int) {

View file

@ -30,7 +30,7 @@ class PTSansTextView @JvmOverloads constructor(context: Context, attrs: Attribut
Typeface.createFromAsset(context.assets, when (typeface) { Typeface.createFromAsset(context.assets, when (typeface) {
PTSANS_NARROW -> "fonts/PTSans-Narrow.ttf" PTSANS_NARROW -> "fonts/PTSans-Narrow.ttf"
PTSANS_NARROW_BOLD -> "fonts/PTSans-NarrowBold.ttf" PTSANS_NARROW_BOLD -> "fonts/PTSans-NarrowBold.ttf"
else -> throw IllegalArgumentException("Font not found " + typeface) else -> throw IllegalArgumentException("Font not found $typeface")
}) })
}) })

View file

@ -2,18 +2,19 @@ package eu.kanade.tachiyomi.widget
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import com.google.android.material.R
import com.google.android.material.textfield.TextInputLayout
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.appcompat.widget.TintTypedArray
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.* import android.widget.*
import androidx.appcompat.widget.TintTypedArray
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.R
import com.google.android.material.internal.ScrimInsetsFrameLayout import com.google.android.material.internal.ScrimInsetsFrameLayout
import com.google.android.material.textfield.TextInputLayout
import eu.kanade.tachiyomi.util.inflate import eu.kanade.tachiyomi.util.inflate
import kotlin.math.min
import eu.kanade.tachiyomi.R as TR import eu.kanade.tachiyomi.R as TR
@Suppress("LeakingThis") @Suppress("LeakingThis")
@ -66,7 +67,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
override fun onMeasure(widthSpec: Int, heightSpec: Int) { override fun onMeasure(widthSpec: Int, heightSpec: Int) {
val width = when (MeasureSpec.getMode(widthSpec)) { val width = when (MeasureSpec.getMode(widthSpec)) {
MeasureSpec.AT_MOST -> MeasureSpec.makeMeasureSpec( MeasureSpec.AT_MOST -> MeasureSpec.makeMeasureSpec(
Math.min(MeasureSpec.getSize(widthSpec), maxWidth), MeasureSpec.EXACTLY) min(MeasureSpec.getSize(widthSpec), maxWidth), MeasureSpec.EXACTLY)
MeasureSpec.UNSPECIFIED -> MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY) MeasureSpec.UNSPECIFIED -> MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY)
else -> widthSpec else -> widthSpec
} }

View file

@ -25,7 +25,7 @@ abstract class LoginDialogPreference(bundle: Bundle? = null) : DialogController(
var requestSubscription: Subscription? = null var requestSubscription: Subscription? = null
override fun onCreateDialog(savedState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val dialog = MaterialDialog.Builder(activity!!) val dialog = MaterialDialog.Builder(activity!!)
.customView(R.layout.pref_account_login, false) .customView(R.layout.pref_account_login, false)
.negativeText(android.R.string.cancel) .negativeText(android.R.string.cancel)