JDK8, lint fixing (#2888)

* Use Kotlin JDK8

* Satisfy a ton of lints

* Run res/layout files (and manifest) through reformatter
This commit is contained in:
TacoTheDank 2020-04-18 14:47:22 -04:00 committed by GitHub
parent 4fc8800a37
commit 415df2357c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 224 additions and 229 deletions

View File

@ -254,7 +254,7 @@ dependencies {
testImplementation "org.robolectric:shadows-multidex:$robolectric_version" testImplementation "org.robolectric:shadows-multidex:$robolectric_version"
testImplementation "org.robolectric:shadows-play-services:$robolectric_version" testImplementation "org.robolectric:shadows-play-services:$robolectric_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
final coroutines_version = '1.3.4' final coroutines_version = '1.3.4'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"

View File

@ -18,15 +18,15 @@
android:name=".App" android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:hasFragileUserData="true"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:usesCleartextTraffic="true" android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name" android:label="@string/app_name"
android:largeHeap="true" android:largeHeap="true"
android:theme="@style/Theme.Tachiyomi.Light"> android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@style/Theme.Tachiyomi.Light"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".ui.main.MainActivity" android:name=".ui.main.MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
@ -36,7 +36,9 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<!--suppress AndroidDomInspection --> <!--suppress AndroidDomInspection -->
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/> <meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity> </activity>
<activity <activity
android:name=".ui.main.DeepLinkActivity" android:name=".ui.main.DeepLinkActivity"
@ -45,16 +47,19 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEARCH" /> <action android:name="android.intent.action.SEARCH" />
<action android:name="com.google.android.gms.actions.SEARCH_ACTION" /> <action android:name="com.google.android.gms.actions.SEARCH_ACTION" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="eu.kanade.tachiyomi.SEARCH" /> <action android:name="eu.kanade.tachiyomi.SEARCH" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity> </activity>
<activity <activity android:name=".ui.reader.ReaderActivity" />
android:name=".ui.reader.ReaderActivity" />
<activity <activity
android:name=".ui.security.BiometricUnlockActivity" android:name=".ui.security.BiometricUnlockActivity"
android:theme="@style/Theme.Splash" /> android:theme="@style/Theme.Splash" />

View File

@ -128,7 +128,7 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
val categoryEntries = JsonArray() val categoryEntries = JsonArray()
// Add value's to root // Add value's to root
root[Backup.VERSION] = Backup.CURRENT_VERSION root[Backup.VERSION] = CURRENT_VERSION
root[Backup.MANGAS] = mangaEntries root[Backup.MANGAS] = mangaEntries
root[CATEGORIES] = categoryEntries root[CATEGORIES] = categoryEntries
@ -303,8 +303,8 @@ class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> { fun restoreChapterFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>): Observable<Pair<List<Chapter>, List<Chapter>>> {
return source.fetchChapterList(manga) return source.fetchChapterList(manga)
.map { syncChaptersWithSource(databaseHelper, it, manga, source) } .map { syncChaptersWithSource(databaseHelper, it, manga, source) }
.doOnNext { .doOnNext { pair ->
if (it.first.isNotEmpty()) { if (pair.first.isNotEmpty()) {
chapters.forEach { it.manga_id = manga.id } chapters.forEach { it.manga_id = manga.id }
insertChapters(chapters) insertChapters(chapters)
} }

View File

@ -164,7 +164,7 @@ class BackupRestoreService : Service() {
* @return the start value of the command. * @return the start value of the command.
*/ */
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent == null) return Service.START_NOT_STICKY if (intent == null) return START_NOT_STICKY
val uri = intent.getParcelableExtra<Uri>(BackupConst.EXTRA_URI) val uri = intent.getParcelableExtra<Uri>(BackupConst.EXTRA_URI)
@ -179,7 +179,7 @@ class BackupRestoreService : Service() {
.subscribeOn(Schedulers.from(executor)) .subscribeOn(Schedulers.from(executor))
.subscribe() .subscribe()
return Service.START_NOT_STICKY return START_NOT_STICKY
} }
/** /**

View File

@ -80,13 +80,13 @@ class ChapterCache(private val context: Context) {
if (file == "journal" || file.startsWith("journal.")) if (file == "journal" || file.startsWith("journal."))
return false return false
try { return try {
// Remove the extension from the file to get the key of the cache // Remove the extension from the file to get the key of the cache
val key = file.substringBeforeLast(".") val key = file.substringBeforeLast(".")
// Remove file from cache. // Remove file from cache.
return diskCache.remove(key) diskCache.remove(key)
} catch (e: Exception) { } catch (e: Exception) {
return false false
} }
} }
@ -149,10 +149,10 @@ class ChapterCache(private val context: Context) {
* @return true if in cache otherwise false. * @return true if in cache otherwise false.
*/ */
fun isImageInCache(imageUrl: String): Boolean { fun isImageInCache(imageUrl: String): Boolean {
try { return try {
return diskCache.get(DiskUtil.hashKeyForDisk(imageUrl)) != null diskCache.get(DiskUtil.hashKeyForDisk(imageUrl)) != null
} catch (e: IOException) { } catch (e: IOException) {
return false false
} }
} }

View File

@ -27,17 +27,15 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
val putResult: PutResult val putResult: PutResult
try { putResult = cursor.use { putCursor ->
if (cursor.count == 0) { if (putCursor.count == 0) {
val insertQuery = mapToInsertQuery(history) val insertQuery = mapToInsertQuery(history)
val insertedId = db.lowLevel().insert(insertQuery, mapToContentValues(history)) val insertedId = db.lowLevel().insert(insertQuery, mapToContentValues(history))
putResult = PutResult.newInsertResult(insertedId, insertQuery.table()) PutResult.newInsertResult(insertedId, insertQuery.table())
} else { } else {
val numberOfRowsUpdated = db.lowLevel().update(updateQuery, mapToUpdateContentValues(history)) val numberOfRowsUpdated = db.lowLevel().update(updateQuery, mapToUpdateContentValues(history))
putResult = PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table()) PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
} }
} finally {
cursor.close()
} }
putResult putResult

View File

@ -259,7 +259,7 @@ class DownloadCache(
*/ */
private inline fun <K, V, R> Map<out K, V>.mapNotNullKeys(transform: (Map.Entry<K?, V>) -> R?): Map<R, V> { private inline fun <K, V, R> Map<out K, V>.mapNotNullKeys(transform: (Map.Entry<K?, V>) -> R?): Map<R, V> {
val destination = LinkedHashMap<R, V>() val destination = LinkedHashMap<R, V>()
forEach { element -> transform(element)?.let { destination.put(it, element.value) } } forEach { element -> transform(element)?.let { destination[it] = element.value } }
return destination return destination
} }

View File

@ -106,7 +106,7 @@ class DownloadService : Service() {
* Not used. * Not used.
*/ */
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return Service.START_NOT_STICKY return START_NOT_STICKY
} }
/** /**

View File

@ -283,7 +283,7 @@ class Downloader(
// Do when page is downloaded. // Do when page is downloaded.
.doOnNext { notifier.onProgressChange(download) } .doOnNext { notifier.onProgressChange(download) }
.toList() .toList()
.map { _ -> download } .map { download }
// Do after download completes // Do after download completes
.doOnNext { ensureSuccessfulDownload(download, mangaDir, tmpDir, chapterDirname) } .doOnNext { ensureSuccessfulDownload(download, mangaDir, tmpDir, chapterDirname) }
// If the page list threw, it will resume here // If the page list threw, it will resume here

View File

@ -5,6 +5,7 @@ import android.util.Log
import com.bumptech.glide.Priority import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.data.DataFetcher
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -24,7 +25,7 @@ open class FileFetcher(private val file: File) : DataFetcher<InputStream> {
data = FileInputStream(file) data = FileInputStream(file)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
if (Log.isLoggable(TAG, Log.DEBUG)) { if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Failed to open file", e) Timber.d(e, "Failed to open file")
} }
callback.onLoadFailed(e) callback.onLoadFailed(e)
return return

View File

@ -246,7 +246,7 @@ class LibraryUpdateService(
stopSelf(startId) stopSelf(startId)
}) })
return Service.START_REDELIVER_INTENT return START_REDELIVER_INTENT
} }
/** /**

View File

@ -97,13 +97,13 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
// 100 point // 100 point
POINT_100 -> index.toFloat() POINT_100 -> index.toFloat()
// 5 stars // 5 stars
POINT_5 -> when { POINT_5 -> when (index) {
index == 0 -> 0f 0 -> 0f
else -> index * 20f - 10f else -> index * 20f - 10f
} }
// Smiley // Smiley
POINT_3 -> when { POINT_3 -> when (index) {
index == 0 -> 0f 0 -> 0f
else -> index * 25f + 10f else -> index * 25f + 10f
} }
// 10 point decimal // 10 point decimal
@ -116,8 +116,8 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
val score = track.score val score = track.score
return when (scorePreference.getOrDefault()) { return when (scorePreference.getOrDefault()) {
POINT_5 -> when { POINT_5 -> when (score) {
score == 0f -> "0 ★" 0f -> "0 ★"
else -> "${((score + 10) / 20).toInt()}" else -> "${((score + 10) / 20).toInt()}"
} }
POINT_3 -> when { POINT_3 -> when {

View File

@ -38,7 +38,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().serializeNulls().create())) .addConverterFactory(GsonConverterFactory.create(GsonBuilder().serializeNulls().create()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build() .build()
.create(KitsuApi.Rest::class.java) .create(Rest::class.java)
private val searchRest = Retrofit.Builder() private val searchRest = Retrofit.Builder()
.baseUrl(algoliaKeyUrl) .baseUrl(algoliaKeyUrl)
@ -46,7 +46,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build() .build()
.create(KitsuApi.SearchKeyRest::class.java) .create(SearchKeyRest::class.java)
private val algoliaRest = Retrofit.Builder() private val algoliaRest = Retrofit.Builder()
.baseUrl(algoliaUrl) .baseUrl(algoliaUrl)
@ -54,7 +54,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build() .build()
.create(KitsuApi.AgoliaSearchRest::class.java) .create(AgoliaSearchRest::class.java)
fun addLibManga(track: Track, userId: String): Observable<Track> { fun addLibManga(track: Track, userId: String): Observable<Track> {
return Observable.defer { return Observable.defer {
@ -162,7 +162,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build() .build()
.create(KitsuApi.LoginRest::class.java) .create(LoginRest::class.java)
.requestAccessToken(username, password) .requestAccessToken(username, password)
} }

View File

@ -36,10 +36,10 @@ class KitsuSearchManga(obj: JsonObject) {
cover_url = original ?: "" cover_url = original ?: ""
summary = synopsis summary = synopsis
tracking_url = KitsuApi.mangaUrl(media_id) tracking_url = KitsuApi.mangaUrl(media_id)
if (endDate == null) { publishing_status = if (endDate == null) {
publishing_status = "Publishing" "Publishing"
} else { } else {
publishing_status = "Finished" "Finished"
} }
publishing_type = subType ?: "" publishing_type = subType ?: ""
start_date = startDate ?: "" start_date = startDate ?: ""

View File

@ -49,8 +49,7 @@ internal class ExtensionInstallReceiver(private val listener: Listener) :
when (intent.action) { when (intent.action) {
Intent.ACTION_PACKAGE_ADDED -> { Intent.ACTION_PACKAGE_ADDED -> {
if (!isReplacing(intent)) launchNow { if (!isReplacing(intent)) launchNow {
val result = getExtensionFromIntent(context, intent) when (val result = getExtensionFromIntent(context, intent)) {
when (result) {
is LoadResult.Success -> listener.onExtensionInstalled(result.extension) is LoadResult.Success -> listener.onExtensionInstalled(result.extension)
is LoadResult.Untrusted -> listener.onExtensionUntrusted(result.extension) is LoadResult.Untrusted -> listener.onExtensionUntrusted(result.extension)
} }
@ -58,8 +57,7 @@ internal class ExtensionInstallReceiver(private val listener: Listener) :
} }
Intent.ACTION_PACKAGE_REPLACED -> { Intent.ACTION_PACKAGE_REPLACED -> {
launchNow { launchNow {
val result = getExtensionFromIntent(context, intent) when (val result = getExtensionFromIntent(context, intent)) {
when (result) {
is LoadResult.Success -> listener.onExtensionUpdated(result.extension) is LoadResult.Success -> listener.onExtensionUpdated(result.extension)
// Not needed as a package can't be upgraded if the signature is different // Not needed as a package can't be upgraded if the signature is different
is LoadResult.Untrusted -> { is LoadResult.Untrusted -> {

View File

@ -94,8 +94,7 @@ internal object ExtensionLoader {
return LoadResult.Error(error) return LoadResult.Error(error)
} }
val extName = pkgManager.getApplicationLabel(appInfo).toString() val extName = pkgManager.getApplicationLabel(appInfo).toString().substringAfter("Tachiyomi: ")
.orEmpty().substringAfter("Tachiyomi: ")
val versionName = pkgInfo.versionName val versionName = pkgInfo.versionName
val versionCode = pkgInfo.versionCode val versionCode = pkgInfo.versionCode
@ -137,8 +136,7 @@ internal object ExtensionLoader {
} }
.flatMap { .flatMap {
try { try {
val obj = Class.forName(it, false, classLoader).newInstance() when (val obj = Class.forName(it, false, classLoader).newInstance()) {
when (obj) {
is Source -> listOf(obj) is Source -> listOf(obj)
is SourceFactory -> obj.createSources() is SourceFactory -> obj.createSources()
else -> throw Exception("Unknown source class type! ${obj.javaClass}") else -> throw Exception("Unknown source class type! ${obj.javaClass}")

View File

@ -81,16 +81,16 @@ class LocalSource(private val context: Context) : CatalogueSource {
val state = ((if (filters.isEmpty()) POPULAR_FILTERS else filters)[0] as OrderBy).state val state = ((if (filters.isEmpty()) POPULAR_FILTERS else filters)[0] as OrderBy).state
when (state?.index) { when (state?.index) {
0 -> { 0 -> {
if (state.ascending) mangaDirs = if (state.ascending)
mangaDirs = mangaDirs.sortedBy { it.name.toLowerCase(Locale.ENGLISH) } mangaDirs.sortedBy { it.name.toLowerCase(Locale.ENGLISH) }
else else
mangaDirs = mangaDirs.sortedByDescending { it.name.toLowerCase(Locale.ENGLISH) } mangaDirs.sortedByDescending { it.name.toLowerCase(Locale.ENGLISH) }
} }
1 -> { 1 -> {
if (state.ascending) mangaDirs = if (state.ascending)
mangaDirs = mangaDirs.sortedBy(File::lastModified) mangaDirs.sortedBy(File::lastModified)
else else
mangaDirs = mangaDirs.sortedByDescending(File::lastModified) mangaDirs.sortedByDescending(File::lastModified)
} }
} }
@ -131,17 +131,14 @@ class LocalSource(private val context: Context) : CatalogueSource {
getBaseDirectories(context) getBaseDirectories(context)
.mapNotNull { File(it, manga.url).listFiles()?.toList() } .mapNotNull { File(it, manga.url).listFiles()?.toList() }
.flatten() .flatten()
.filter { it.extension.equals("json") } .firstOrNull { it.extension == "json" }
.firstOrNull()
?.apply { ?.apply {
val json = Gson().fromJson(Scanner(this).useDelimiter("\\Z").next(), JsonObject::class.java) val json = Gson().fromJson(Scanner(this).useDelimiter("\\Z").next(), JsonObject::class.java)
manga.title = json["title"]?.asString ?: manga.title manga.title = json["title"]?.asString ?: manga.title
manga.author = json["author"]?.asString ?: manga.author manga.author = json["author"]?.asString ?: manga.author
manga.artist = json["artist"]?.asString ?: manga.artist manga.artist = json["artist"]?.asString ?: manga.artist
manga.description = json["description"]?.asString ?: manga.description manga.description = json["description"]?.asString ?: manga.description
manga.genre = json["genre"]?.asJsonArray manga.genre = json["genre"]?.asJsonArray?.joinToString(", ") { it.asString }
?.map { it.asString }
?.joinToString(", ")
?: manga.genre ?: manga.genre
manga.status = json["status"]?.asInt ?: manga.status manga.status = json["status"]?.asInt ?: manga.status
} }
@ -150,6 +147,7 @@ class LocalSource(private val context: Context) : CatalogueSource {
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
val chapters = getBaseDirectories(context) val chapters = getBaseDirectories(context)
.asSequence()
.mapNotNull { File(it, manga.url).listFiles()?.toList() } .mapNotNull { File(it, manga.url).listFiles()?.toList() }
.flatten() .flatten()
.filter { it.isDirectory || isSupportedFile(it.extension) } .filter { it.isDirectory || isSupportedFile(it.extension) }
@ -171,6 +169,7 @@ class LocalSource(private val context: Context) : CatalogueSource {
val c = c2.chapter_number.compareTo(c1.chapter_number) val c = c2.chapter_number.compareTo(c1.chapter_number)
if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c if (c == 0) c2.name.compareToCaseInsensitiveNaturalOrder(c1.name) else c
}) })
.toList()
return Observable.just(chapters) return Observable.just(chapters)
} }
@ -211,8 +210,7 @@ class LocalSource(private val context: Context) : CatalogueSource {
} }
private fun updateCover(chapter: SChapter, manga: SManga): File? { private fun updateCover(chapter: SChapter, manga: SManga): File? {
val format = getFormat(chapter) return when (val format = getFormat(chapter)) {
return when (format) {
is Format.Directory -> { is Format.Directory -> {
val entry = format.file.listFiles() val entry = format.file.listFiles()
.sortedWith(Comparator<File> { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) }) .sortedWith(Comparator<File> { f1, f2 -> f1.name.compareToCaseInsensitiveNaturalOrder(f2.name) })
@ -250,7 +248,7 @@ class LocalSource(private val context: Context) : CatalogueSource {
} }
} }
private class OrderBy : Filter.Sort("Order by", arrayOf("Title", "Date"), Filter.Sort.Selection(0, true)) private class OrderBy : Filter.Sort("Order by", arrayOf("Title", "Date"), Selection(0, true))
override fun getFilterList() = FilterList(OrderBy()) override fun getFilterList() = FilterList(OrderBy())

View File

@ -207,14 +207,14 @@ abstract class HttpSource : CatalogueSource {
* @param manga the manga to look for chapters. * @param manga the manga to look for chapters.
*/ */
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> { override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
if (manga.status != SManga.LICENSED) { return if (manga.status != SManga.LICENSED) {
return client.newCall(chapterListRequest(manga)) client.newCall(chapterListRequest(manga))
.asObservableSuccess() .asObservableSuccess()
.map { response -> .map { response ->
chapterListParse(response) chapterListParse(response)
} }
} else { } else {
return Observable.error(Exception("Licensed - No chapters to show")) Observable.error(Exception("Licensed - No chapters to show"))
} }
} }
@ -340,16 +340,16 @@ abstract class HttpSource : CatalogueSource {
* @param orig the full url. * @param orig the full url.
*/ */
private fun getUrlWithoutDomain(orig: String): String { private fun getUrlWithoutDomain(orig: String): String {
try { return try {
val uri = URI(orig) val uri = URI(orig)
var out = uri.path var out = uri.path
if (uri.query != null) if (uri.query != null)
out += "?" + uri.query out += "?" + uri.query
if (uri.fragment != null) if (uri.fragment != null)
out += "#" + uri.fragment out += "#" + uri.fragment
return out out
} catch (e: URISyntaxException) { } catch (e: URISyntaxException) {
return orig orig
} }
} }

View File

@ -31,13 +31,13 @@ interface SlicedHolder {
when { when {
// Only one item in the card // Only one item in the card
count == 1 -> applySlice(2f, false, false, true, true) count == 1 -> applySlice(2f, topRect = false, bottomRect = false, topShadow = true, bottomShadow = true)
// First item of the card // First item of the card
position == 0 -> applySlice(2f, false, true, true, false) position == 0 -> applySlice(2f, topRect = false, bottomRect = true, topShadow = true, bottomShadow = false)
// Last item of the card // Last item of the card
position == count - 1 -> applySlice(2f, true, false, false, true) position == count - 1 -> applySlice(2f, topRect = true, bottomRect = false, topShadow = false, bottomShadow = true)
// Middle item // Middle item
else -> applySlice(0f, false, false, false, false) else -> applySlice(0f, topRect = false, bottomRect = false, topShadow = false, bottomShadow = false)
} }
} }

View File

@ -22,7 +22,7 @@ class ExtensionAdapter(val controller: ExtensionController) :
/** /**
* Listener for browse item clicks. * Listener for browse item clicks.
*/ */
val buttonClickListener: ExtensionAdapter.OnButtonClickListener = controller val buttonClickListener: OnButtonClickListener = controller
interface OnButtonClickListener { interface OnButtonClickListener {
fun onButtonClick(position: Int) fun onButtonClick(position: Int)

View File

@ -229,13 +229,13 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
override fun onItemClick(view: View?, position: Int): Boolean { override fun onItemClick(view: View?, position: Int): Boolean {
// If the action mode is created and the position is valid, toggle the selection. // If the action mode is created and the position is valid, toggle the selection.
val item = adapter.getItem(position) ?: return false val item = adapter.getItem(position) ?: return false
if (adapter.mode == SelectableAdapter.Mode.MULTI) { return if (adapter.mode == SelectableAdapter.Mode.MULTI) {
lastClickPosition = position lastClickPosition = position
toggleSelection(position) toggleSelection(position)
return true true
} else { } else {
openManga(item.manga) openManga(item.manga)
return false false
} }
} }

View File

@ -303,7 +303,7 @@ class LibraryPresenter(
if (mangas.isEmpty()) return emptyList() if (mangas.isEmpty()) return emptyList()
return mangas.toSet() return mangas.toSet()
.map { db.getCategoriesForManga(it).executeAsBlocking() } .map { db.getCategoriesForManga(it).executeAsBlocking() }
.reduce { set1: Iterable<Category>, set2 -> set1.intersect(set2) } .reduce { set1: Iterable<Category>, set2 -> set1.intersect(set2).toMutableList() }
} }
/** /**

View File

@ -306,13 +306,13 @@ class ChaptersController : NucleusController<ChaptersControllerBinding, Chapters
override fun onItemClick(view: View?, position: Int): Boolean { override fun onItemClick(view: View?, position: Int): Boolean {
val adapter = adapter ?: return false val adapter = adapter ?: return false
val item = adapter.getItem(position) ?: return false val item = adapter.getItem(position) ?: return false
if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) { return if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) {
lastClickPosition = position lastClickPosition = position
toggleSelection(position) toggleSelection(position)
return true true
} else { } else {
openChapter(item.chapter) openChapter(item.chapter)
return false false
} }
} }

View File

@ -67,8 +67,8 @@ class ChaptersPresenter(
// Prepare the relay. // Prepare the relay.
chaptersRelay.flatMap { applyChapterFilters(it) } chaptersRelay.flatMap { applyChapterFilters(it) }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(ChaptersController::onNextChapters, .subscribeLatestCache(ChaptersController::onNextChapters)
{ _, error -> Timber.e(error) }) { _, error -> Timber.e(error) }
// Add the subscription that retrieves the chapters from the database, keeps subscribed to // Add the subscription that retrieves the chapters from the database, keeps subscribed to
// changes, and sends the list of chapters to the relay. // changes, and sends the list of chapters to the relay.

View File

@ -262,13 +262,11 @@ class MangaInfoController(private val fromSource: Boolean = false) :
.centerCrop() .centerCrop()
.into(binding.mangaCover) .into(binding.mangaCover)
if (binding.backdrop != null) {
GlideApp.with(view.context) GlideApp.with(view.context)
.load(manga) .load(manga)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop() .centerCrop()
.into(binding.backdrop!!) .into(binding.backdrop)
}
} }
// Manga info section // Manga info section
@ -618,8 +616,7 @@ class MangaInfoController(private val fromSource: Boolean = false) :
return return
} }
val previousController = router.backstack[router.backstackSize - 2].controller() when (val previousController = router.backstack[router.backstackSize - 2].controller()) {
when (previousController) {
is LibraryController -> { is LibraryController -> {
router.handleBack() router.handleBack()
previousController.search(query) previousController.search(query)

View File

@ -33,7 +33,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() val statusList = item.service.getStatusList()
val statusString = statusList.mapNotNull { item.service.getStatus(it) } val statusString = statusList.map { item.service.getStatus(it) }
val selectedIndex = statusList.indexOf(item.track?.status) val selectedIndex = statusList.indexOf(item.track?.status)
return MaterialDialog.Builder(activity!!) return MaterialDialog.Builder(activity!!)

View File

@ -90,7 +90,7 @@ class TrackController : NucleusController<TrackControllerBinding, TrackPresenter
override fun onLogoClick(position: Int) { override fun onLogoClick(position: Int) {
val track = adapter?.getItem(position)?.track ?: return val track = adapter?.getItem(position)?.track ?: return
if (track.tracking_url.isNullOrBlank()) { if (track.tracking_url.isBlank()) {
activity?.toast(R.string.url_not_set) activity?.toast(R.string.url_not_set)
} else { } else {
activity?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(track.tracking_url))) activity?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(track.tracking_url)))

View File

@ -54,7 +54,7 @@ class TrackSearchAdapter(context: Context) :
view.track_search_title.text = track.title view.track_search_title.text = track.title
view.track_search_summary.text = track.summary view.track_search_summary.text = track.summary
GlideApp.with(view.context).clear(view.track_search_cover) GlideApp.with(view.context).clear(view.track_search_cover)
if (!track.cover_url.isNullOrEmpty()) { if (!track.cover_url.isEmpty()) {
GlideApp.with(view.context) GlideApp.with(view.context)
.load(track.cover_url) .load(track.cover_url)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
@ -62,21 +62,21 @@ class TrackSearchAdapter(context: Context) :
.into(view.track_search_cover) .into(view.track_search_cover)
} }
if (track.publishing_status.isNullOrBlank()) { if (track.publishing_status.isBlank()) {
view.track_search_status.gone() view.track_search_status.gone()
view.track_search_status_result.gone() view.track_search_status_result.gone()
} else { } else {
view.track_search_status_result.text = track.publishing_status.capitalize() view.track_search_status_result.text = track.publishing_status.capitalize()
} }
if (track.publishing_type.isNullOrBlank()) { if (track.publishing_type.isBlank()) {
view.track_search_type.gone() view.track_search_type.gone()
view.track_search_type_result.gone() view.track_search_type_result.gone()
} else { } else {
view.track_search_type_result.text = track.publishing_type.capitalize() view.track_search_type_result.text = track.publishing_type.capitalize()
} }
if (track.start_date.isNullOrBlank()) { if (track.start_date.isBlank()) {
view.track_search_start.gone() view.track_search_start.gone()
view.track_search_start_result.gone() view.track_search_start_result.gone()
} else { } else {

View File

@ -9,8 +9,8 @@ import kotlinx.android.synthetic.main.source_list_item.thumbnail
import kotlinx.android.synthetic.main.source_list_item.title import kotlinx.android.synthetic.main.source_list_item.title
class MangaHolder( class MangaHolder(
private val view: View, view: View,
private val adapter: FlexibleAdapter<*> adapter: FlexibleAdapter<*>
) : BaseFlexibleViewHolder(view, adapter) { ) : BaseFlexibleViewHolder(view, adapter) {
fun bind(item: MangaItem) { fun bind(item: MangaItem) {

View File

@ -25,7 +25,7 @@ class SelectionHeader : AbstractHeaderItem<SelectionHeader.Holder>() {
* Creates a new view holder for this item. * Creates a new view holder for this item.
*/ */
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): Holder {
return SelectionHeader.Holder(view, adapter) return Holder(view, adapter)
} }
/** /**

View File

@ -171,7 +171,7 @@ class AboutController : SettingsController() {
} }
private fun getFormattedBuildTime(): String { private fun getFormattedBuildTime(): String {
try { return try {
val inputDf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US) val inputDf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)
inputDf.timeZone = TimeZone.getTimeZone("UTC") inputDf.timeZone = TimeZone.getTimeZone("UTC")
val buildTime = inputDf.parse(BuildConfig.BUILD_TIME) val buildTime = inputDf.parse(BuildConfig.BUILD_TIME)
@ -180,9 +180,9 @@ class AboutController : SettingsController() {
DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault()) DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
outputDf.timeZone = TimeZone.getDefault() outputDf.timeZone = TimeZone.getDefault()
return buildTime.toDateTimestampString(dateFormat) buildTime.toDateTimestampString(dateFormat)
} catch (e: ParseException) { } catch (e: ParseException) {
return BuildConfig.BUILD_TIME BuildConfig.BUILD_TIME
} }
} }
} }

View File

@ -7,7 +7,6 @@ import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
import android.text.style.ScaleXSpan import android.text.style.ScaleXSpan
import android.util.AttributeSet import android.util.AttributeSet
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.AppCompatTextView
import eu.kanade.tachiyomi.widget.OutlineSpan import eu.kanade.tachiyomi.widget.OutlineSpan
@ -39,7 +38,7 @@ class PageIndicatorTextView(
} }
} }
super.setText(finalText, TextView.BufferType.SPANNABLE) super.setText(finalText, BufferType.SPANNABLE)
} }
private companion object { private companion object {

View File

@ -361,7 +361,7 @@ class ReaderPresenter(
if (selectedChapter != currentChapters.currChapter) { if (selectedChapter != currentChapters.currChapter) {
Timber.d("Setting ${selectedChapter.chapter.url} as active") Timber.d("Setting ${selectedChapter.chapter.url} as active")
onChapterChanged(currentChapters.currChapter, selectedChapter) onChapterChanged(currentChapters.currChapter)
loadNewChapter(selectedChapter) loadNewChapter(selectedChapter)
} }
} }
@ -370,7 +370,7 @@ class ReaderPresenter(
* Called when a chapter changed from [fromChapter] to [toChapter]. It updates [fromChapter] * Called when a chapter changed from [fromChapter] to [toChapter]. It updates [fromChapter]
* on the database. * on the database.
*/ */
private fun onChapterChanged(fromChapter: ReaderChapter, toChapter: ReaderChapter) { private fun onChapterChanged(fromChapter: ReaderChapter) {
saveChapterProgress(fromChapter) saveChapterProgress(fromChapter)
saveChapterHistory(fromChapter) saveChapterHistory(fromChapter)
} }

View File

@ -33,10 +33,10 @@ class ChapterLoader(
return Observable.just(chapter) return Observable.just(chapter)
.doOnNext { chapter.state = ReaderChapter.State.Loading } .doOnNext { chapter.state = ReaderChapter.State.Loading }
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.flatMap { .flatMap { readerChapter ->
Timber.d("Loading pages for ${chapter.chapter.name}") Timber.d("Loading pages for ${chapter.chapter.name}")
val loader = getPageLoader(it) val loader = getPageLoader(readerChapter)
chapter.pageLoader = loader chapter.pageLoader = loader
loader.getPages().take(1).doOnNext { pages -> loader.getPages().take(1).doOnNext { pages ->

View File

@ -122,7 +122,7 @@ class ReaderProgressBar @JvmOverloads constructor(
*/ */
override fun setVisibility(visibility: Int) { override fun setVisibility(visibility: Int) {
super.setVisibility(visibility) super.setVisibility(visibility)
val isVisible = visibility == View.VISIBLE val isVisible = visibility == VISIBLE
if (isVisible) { if (isVisible) {
startAnimation() startAnimation()
} else { } else {
@ -134,7 +134,7 @@ class ReaderProgressBar @JvmOverloads constructor(
* Starts the rotation animation if needed. * Starts the rotation animation if needed.
*/ */
private fun startAnimation() { private fun startAnimation() {
if (visibility != View.VISIBLE || windowVisibility != View.VISIBLE || animation != null) { if (visibility != VISIBLE || windowVisibility != VISIBLE || animation != null) {
return return
} }
@ -153,7 +153,7 @@ class ReaderProgressBar @JvmOverloads constructor(
* Hides this progress bar with an optional fade out if [animate] is true. * Hides this progress bar with an optional fade out if [animate] is true.
*/ */
fun hide(animate: Boolean = false) { fun hide(animate: Boolean = false) {
if (visibility == View.GONE) return if (visibility == GONE) return
if (!animate) { if (!animate) {
gone() gone()

View File

@ -285,7 +285,7 @@ class PagerPageHolder(
return ReaderProgressBar(context, null).apply { return ReaderProgressBar(context, null).apply {
val size = 48.dpToPx val size = 48.dpToPx
layoutParams = FrameLayout.LayoutParams(size, size).apply { layoutParams = LayoutParams(size, size).apply {
gravity = Gravity.CENTER gravity = Gravity.CENTER
} }
} }
@ -300,7 +300,7 @@ class PagerPageHolder(
val config = viewer.config val config = viewer.config
subsamplingImageView = SubsamplingScaleImageView(context).apply { subsamplingImageView = SubsamplingScaleImageView(context).apply {
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) layoutParams = LayoutParams(MATCH_PARENT, MATCH_PARENT)
setMaxTileSize(viewer.activity.maxBitmapSize) setMaxTileSize(viewer.activity.maxBitmapSize)
setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER) setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
setDoubleTapZoomDuration(config.doubleTapAnimDuration) setDoubleTapZoomDuration(config.doubleTapAnimDuration)
@ -335,7 +335,7 @@ class PagerPageHolder(
if (imageView != null) return imageView!! if (imageView != null) return imageView!!
imageView = PhotoView(context, null).apply { imageView = PhotoView(context, null).apply {
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) layoutParams = LayoutParams(MATCH_PARENT, MATCH_PARENT)
adjustViewBounds = true adjustViewBounds = true
setZoomTransitionDuration(viewer.config.doubleTapAnimDuration) setZoomTransitionDuration(viewer.config.doubleTapAnimDuration)
setScaleLevels(1f, 2f, 3f) setScaleLevels(1f, 2f, 3f)
@ -362,7 +362,7 @@ class PagerPageHolder(
if (retryButton != null) return retryButton!! if (retryButton != null) return retryButton!!
retryButton = PagerButton(context, viewer).apply { retryButton = PagerButton(context, viewer).apply {
layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
gravity = Gravity.CENTER gravity = Gravity.CENTER
} }
setText(R.string.action_retry) setText(R.string.action_retry)
@ -399,7 +399,7 @@ class PagerPageHolder(
} }
PagerButton(context, viewer).apply { PagerButton(context, viewer).apply {
layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
setMargins(margins, margins, margins, margins) setMargins(margins, margins, margins, margins)
} }
setText(R.string.action_retry) setText(R.string.action_retry)
@ -413,7 +413,7 @@ class PagerPageHolder(
val imageUrl = page.imageUrl val imageUrl = page.imageUrl
if (imageUrl.orEmpty().startsWith("http")) { if (imageUrl.orEmpty().startsWith("http")) {
PagerButton(context, viewer).apply { PagerButton(context, viewer).apply {
layoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply { layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
setMargins(margins, margins, margins, margins) setMargins(margins, margins, margins, margins)
} }
setText(R.string.action_open_in_web_view) setText(R.string.action_open_in_web_view)

View File

@ -55,7 +55,7 @@ class PagerTransitionHolder(
* dynamically. * dynamically.
*/ */
private var pagesContainer = LinearLayout(context).apply { private var pagesContainer = LinearLayout(context).apply {
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT) layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
orientation = VERTICAL orientation = VERTICAL
gravity = Gravity.CENTER gravity = Gravity.CENTER
} }

View File

@ -209,7 +209,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
*/ */
private fun setChaptersInternal(chapters: ViewerChapters) { private fun setChaptersInternal(chapters: ViewerChapters) {
Timber.d("setChaptersInternal") Timber.d("setChaptersInternal")
var forceTransition = config.alwaysShowChapterTransition || adapter.items.getOrNull(pager.currentItem) is ChapterTransition val forceTransition = config.alwaysShowChapterTransition || adapter.items.getOrNull(pager.currentItem) is ChapterTransition
adapter.setChapters(chapters, forceTransition) adapter.setChapters(chapters, forceTransition)
// Layout the pager once a chapter is being set // Layout the pager once a chapter is being set

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.viewpager.widget.PagerAdapter
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
@ -93,8 +92,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
* Creates a new view for the item at the given [position]. * Creates a new view for the item at the given [position].
*/ */
override fun createView(container: ViewGroup, position: Int): View { override fun createView(container: ViewGroup, position: Int): View {
val item = items[position] return when (val item = items[position]) {
return when (item) {
is ReaderPage -> PagerPageHolder(viewer, item) is ReaderPage -> PagerPageHolder(viewer, item)
is ChapterTransition -> PagerTransitionHolder(viewer, item) is ChapterTransition -> PagerTransitionHolder(viewer, item)
else -> throw NotImplementedError("Holder for ${item.javaClass} not implemented") else -> throw NotImplementedError("Holder for ${item.javaClass} not implemented")
@ -113,6 +111,6 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
Timber.d("Position for ${view.item} not found") Timber.d("Position for ${view.item} not found")
} }
} }
return PagerAdapter.POSITION_NONE return POSITION_NONE
} }
} }

View File

@ -82,8 +82,7 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
* Returns the view type for the item at the given [position]. * Returns the view type for the item at the given [position].
*/ */
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
val item = items[position] return when (val item = items[position]) {
return when (item) {
is ReaderPage -> PAGE_VIEW is ReaderPage -> PAGE_VIEW
is ChapterTransition -> TRANSITION_VIEW is ChapterTransition -> TRANSITION_VIEW
else -> error("Unknown view type for ${item.javaClass}") else -> error("Unknown view type for ${item.javaClass}")

View File

@ -202,7 +202,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
*/ */
override fun setChapters(chapters: ViewerChapters) { override fun setChapters(chapters: ViewerChapters) {
Timber.d("setChapters") Timber.d("setChapters")
var forceTransition = config.alwaysShowChapterTransition || currentPage is ChapterTransition val forceTransition = config.alwaysShowChapterTransition || currentPage is ChapterTransition
adapter.setChapters(chapters, forceTransition) adapter.setChapters(chapters, forceTransition)
if (recycler.visibility == View.GONE) { if (recycler.visibility == View.GONE) {

View File

@ -53,9 +53,9 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
val map = TreeMap<Date, MutableList<MangaChapterHistory>> { d1, d2 -> d2.compareTo(d1) } val map = TreeMap<Date, MutableList<MangaChapterHistory>> { d1, d2 -> d2.compareTo(d1) }
val byDay = recents val byDay = recents
.groupByTo(map, { it.history.last_read.toDateKey() }) .groupByTo(map, { it.history.last_read.toDateKey() })
byDay.flatMap { byDay.flatMap { entry ->
val dateItem = DateSectionItem(it.key) val dateItem = DateSectionItem(entry.key)
it.value.map { HistoryItem(it, dateItem) } entry.value.map { HistoryItem(it, dateItem) }
} }
} }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -102,7 +102,7 @@ class HistoryPresenter : BasePresenter<HistoryController>() {
} }
val chapters = db.getChapters(manga).executeAsBlocking() val chapters = db.getChapters(manga).executeAsBlocking()
.sortedWith(Comparator<Chapter> { c1, c2 -> sortFunction(c1, c2) }) .sortedWith(Comparator { c1, c2 -> sortFunction(c1, c2) })
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id } val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }
return when (manga.sorting) { return when (manga.sorting) {

View File

@ -156,12 +156,12 @@ class UpdatesController : NucleusController<UpdatesControllerBinding, UpdatesPre
// Get item from position // Get item from position
val item = adapter.getItem(position) as? UpdatesItem ?: return false val item = adapter.getItem(position) as? UpdatesItem ?: return false
if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) { return if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) {
toggleSelection(position) toggleSelection(position)
return true true
} else { } else {
openChapter(item) openChapter(item)
return false false
} }
} }

View File

@ -63,15 +63,15 @@ class UpdatesPresenter(
val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) } val map = TreeMap<Date, MutableList<MangaChapter>> { d1, d2 -> d2.compareTo(d1) }
val byDay = mangaChapters val byDay = mangaChapters
.groupByTo(map, { it.chapter.date_fetch.toDateKey() }) .groupByTo(map, { it.chapter.date_fetch.toDateKey() })
byDay.flatMap { byDay.flatMap { entry ->
val dateItem = DateSectionItem(it.key) val dateItem = DateSectionItem(entry.key)
it.value entry.value
.sortedWith(compareBy({ it.chapter.date_fetch }, { it.chapter.chapter_number })).asReversed() .sortedWith(compareBy({ it.chapter.date_fetch }, { it.chapter.chapter_number })).asReversed()
.map { UpdatesItem(it.chapter, it.manga, dateItem) } .map { UpdatesItem(it.chapter, it.manga, dateItem) }
} }
} }
.doOnNext { .doOnNext { list ->
it.forEach { item -> list.forEach { item ->
// Find an active download for this chapter. // Find an active download for this chapter.
val download = downloadManager.queue.find { it.chapter.id == item.chapter.id } val download = downloadManager.queue.find { it.chapter.id == item.chapter.id }
@ -81,8 +81,8 @@ class UpdatesPresenter(
item.download = download item.download = download
} }
} }
setDownloadedChapters(it) setDownloadedChapters(list)
chapters = it chapters = list
} }
} }

View File

@ -101,8 +101,8 @@ class SettingsDownloadController : SettingsController() {
.subscribeUntilDestroy { isVisible = it } .subscribeUntilDestroy { isVisible = it }
preferences.downloadNewCategories().asObservable() preferences.downloadNewCategories().asObservable()
.subscribeUntilDestroy { .subscribeUntilDestroy { mutableSet ->
val selectedCategories = it val selectedCategories = mutableSet
.mapNotNull { id -> categories.find { it.id == id.toInt() } } .mapNotNull { id -> categories.find { it.id == id.toInt() } }
.sortedBy { it.order } .sortedBy { it.order }

View File

@ -118,8 +118,8 @@ class SettingsLibraryController : SettingsController() {
entries = categories.map { it.name }.toTypedArray() entries = categories.map { it.name }.toTypedArray()
entryValues = categories.map { it.id.toString() }.toTypedArray() entryValues = categories.map { it.id.toString() }.toTypedArray()
preferences.libraryUpdateCategories().asObservable() preferences.libraryUpdateCategories().asObservable()
.subscribeUntilDestroy { .subscribeUntilDestroy { mutableSet ->
val selectedCategories = it val selectedCategories = mutableSet
.mapNotNull { id -> categories.find { it.id == id.toInt() } } .mapNotNull { id -> categories.find { it.id == id.toInt() } }
.sortedBy { it.order } .sortedBy { it.order }

View File

@ -87,7 +87,7 @@ class SourcePresenter(
sharedObs.take(1), sharedObs.take(1),
sharedObs.skip(1).delay(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())) sharedObs.skip(1).delay(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()))
.distinctUntilChanged() .distinctUntilChanged()
.map { (sourceManager.get(it) as? CatalogueSource)?.let { SourceItem(it) } } .map { item -> (sourceManager.get(item) as? CatalogueSource)?.let { SourceItem(it) } }
.subscribeLatestCache(SourceController::setLastUsedSource) .subscribeLatestCache(SourceController::setLastUsedSource)
} }

View File

@ -149,9 +149,9 @@ open class BrowseSourcePresenter(
pagerSubscription?.let { remove(it) } pagerSubscription?.let { remove(it) }
pagerSubscription = pager.results() pagerSubscription = pager.results()
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.map { it.first to it.second.map { networkToLocalManga(it, sourceId) } } .map { pair -> pair.first to pair.second.map { networkToLocalManga(it, sourceId) } }
.doOnNext { initializeMangas(it.second) } .doOnNext { initializeMangas(it.second) }
.map { it.first to it.second.map { SourceItem(it, catalogueAsList) } } .map { pair -> pair.first to pair.second.map { SourceItem(it, catalogueAsList) } }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeReplay({ view, (page, mangas) -> .subscribeReplay({ view, (page, mangas) ->
view.onAddPage(page, mangas) view.onAddPage(page, mangas)
@ -292,17 +292,17 @@ open class BrowseSourcePresenter(
} }
private fun FilterList.toItems(): List<IFlexible<*>> { private fun FilterList.toItems(): List<IFlexible<*>> {
return mapNotNull { return mapNotNull { filter ->
when (it) { when (filter) {
is Filter.Header -> HeaderItem(it) is Filter.Header -> HeaderItem(filter)
is Filter.Separator -> SeparatorItem(it) is Filter.Separator -> SeparatorItem(filter)
is Filter.CheckBox -> CheckboxItem(it) is Filter.CheckBox -> CheckboxItem(filter)
is Filter.TriState -> TriStateItem(it) is Filter.TriState -> TriStateItem(filter)
is Filter.Text -> TextItem(it) is Filter.Text -> TextItem(filter)
is Filter.Select<*> -> SelectItem(it) is Filter.Select<*> -> SelectItem(filter)
is Filter.Group<*> -> { is Filter.Group<*> -> {
val group = GroupItem(it) val group = GroupItem(filter)
val subItems = it.state.mapNotNull { val subItems = filter.state.mapNotNull {
when (it) { when (it) {
is Filter.CheckBox -> CheckboxSectionItem(it) is Filter.CheckBox -> CheckboxSectionItem(it)
is Filter.TriState -> TriStateSectionItem(it) is Filter.TriState -> TriStateSectionItem(it)
@ -316,8 +316,8 @@ open class BrowseSourcePresenter(
group group
} }
is Filter.Sort -> { is Filter.Sort -> {
val group = SortGroup(it) val group = SortGroup(filter)
val subItems = it.values.map { val subItems = filter.values.map {
SortItem(it, group) SortItem(it, group)
} }
group.subItems = subItems group.subItems = subItems

View File

@ -43,6 +43,10 @@ class ProgressItem : AbstractFlexibleItem<ProgressItem.Holder>() {
return this === other return this === other
} }
override fun hashCode(): Int {
return loadMore.hashCode()
}
class Holder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter) { class Holder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter) {
val progressBar: ProgressBar = view.findViewById(R.id.progress_bar) val progressBar: ProgressBar = view.findViewById(R.id.progress_bar)

View File

@ -163,9 +163,9 @@ open class GlobalSearchPresenter(
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.onErrorReturn { MangasPage(emptyList(), false) } // Ignore timeouts or other exceptions .onErrorReturn { MangasPage(emptyList(), false) } // Ignore timeouts or other exceptions
.map { it.mangas.take(10) } // Get at most 10 manga from search result. .map { it.mangas.take(10) } // Get at most 10 manga from search result.
.map { it.map { networkToLocalManga(it, source.id) } } // Convert to local manga. .map { list -> list.map { networkToLocalManga(it, source.id) } } // Convert to local manga.
.doOnNext { fetchImage(it, source) } // Load manga covers. .doOnNext { fetchImage(it, source) } // Load manga covers.
.map { createCatalogueSearchItem(source, it.map { GlobalSearchCardItem(it) }) } .map { list -> createCatalogueSearchItem(source, list.map { GlobalSearchCardItem(it) }) }
}, 5) }, 5)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
// Update matching source with the obtained results // Update matching source with the obtained results
@ -198,9 +198,9 @@ open class GlobalSearchPresenter(
private fun initializeFetchImageSubscription() { private fun initializeFetchImageSubscription() {
fetchImageSubscription?.unsubscribe() fetchImageSubscription?.unsubscribe()
fetchImageSubscription = fetchImageSubject.observeOn(Schedulers.io()) fetchImageSubscription = fetchImageSubject.observeOn(Schedulers.io())
.flatMap { .flatMap { pair ->
val source = it.second val source = pair.second
Observable.from(it.first).filter { it.thumbnail_url == null && !it.initialized } Observable.from(pair.first).filter { it.thumbnail_url == null && !it.initialized }
.map { Pair(it, source) } .map { Pair(it, source) }
.concatMap { getMangaDetailsObservable(it.first, it.second) } .concatMap { getMangaDetailsObservable(it.first, it.second) }
.map { Pair(source as CatalogueSource, it) } .map { Pair(source as CatalogueSource, it) }

View File

@ -123,11 +123,11 @@ object ChapterRecognition {
if (alpha.contains("special")) if (alpha.contains("special"))
return .97f return .97f
if (alpha[0] == '.') { return if (alpha[0] == '.') {
// Take value after (.) // Take value after (.)
return parseAlphaPostFix(alpha[1]) parseAlphaPostFix(alpha[1])
} else { } else {
return parseAlphaPostFix(alpha[0]) parseAlphaPostFix(alpha[0])
} }
} }

View File

@ -85,7 +85,7 @@ object DiskUtil {
*/ */
fun buildValidFilename(origName: String): String { fun buildValidFilename(origName: String): String {
val name = origName.trim('.', ' ') val name = origName.trim('.', ' ')
if (name.isNullOrEmpty()) { if (name.isEmpty()) {
return "(invalid)" return "(invalid)"
} }
val sb = StringBuilder(name.length) val sb = StringBuilder(name.length)

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.widget
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.annotation.StringRes import androidx.annotation.StringRes
@ -77,6 +76,6 @@ class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
data class Action( data class Action(
@StringRes val resId: Int, @StringRes val resId: Int,
val listener: View.OnClickListener val listener: OnClickListener
) )
} }

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.widget
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -160,7 +159,7 @@ open class ExtendedNavigationView @JvmOverloads constructor(
*/ */
abstract inner class Adapter(private val items: List<Item>) : RecyclerView.Adapter<Holder>() { abstract inner class Adapter(private val items: List<Item>) : RecyclerView.Adapter<Holder>() {
private val onClick = View.OnClickListener { private val onClick = OnClickListener {
val pos = recycler.getChildAdapterPosition(it) val pos = recycler.getChildAdapterPosition(it)
val item = items[pos] val item = items[pos]
onItemClicked(item) onItemClicked(item)

View File

@ -76,7 +76,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
/** /**
* Clickable view holder. * Clickable view holder.
*/ */
abstract class ClickableHolder(view: View, listener: View.OnClickListener?) : Holder(view) { abstract class ClickableHolder(view: View, listener: OnClickListener?) : Holder(view) {
init { init {
itemView.setOnClickListener(listener) itemView.setOnClickListener(listener)
} }
@ -85,7 +85,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
/** /**
* Radio view holder. * Radio view holder.
*/ */
class RadioHolder(parent: ViewGroup, listener: View.OnClickListener?) : class RadioHolder(parent: ViewGroup, listener: OnClickListener?) :
ClickableHolder(parent.inflate(TR.layout.navigation_view_radio), listener) { ClickableHolder(parent.inflate(TR.layout.navigation_view_radio), listener) {
val radio: RadioButton = itemView.findViewById(TR.id.nav_view_item) val radio: RadioButton = itemView.findViewById(TR.id.nav_view_item)
@ -94,7 +94,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
/** /**
* Checkbox view holder. * Checkbox view holder.
*/ */
class CheckboxHolder(parent: ViewGroup, listener: View.OnClickListener?) : class CheckboxHolder(parent: ViewGroup, listener: OnClickListener?) :
ClickableHolder(parent.inflate(TR.layout.navigation_view_checkbox), listener) { ClickableHolder(parent.inflate(TR.layout.navigation_view_checkbox), listener) {
val check: CheckBox = itemView.findViewById(TR.id.nav_view_item) val check: CheckBox = itemView.findViewById(TR.id.nav_view_item)
@ -103,7 +103,7 @@ open class SimpleNavigationView @JvmOverloads constructor(
/** /**
* Multi state view holder. * Multi state view holder.
*/ */
class MultiStateHolder(parent: ViewGroup, listener: View.OnClickListener?) : class MultiStateHolder(parent: ViewGroup, listener: OnClickListener?) :
ClickableHolder(parent.inflate(TR.layout.navigation_view_checkedtext), listener) { ClickableHolder(parent.inflate(TR.layout.navigation_view_checkedtext), listener) {
val text: CheckedTextView = itemView.findViewById(TR.id.nav_view_item) val text: CheckedTextView = itemView.findViewById(TR.id.nav_view_item)

View File

@ -33,7 +33,7 @@
android:layout_height="@dimen/material_component_lists_single_line_with_avatar_height" android:layout_height="@dimen/material_component_lists_single_line_with_avatar_height"
android:layout_gravity="end" android:layout_gravity="end"
android:scaleType="center" android:scaleType="center"
android:tint="?android:attr/textColorPrimary" app:srcCompat="@drawable/ic_reorder_grey_24dp"
app:srcCompat="@drawable/ic_reorder_grey_24dp" /> app:tint="?android:attr/textColorPrimary" />
</FrameLayout> </FrameLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -28,9 +27,9 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:paddingBottom="@dimen/fab_list_padding"
android:clipToPadding="false" android:clipToPadding="false"
android:descendantFocusability="blocksDescendants" android:descendantFocusability="blocksDescendants"
android:paddingBottom="@dimen/fab_list_padding"
tools:listitem="@layout/chapters_item" /> tools:listitem="@layout/chapters_item" />
</eu.kanade.tachiyomi.widget.ThemedSwipeRefreshLayout> </eu.kanade.tachiyomi.widget.ThemedSwipeRefreshLayout>
@ -54,7 +53,7 @@
android:id="@+id/fab" android:id="@+id/fab"
style="@style/Theme.Widget.FAB" style="@style/Theme.Widget.FAB"
android:text="@string/action_resume" android:text="@string/action_resume"
app:layout_anchor="@id/recycler" app:icon="@drawable/ic_play_arrow_24dp"
app:icon="@drawable/ic_play_arrow_24dp" /> app:layout_anchor="@id/recycler" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -5,8 +5,8 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight" android:layout_height="?android:attr/listPreferredItemHeight"
android:background="@drawable/list_item_selector" android:background="@drawable/list_item_selector"
android:paddingEnd="16dp" android:paddingStart="16dp"
android:paddingStart="16dp"> android:paddingEnd="16dp">
<TextView <TextView
android:id="@+id/chapter_title" android:id="@+id/chapter_title"
@ -29,8 +29,8 @@
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
app:layout_constraintEnd_toStartOf="@+id/download_text"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/download_text"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
tools:text="22/02/2016 • Scanlator • Page: 45" /> tools:text="22/02/2016 • Scanlator • Page: 45" />

View File

@ -10,11 +10,11 @@
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:elevation="2dp"
android:theme="?attr/actionBarTheme" android:theme="?attr/actionBarTheme"
android:visibility="gone" android:visibility="gone"
android:elevation="2dp" app:contentInsetEnd="8dp"
app:contentInsetStart="8dp" app:contentInsetStart="8dp">
app:contentInsetEnd="8dp">
<androidx.appcompat.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/common_action_menu" android:id="@+id/common_action_menu"

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nnf_item_container" android:id="@+id/nnf_item_container"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -18,8 +19,8 @@
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/nnf_ic_file_folder" android:src="@drawable/nnf_ic_file_folder"
android:tint="?attr/colorAccent"
android:visibility="visible" android:visibility="visible"
app:tint="?attr/colorAccent"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
<TextView <TextView

View File

@ -14,11 +14,11 @@
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_gravity="start" android:layout_gravity="start"
android:scaleType="center" android:scaleType="center"
android:tint="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_reorder_grey_24dp" /> app:srcCompat="@drawable/ic_reorder_grey_24dp"
app:tint="?android:attr/textColorPrimary" />
<TextView <TextView
android:id="@+id/manga_full_title" android:id="@+id/manga_full_title"

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@ -80,8 +80,8 @@
style="@style/TextAppearance.Medium.Title" style="@style/TextAppearance.Medium.Title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="8dp"
android:maxLines="2" android:maxLines="2"
android:paddingBottom="8dp"
android:text="@string/manga_info_full_title_label" android:text="@string/manga_info_full_title_label"
android:textIsSelectable="false" android:textIsSelectable="false"
app:autoSizeMaxTextSize="20sp" app:autoSizeMaxTextSize="20sp"

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall" android:layout_height="?attr/listPreferredItemHeightSmall"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:focusable="true" android:focusable="true"
android:paddingStart="?attr/listPreferredItemPaddingStart" android:paddingStart="?attr/listPreferredItemPaddingStart"

View File

@ -3,6 +3,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:baselineAligned="false"
android:focusable="true" android:focusable="true"
android:paddingStart="?attr/listPreferredItemPaddingStart" android:paddingStart="?attr/listPreferredItemPaddingStart"
android:paddingEnd="?attr/listPreferredItemPaddingEnd"> android:paddingEnd="?attr/listPreferredItemPaddingEnd">

View File

@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="@dimen/dialog_content_padding" android:paddingStart="@dimen/dialog_content_padding"
android:paddingTop="@dimen/dialog_margin_top_content" android:paddingTop="@dimen/dialog_margin_top_content"

View File

@ -19,8 +19,8 @@
<ImageView <ImageView
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:tint="@color/md_white_1000_54" app:srcCompat="@drawable/ic_photo_24dp"
app:srcCompat="@drawable/ic_photo_24dp" /> app:tint="@color/md_white_1000_54" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -44,8 +44,8 @@
<ImageView <ImageView
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:tint="@color/md_white_1000_54" app:srcCompat="@drawable/ic_share_24dp"
app:srcCompat="@drawable/ic_share_24dp" /> app:tint="@color/md_white_1000_54" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -69,8 +69,8 @@
<ImageView <ImageView
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:tint="@color/md_white_1000_54" app:srcCompat="@drawable/ic_file_download_black_24dp"
app:srcCompat="@drawable/ic_file_download_black_24dp" /> app:tint="@color/md_white_1000_54" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -260,9 +260,9 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/pref_webtoon_side_padding" android:text="@string/pref_webtoon_side_padding"
app:layout_constraintBaseline_toBaselineOf="@id/webtoon_side_padding"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/verticalcenter" app:layout_constraintRight_toLeftOf="@id/verticalcenter" />
app:layout_constraintBaseline_toBaselineOf="@id/webtoon_side_padding"/>
<androidx.appcompat.widget.AppCompatSpinner <androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/webtoon_side_padding" android:id="@+id/webtoon_side_padding"

View File

@ -21,10 +21,10 @@
android:alpha="0.5" android:alpha="0.5"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@drawable/ic_drag_pill_24dp" android:src="@drawable/ic_drag_pill_24dp"
android:tint="?attr/colorOnBackground"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
app:tint="?attr/colorOnBackground" />
<Button <Button
android:id="@+id/reset_btn" android:id="@+id/reset_btn"

View File

@ -98,6 +98,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:ellipsize="end" android:ellipsize="end"
android:fontFamily="@font/ptsans_narrow_bold"
android:lineSpacingExtra="-4dp" android:lineSpacingExtra="-4dp"
android:maxLines="2" android:maxLines="2"
android:padding="8dp" android:padding="8dp"
@ -105,7 +106,6 @@
android:shadowDx="0" android:shadowDx="0"
android:shadowDy="0" android:shadowDy="0"
android:shadowRadius="4" android:shadowRadius="4"
android:fontFamily="@font/ptsans_narrow_bold"
tools:text="Sample name" /> tools:text="Sample name" />
<ProgressBar <ProgressBar

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">

View File

@ -13,9 +13,9 @@
android:id="@+id/recycler" android:id="@+id/recycler"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"
android:descendantFocusability="blocksDescendants" android:descendantFocusability="blocksDescendants"
android:paddingBottom="?attr/actionBarSize" android:paddingBottom="?attr/actionBarSize"
android:clipToPadding="false"
tools:listitem="@layout/updates_item" /> tools:listitem="@layout/updates_item" />
<eu.kanade.tachiyomi.widget.ActionToolbar <eu.kanade.tachiyomi.widget.ActionToolbar

View File

@ -4,8 +4,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/material_component_lists_two_line_height" android:layout_height="@dimen/material_component_lists_two_line_height"
android:paddingEnd="16dp" android:background="@drawable/list_item_selector"
android:background="@drawable/list_item_selector"> android:paddingEnd="16dp">
<ImageView <ImageView
android:id="@+id/manga_cover" android:id="@+id/manga_cover"

View File

@ -40,7 +40,7 @@ import uy.kohesive.injekt.api.addSingleton
* Test class for the [BackupManager]. * Test class for the [BackupManager].
* Note that this does not include the backup create/restore services. * Note that this does not include the backup create/restore services.
*/ */
@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP)) @Config(constants = BuildConfig::class, sdk = [Build.VERSION_CODES.LOLLIPOP])
@RunWith(CustomRobolectricGradleTestRunner::class) @RunWith(CustomRobolectricGradleTestRunner::class)
class BackupTest { class BackupTest {
// Create root object // Create root object

View File

@ -72,7 +72,7 @@ class CategoryTest {
// It should not have 0 as id // It should not have 0 as id
val c = db.getCategories().executeAsBlocking()[0] val c = db.getCategories().executeAsBlocking()[0]
assertThat(c.id).isNotZero() assertThat(c.id).isNotZero
// Add a manga to a category // Add a manga to a category
val m = db.getMangas().executeAsBlocking()[0] val m = db.getMangas().executeAsBlocking()[0]