diff --git a/app/build.gradle b/app/build.gradle
index 141e7ec695..be30aff7f0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -29,17 +29,17 @@ ext {
}
android {
- compileSdkVersion 27
- buildToolsVersion '28.0.3'
+ compileSdkVersion 29
+ buildToolsVersion '29.0.2'
publishNonDefault true
defaultConfig {
applicationId "eu.kanade.tachiyomi"
- minSdkVersion 16
- targetSdkVersion 27
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- versionCode 41
- versionName "0.8.4"
+ minSdkVersion 21
+ targetSdkVersion 29
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ versionCode 42
+ versionName "0.9.0"
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
@@ -60,6 +60,9 @@ android {
versionNameSuffix "-${getCommitCount()}"
applicationIdSuffix ".debug"
}
+ release {
+ applicationIdSuffix = '.j2k'
+ }
}
flavorDimensions "default"
@@ -73,7 +76,6 @@ android {
dimension "default"
}
dev {
- minSdkVersion 21
resConfigs "en", "xxhdpi"
dimension "default"
}
@@ -92,6 +94,15 @@ android {
checkReleaseBuilds false
}
+ compileOptions {
+ sourceCompatibility = 1.8
+ targetCompatibility = 1.8
+ }
+
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+
}
dependencies {
@@ -101,35 +112,35 @@ dependencies {
implementation 'com.github.inorichi:junrar-android:634c1f5'
// Android support library
- final support_library_version = '27.0.2'
- implementation "com.android.support:support-v4:$support_library_version"
- implementation "com.android.support:appcompat-v7:$support_library_version"
- implementation "com.android.support:cardview-v7:$support_library_version"
- implementation "com.android.support:design:$support_library_version"
- implementation "com.android.support:recyclerview-v7:$support_library_version"
- implementation "com.android.support:preference-v7:$support_library_version"
- implementation "com.android.support:support-annotations:$support_library_version"
- implementation "com.android.support:customtabs:$support_library_version"
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation 'androidx.preference:preference:1.1.0'
+ implementation 'androidx.annotation:annotation:1.1.0'
+ implementation 'androidx.browser:browser:1.0.0'
- implementation 'com.android.support.constraint:constraint-layout:1.1.2'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'com.android.support:multidex:1.0.3'
+ implementation 'androidx.multidex:multidex:2.0.1'
- standardImplementation 'com.google.firebase:firebase-core:11.8.0'
+ standardImplementation 'com.google.firebase:firebase-core:17.2.1'
// ReactiveX
implementation 'io.reactivex:rxandroid:1.2.1'
- implementation 'io.reactivex:rxjava:1.3.6'
+ implementation 'io.reactivex:rxjava:1.3.8'
implementation 'com.jakewharton.rxrelay:rxrelay:1.2.0'
implementation 'com.f2prateek.rx.preferences:rx-preferences:1.0.2'
- implementation 'com.github.pwittchen:reactivenetwork:0.7.0'
+ implementation 'com.github.pwittchen:reactivenetwork:0.13.0'
// Network client
- implementation "com.squareup.okhttp3:okhttp:3.10.0"
- implementation 'com.squareup.okio:okio:1.14.0'
+ final okhttp_version = "4.2.1"
+ implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
+ implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
+ implementation 'com.squareup.okio:okio:2.4.0'
// REST
- final retrofit_version = '2.3.0'
+ final retrofit_version = '2.6.2'
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "com.squareup.retrofit2:adapter-rxjava:$retrofit_version"
@@ -146,17 +157,17 @@ dependencies {
implementation 'com.github.inorichi:unifile:e9ee588'
// HTML parser
- implementation 'org.jsoup:jsoup:1.10.2'
+ implementation 'org.jsoup:jsoup:1.12.1'
// Job scheduling
implementation 'com.evernote:android-job:1.2.5'
- implementation 'com.google.android.gms:play-services-gcm:11.8.0'
+ implementation 'com.google.android.gms:play-services-gcm:17.0.0'
// Changelog
implementation 'com.github.gabrielemariotti.changeloglib:changelog:2.1.0'
// Database
- implementation 'android.arch.persistence:db:1.0.0'
+ implementation 'androidx.sqlite:sqlite:2.0.1'
implementation 'com.github.inorichi.storio:storio-common:8be19de@aar'
implementation 'com.github.inorichi.storio:storio-sqlite:8be19de@aar'
implementation 'io.requery:sqlite-android:3.25.2'
@@ -170,16 +181,16 @@ dependencies {
implementation "com.github.inorichi.injekt:injekt-core:65b0440"
// Image library
- final glide_version = '4.6.1'
+ final glide_version = '4.10.0'
implementation "com.github.bumptech.glide:glide:$glide_version"
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
// Transformations
- implementation 'jp.wasabeef:glide-transformations:3.1.1'
+ implementation 'jp.wasabeef:glide-transformations:4.0.0'
// Logging
- implementation 'com.jakewharton.timber:timber:4.6.1'
+ implementation 'com.jakewharton.timber:timber:4.7.1'
// Crash reports
implementation 'ch.acra:acra:4.9.2'
@@ -190,24 +201,24 @@ dependencies {
// UI
implementation 'com.dmitrymalkovich.android:material-design-dimens:1.4'
implementation 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
- implementation 'eu.davidea:flexible-adapter:5.0.0-rc4'
- implementation 'eu.davidea:flexible-adapter-ui:1.0.0-b1'
+ implementation 'eu.davidea:flexible-adapter:5.1.0'
+ implementation 'eu.davidea:flexible-adapter-ui:1.0.0'
implementation 'com.nononsenseapps:filepicker:2.5.2'
implementation 'com.github.amulyakhare:TextDrawable:558677e'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'me.zhanghai.android.systemuihelper:library:1.0.0'
- implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.0.4'
+ implementation 'com.nightlynexus.viewstatepageradapter:viewstatepageradapter:1.1.0'
implementation 'com.github.mthli:Slice:v1.2'
implementation 'me.gujun.android.taggroup:library:1.4@aar'
- implementation 'com.github.chrisbanes:PhotoView:2.1.3'
- implementation 'com.github.inorichi:DirectionalViewPager:3acc51a'
+ implementation 'com.github.chrisbanes:PhotoView:2.3.0'
+ implementation 'com.github.carlosesco:DirectionalViewPager:a844dbca0a'
// Conductor
implementation 'com.bluelinelabs:conductor:2.1.5'
implementation ("com.bluelinelabs:conductor-support:2.1.5") {
exclude group: "com.android.support"
}
- implementation 'com.github.inorichi:conductor-support-preference:27.0.2'
+ implementation project(":j2k-preference")
// RxBindings
final rxbindings_version = '1.0.1'
@@ -228,18 +239,19 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- final coroutines_version = '0.22.2'
+ final coroutines_version = '1.3.2'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
}
buildscript {
- ext.kotlin_version = '1.2.71'
+ ext.kotlin_version = '1.3.50'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
}
@@ -247,12 +259,6 @@ repositories {
mavenCentral()
}
-kotlin {
- experimental {
- coroutines 'enable'
- }
-}
-
androidExtensions {
experimental = true
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e13d89ba7c..3861b81dac 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,7 +9,10 @@
+
+
+
+ android:theme="@style/Theme.Tachiyomi"
+ android:networkSecurityConfig="@xml/network_security_config">
@@ -43,6 +47,9 @@
+
diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt
index ef4564f777..7a2688b924 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/App.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi
import android.app.Application
import android.content.Context
import android.content.res.Configuration
-import android.support.multidex.MultiDex
+import androidx.multidex.MultiDex
import com.evernote.android.job.JobManager
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
index 3a46947180..7fc1bcaf94 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
@@ -39,7 +39,7 @@ object Migrations {
if (oldDir.exists()) {
val destDir = context.getExternalFilesDir("covers")
if (destDir != null) {
- oldDir.listFiles().forEach {
+ oldDir.listFiles()?.forEach {
it.renameTo(File(destDir, it.name))
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt
index 0d993a7019..d7095642db 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreateService.kt
@@ -57,7 +57,8 @@ class BackupCreateService : IntentService(NAME) {
val uri = intent.getParcelableExtra(BackupConst.EXTRA_URI)
val flags = intent.getIntExtra(EXTRA_FLAGS, 0)
// Create backup
- backupManager.createBackup(uri, flags, false)
+ if (uri != null)
+ backupManager.createBackup(uri, flags, false)
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
index db6866e289..365dd8804f 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt
@@ -160,9 +160,9 @@ class BackupRestoreService : Service() {
* @return the start value of the command.
*/
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(BackupConst.EXTRA_URI)
+ val uri = intent.getParcelableExtra(BackupConst.EXTRA_URI) ?: return START_NOT_STICKY
// Unsubscribe from any previous subscription if needed.
subscription?.unsubscribe()
@@ -175,7 +175,7 @@ class BackupRestoreService : Service() {
.subscribeOn(Schedulers.from(executor))
.subscribe()
- return Service.START_NOT_STICKY
+ return START_NOT_STICKY
}
/**
@@ -189,7 +189,7 @@ class BackupRestoreService : Service() {
return Observable.just(Unit)
.map {
- val reader = JsonReader(contentResolver.openInputStream(uri).bufferedReader())
+ val reader = JsonReader(contentResolver.openInputStream(uri)!!.bufferedReader())
val json = JsonParser().parse(reader).asJsonObject
// Get parser version
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt
index 4868dec1ec..f606e6640c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt
@@ -11,6 +11,8 @@ import eu.kanade.tachiyomi.util.DiskUtil
import eu.kanade.tachiyomi.util.saveTo
import okhttp3.Response
import okio.Okio
+import okio.buffer
+import okio.sink
import rx.Observable
import uy.kohesive.injekt.injectLazy
import java.io.File
@@ -126,7 +128,7 @@ class ChapterCache(private val context: Context) {
editor = diskCache.edit(key) ?: return
// Write chapter urls to cache.
- Okio.buffer(Okio.sink(editor.newOutputStream(0))).use {
+ editor.newOutputStream(0).sink().buffer().use {
it.write(cachedValue.toByteArray())
it.flush()
}
@@ -186,12 +188,12 @@ class ChapterCache(private val context: Context) {
editor = diskCache.edit(key) ?: throw IOException("Unable to edit key")
// Get OutputStream and write image with Okio.
- response.body()!!.source().saveTo(editor.newOutputStream(0))
+ response.body!!.source().saveTo(editor.newOutputStream(0))
diskCache.flush()
editor.commit()
} finally {
- response.body()?.close()
+ response.body?.close()
editor?.abortUnlessCommitted()
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.kt
index 4586f8c182..96db0846bd 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/cache/CoverCache.kt
@@ -1,7 +1,11 @@
package eu.kanade.tachiyomi.data.cache
import android.content.Context
+import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.util.DiskUtil
+import eu.kanade.tachiyomi.util.launchUI
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.delay
import java.io.File
import java.io.IOException
import java.io.InputStream
@@ -60,8 +64,7 @@ class CoverCache(private val context: Context) {
return false
// Remove file.
- val file = getCoverFile(thumbnailUrl!!)
+ val file = getCoverFile(thumbnailUrl)
return file.exists() && file.delete()
}
-
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt
index 6148e49ae7..711cefbcb3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/DatabaseHelper.kt
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.database
-import android.arch.persistence.db.SupportSQLiteOpenHelper
+import androidx.sqlite.db.SupportSQLiteOpenHelper
import android.content.Context
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite
import eu.kanade.tachiyomi.data.database.mappers.*
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
index cf65b6a1d6..e8c1a4ed3a 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database
-import android.arch.persistence.db.SupportSQLiteDatabase
-import android.arch.persistence.db.SupportSQLiteOpenHelper
+import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.sqlite.db.SupportSQLiteOpenHelper
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
@@ -18,7 +18,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
/**
* Version of the database.
*/
- const val DATABASE_VERSION = 8
+ const val DATABASE_VERSION = 9
}
override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
@@ -67,6 +67,9 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
db.execSQL(MangaTable.createLibraryIndexQuery)
db.execSQL(ChapterTable.createUnreadChaptersIndexQuery)
}
+ if (oldVersion < 9) {
+ db.execSQL(MangaTable.addHideTitle)
+ }
}
override fun onConfigure(db: SupportSQLiteDatabase) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt
index 9ad72908fe..ac89bbc209 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/MangaTypeMapping.kt
@@ -17,6 +17,7 @@ import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_CHAPTER_FLAGS
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_DESCRIPTION
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_FAVORITE
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_GENRE
+import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_HIDE_TITLE
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_ID
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_INITIALIZED
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_LAST_UPDATE
@@ -61,6 +62,7 @@ class MangaPutResolver : DefaultPutResolver() {
put(COL_LAST_UPDATE, obj.last_update)
put(COL_INITIALIZED, obj.initialized)
put(COL_VIEWER, obj.viewer)
+ put(COL_HIDE_TITLE, obj.hide_title)
put(COL_CHAPTER_FLAGS, obj.chapter_flags)
}
}
@@ -82,6 +84,7 @@ interface BaseMangaGetResolver {
initialized = cursor.getInt(cursor.getColumnIndex(COL_INITIALIZED)) == 1
viewer = cursor.getInt(cursor.getColumnIndex(COL_VIEWER))
chapter_flags = cursor.getInt(cursor.getColumnIndex(COL_CHAPTER_FLAGS))
+ hide_title = cursor.getInt(cursor.getColumnIndex(COL_HIDE_TITLE)) == 1
}
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt
index 1782662dce..c7dff69dfa 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt
@@ -16,6 +16,8 @@ interface Manga : SManga {
var chapter_flags: Int
+ var hide_title: Boolean
+
fun setChapterOrder(order: Int) {
setFlags(order, SORT_MASK)
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt
index 977864c249..b5a4754486 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt
@@ -1,5 +1,7 @@
package eu.kanade.tachiyomi.data.database.models
+import eu.kanade.tachiyomi.source.model.SManga
+
open class MangaImpl : Manga {
override var id: Long? = null
@@ -32,6 +34,14 @@ open class MangaImpl : Manga {
override var chapter_flags: Int = 0
+ override var hide_title: Boolean = false
+
+ override fun copyFrom(other: SManga) {
+ if (other is MangaImpl && (other as MangaImpl)::title.isInitialized && other.title != title)
+ title = other.title
+ super.copyFrom(other)
+ }
+
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt
index b6cb58670d..c10d0b9367 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/ChapterQueries.kt
@@ -52,6 +52,14 @@ interface ChapterQueries : DbProvider {
.build())
.prepare()
+ fun getChapter(url: String, mangaId: Long) = db.get()
+ .`object`(Chapter::class.java)
+ .withQuery(Query.builder()
+ .table(ChapterTable.TABLE)
+ .where("${ChapterTable.COL_URL} = ? AND ${ChapterTable.COL_MANGA_ID} = ?")
+ .whereArgs(url, mangaId)
+ .build())
+ .prepare()
fun insertChapter(chapter: Chapter) = db.put().`object`(chapter).prepare()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt
index fc17e36ec2..e9650347aa 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/HistoryQueries.kt
@@ -22,10 +22,10 @@ interface HistoryQueries : DbProvider {
* Returns history of recent manga containing last read chapter
* @param date recent date range
*/
- fun getRecentManga(date: Date) = db.get()
+ fun getRecentManga(date: Date, offset: Int = 0) = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(RawQuery.builder()
- .query(getRecentMangasQuery())
+ .query(getRecentMangasQuery(offset))
.args(date.time)
.observesTables(HistoryTable.TABLE)
.build())
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
index a64a097925..0da34ffe0d 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt
@@ -82,6 +82,11 @@ interface MangaQueries : DbProvider {
.withPutResolver(MangaViewerPutResolver())
.prepare()
+ fun updateMangaHideTitle(manga: Manga) = db.put()
+ .`object`(manga)
+ .withPutResolver(MangaHideTitlePutResolver())
+ .prepare()
+
fun updateMangaTitle(manga: Manga) = db.put()
.`object`(manga)
.withPutResolver(MangaTitlePutResolver())
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
index daa5c48fd0..83a9866b09 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
@@ -47,7 +47,7 @@ fun getRecentsQuery() = """
* and are read after the given time period
* @return return limit is 25
*/
-fun getRecentMangasQuery() = """
+fun getRecentMangasQuery(offset: Int = 0) = """
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
JOIN ${Chapter.TABLE}
@@ -62,7 +62,7 @@ fun getRecentMangasQuery() = """
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ? AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
- LIMIT 25
+ LIMIT 25 OFFSET $offset
"""
fun getHistoryByMangaId() = """
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryLastReadPutResolver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryLastReadPutResolver.kt
index b9d583d4c9..f1d68c22a9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryLastReadPutResolver.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/HistoryLastReadPutResolver.kt
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.database.resolvers
import android.content.ContentValues
-import android.support.annotation.NonNull
+import androidx.annotation.NonNull
import com.pushtorefresh.storio.sqlite.StorIOSQLite
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
import com.pushtorefresh.storio.sqlite.queries.Query
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaHideTitlePutResolver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaHideTitlePutResolver.kt
new file mode 100644
index 0000000000..48ead1a5e6
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/MangaHideTitlePutResolver.kt
@@ -0,0 +1,33 @@
+package eu.kanade.tachiyomi.data.database.resolvers
+
+import android.content.ContentValues
+import com.pushtorefresh.storio.sqlite.StorIOSQLite
+import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
+import com.pushtorefresh.storio.sqlite.operations.put.PutResult
+import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
+import eu.kanade.tachiyomi.data.database.inTransactionReturn
+import eu.kanade.tachiyomi.data.database.models.LibraryManga
+import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.data.database.tables.MangaTable
+
+class MangaHideTitlePutResolver : PutResolver() {
+
+ override fun performPut(db: StorIOSQLite, manga: Manga) = db.inTransactionReturn {
+ val updateQuery = mapToUpdateQuery(manga)
+ val contentValues = mapToContentValues(manga)
+
+ val numberOfRowsUpdated = db.lowLevel().update(updateQuery, contentValues)
+ PutResult.newUpdateResult(numberOfRowsUpdated, updateQuery.table())
+ }
+
+ fun mapToUpdateQuery(manga: Manga) = UpdateQuery.builder()
+ .table(MangaTable.TABLE)
+ .where("${MangaTable.COL_ID} = ?")
+ .whereArgs(manga.id)
+ .build()
+
+ fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
+ put(MangaTable.COL_HIDE_TITLE, manga.hide_title)
+ }
+
+}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt
index 2b1ff7458d..c642536b01 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt
@@ -38,6 +38,8 @@ object MangaTable {
const val COL_CATEGORY = "category"
+ const val COL_HIDE_TITLE = "hideTitle"
+
val createTableQuery: String
get() = """CREATE TABLE $TABLE(
$COL_ID INTEGER NOT NULL PRIMARY KEY,
@@ -54,6 +56,7 @@ object MangaTable {
$COL_LAST_UPDATE LONG,
$COL_INITIALIZED BOOLEAN NOT NULL,
$COL_VIEWER INTEGER NOT NULL,
+ $COL_HIDE_TITLE INTEGER NOT NULL,
$COL_CHAPTER_FLAGS INTEGER NOT NULL
)"""
@@ -63,4 +66,7 @@ object MangaTable {
val createLibraryIndexQuery: String
get() = "CREATE INDEX library_${COL_FAVORITE}_index ON $TABLE($COL_FAVORITE) " +
"WHERE $COL_FAVORITE = 1"
+
+ val addHideTitle: String
+ get() = "ALTER TABLE $TABLE ADD COLUMN $COL_HIDE_TITLE INTEGER DEFAULT 0"
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
index 4e23599d0c..f490956eec 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
@@ -9,6 +9,9 @@ import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page
+import eu.kanade.tachiyomi.util.launchNow
+import eu.kanade.tachiyomi.util.launchUI
+import kotlinx.coroutines.delay
import rx.Observable
import uy.kohesive.injekt.injectLazy
@@ -181,6 +184,7 @@ class DownloadManager(context: Context) {
* @param source the source of the manga.
*/
fun deleteManga(manga: Manga, source: Source) {
+ downloader.clearQueue(manga, true)
queue.remove(manga)
provider.findMangaDir(manga, source)?.delete()
cache.removeManga(manga)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
index af9d84c0af..dbc7ef0fe8 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadNotifier.kt
@@ -2,7 +2,8 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context
import android.graphics.BitmapFactory
-import android.support.v4.app.NotificationCompat
+import androidx.core.app.NotificationCompat
+import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
@@ -168,7 +169,8 @@ internal class DownloadNotifier(private val context: Context) {
setSmallIcon(android.R.drawable.stat_sys_download_done)
setAutoCancel(true)
clearActions()
- setContentIntent(NotificationReceiver.openChapterPendingBroadcast(context, download.manga, download.chapter))
+ setContentIntent(NotificationReceiver.openChapterPendingActivity(context, download
+ .manga, download.chapter))
setProgress(0, 0, false)
}
@@ -214,9 +216,11 @@ internal class DownloadNotifier(private val context: Context) {
setContentTitle(chapter ?: context.getString(R.string.download_notifier_downloader_title))
setContentText(error ?: context.getString(R.string.download_notifier_unkown_error))
setSmallIcon(android.R.drawable.stat_sys_warning)
+ setCategory(NotificationCompat.CATEGORY_ERROR)
clearActions()
- setAutoCancel(false)
+ setAutoCancel(true)
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
+ color = ContextCompat.getColor(context, R.color.colorAccentLight)
setProgress(0, 0, false)
}
notification.show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt
index 894b9e493d..a7ce329a8a 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt
@@ -90,6 +90,22 @@ class DownloadPendingDeleter(context: Context) {
}
}
+ /**
+ * Returns the list of chapters to be deleted grouped by its manga.
+ *
+ * Note: the returned list of manga and chapters only contain basic information needed by the
+ * downloader, so don't use them for anything else.
+ */
+ @Synchronized
+ fun getPendingChapters(manga: Manga): List? {
+ val entries = decodeAll()
+ prefs.edit().clear().apply()
+ lastAddedEntry = null
+
+ val entry = entries.find { it.manga.id == manga.id }
+ return entry?.chapters?.map { it.toModel() }
+ }
+
/**
* Decodes all the chapters from preferences.
*/
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt
index 8fdb4f6267..860dbf145d 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt
@@ -9,7 +9,7 @@ import android.net.NetworkInfo.State.DISCONNECTED
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
-import android.support.v4.app.NotificationCompat
+import androidx.core.app.NotificationCompat
import com.github.pwittchen.reactivenetwork.library.Connectivity
import com.github.pwittchen.reactivenetwork.library.ReactiveNetwork
import com.jakewharton.rxrelay.BehaviorRelay
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
index 0ca5449361..a68d60c1f5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
@@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.fetchAllImageUrlsFromPageList
import eu.kanade.tachiyomi.util.*
-import kotlinx.coroutines.experimental.async
+import kotlinx.coroutines.async
import okhttp3.Response
import rx.Observable
import rx.android.schedulers.AndroidSchedulers
@@ -157,6 +157,26 @@ class Downloader(
notifier.dismiss()
}
+ /**
+ * Removes everything from the queue for a certain manga
+ *
+ * @param isNotification value that determines if status is set (needed for view updates)
+ */
+ fun clearQueue(manga: Manga, isNotification: Boolean = false) {
+ //Needed to update the chapter view
+ if (isNotification) {
+ queue
+ .filter { it.status == Download.QUEUE && it.manga.id == manga.id }
+ .forEach { it.status = Download.NOT_DOWNLOADED }
+ }
+ queue.remove(manga)
+ if (queue.isEmpty()) {
+ DownloadService.stop(context)
+ stop()
+ }
+ notifier.dismiss()
+ }
+
/**
* Prepares the subscriptions to start downloading.
*/
@@ -351,7 +371,7 @@ class Downloader(
.map { response ->
val file = tmpDir.createFile("$filename.tmp")
try {
- response.body()!!.source().saveTo(file.openOutputStream())
+ response.body!!.source().saveTo(file.openOutputStream())
val extension = getImageExtension(response, file)
file.renameTo("$filename.$extension")
} catch (e: Exception) {
@@ -374,7 +394,7 @@ class Downloader(
*/
private fun getImageExtension(response: Response, file: UniFile): String {
// Read content type if available.
- val mime = response.body()?.contentType()?.let { ct -> "${ct.type()}/${ct.subtype()}" }
+ val mime = response.body?.contentType()?.let { ct -> "${ct.type}/${ct.subtype}" }
// Else guess from the uri.
?: context.contentResolver.getType(file.uri)
// Else read magic numbers.
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
index ab386b1330..2fb2e5d83a 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
@@ -22,7 +22,7 @@ class LibraryUpdateJob : Job() {
val preferences = Injekt.get()
val interval = prefInterval ?: preferences.libraryUpdateInterval().getOrDefault()
if (interval > 0) {
- val restrictions = preferences.libraryUpdateRestriction()
+ val restrictions = preferences.libraryUpdateRestriction()!!
val acRestriction = "ac" in restrictions
val wifiRestriction = if ("wifi" in restrictions)
JobRequest.NetworkType.UNMETERED
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
index 415a458687..17aad93ec3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
@@ -9,7 +9,9 @@ import android.graphics.BitmapFactory
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
-import android.support.v4.app.NotificationCompat
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
@@ -18,6 +20,7 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
+import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
@@ -29,14 +32,18 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.main.MainActivity
-import eu.kanade.tachiyomi.util.*
+import eu.kanade.tachiyomi.util.chop
+import eu.kanade.tachiyomi.util.isServiceRunning
+import eu.kanade.tachiyomi.util.notification
+import eu.kanade.tachiyomi.util.notificationManager
+import eu.kanade.tachiyomi.util.syncChaptersWithSource
import rx.Observable
import rx.Subscription
import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
-import java.util.*
+import java.util.ArrayList
import java.util.concurrent.atomic.AtomicInteger
/**
@@ -88,6 +95,7 @@ class LibraryUpdateService(
.setLargeIcon(notificationBitmap)
.setOngoing(true)
.setOnlyAlertOnce(true)
+ .setColor(ContextCompat.getColor(this, R.color.colorAccentLight))
.addAction(R.drawable.ic_clear_grey_24dp_img, getString(android.R.string.cancel), cancelIntent)
}
@@ -270,7 +278,7 @@ class LibraryUpdateService(
// Initialize the variables holding the progress of the updates.
val count = AtomicInteger(0)
// List containing new updates
- val newUpdates = ArrayList()
+ val newUpdates = ArrayList>>()
// list containing failed updates
val failedUpdates = ArrayList()
// List containing categories that get included in downloads.
@@ -303,7 +311,8 @@ class LibraryUpdateService(
}
}
// Convert to the manga that contains new chapters.
- .map { manga }
+ .map { Pair(manga, (it.first.sortedByDescending { ch -> ch
+ .source_order }.toTypedArray())) }
}
// Add manga with new chapters to the list.
.doOnNext { manga ->
@@ -325,6 +334,7 @@ class LibraryUpdateService(
cancelProgressNotification()
}
+ .map { manga -> manga.first }
}
fun downloadChapters(manga: Manga, chapters: List) {
@@ -438,39 +448,64 @@ class LibraryUpdateService(
*
* @param updates a list of manga with new updates.
*/
- private fun showResultNotification(updates: List) {
- val newUpdates = updates.map { it.title.chop(45) }.toMutableSet()
-
- // Append new chapters from a previous, existing notification
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- val previousNotification = notificationManager.activeNotifications
- .find { it.id == Notifications.ID_LIBRARY_RESULT }
-
- if (previousNotification != null) {
- val oldUpdates = previousNotification.notification.extras
- .getString(Notification.EXTRA_BIG_TEXT)
-
- if (!oldUpdates.isNullOrEmpty()) {
- newUpdates += oldUpdates.split("\n")
+ private fun showResultNotification(updates: List>>) {
+ val notifications = ArrayList>()
+ updates.forEach {
+ val manga = it.first
+ val chapters = it.second
+ val chapterNames = chapters.map { chapter -> chapter.name.chop(45) }.toSet()
+ notifications.add(Pair(notification(Notifications.CHANNEL_NEW_CHAPTERS) {
+ setSmallIcon(R.drawable.ic_tachiyomi_icon)
+ try {
+ val icon = GlideApp.with(this@LibraryUpdateService)
+ .asBitmap().load(manga).dontTransform().centerCrop().circleCrop()
+ .override(256, 256).submit().get()
+ setLargeIcon(icon)
}
- }
+ catch (e: Exception) { }
+ setContentTitle(manga.title.chop(45))
+ color = ContextCompat.getColor(this@LibraryUpdateService, R.color.colorAccentLight)
+ setContentText(chapterNames.first())
+ setStyle(NotificationCompat.BigTextStyle().bigText(
+ if (chapterNames.size > 5) {
+ "${chapterNames.take(4).joinToString(", ")}, " +
+ getString(R.string.notification_and_n_more, (chapterNames.size - 4))
+ } else chapterNames.joinToString(", ")))
+ priority = NotificationCompat.PRIORITY_HIGH
+ setGroup(Notifications.GROUP_NEW_CHAPTERS)
+ setContentIntent(
+ NotificationReceiver.openChapterPendingActivity(
+ this@LibraryUpdateService, manga, chapters.first()
+ )
+ )
+ addAction(R.drawable.ic_glasses_black_24dp, getString(R.string.action_mark_as_read),
+ NotificationReceiver.markAsReadPendingBroadcast(this@LibraryUpdateService,
+ manga, chapters, Notifications.ID_NEW_CHAPTERS))
+ addAction(R.drawable.ic_book_white_24dp, getString(R.string.action_view_chapters),
+ NotificationReceiver.openChapterPendingActivity(this@LibraryUpdateService,
+ manga, Notifications.ID_NEW_CHAPTERS))
+ setAutoCancel(true)
+ }, manga.id.hashCode()))
}
- notificationManager.notify(Notifications.ID_LIBRARY_RESULT, notification(Notifications.CHANNEL_LIBRARY) {
- setSmallIcon(R.drawable.ic_book_white_24dp)
- setLargeIcon(notificationBitmap)
- setContentTitle(getString(R.string.notification_new_chapters))
- if (newUpdates.size > 1) {
- setContentText(getString(R.string.notification_new_chapters_text, newUpdates.size))
- setStyle(NotificationCompat.BigTextStyle().bigText(newUpdates.joinToString("\n")))
- setNumber(newUpdates.size)
- } else {
- setContentText(newUpdates.first())
+ NotificationManagerCompat.from(this).apply {
+ notifications.forEach {
+ notify(it.second, it.first)
}
- priority = NotificationCompat.PRIORITY_HIGH
- setContentIntent(getNotificationIntent())
- setAutoCancel(true)
- })
+
+ notify(Notifications.ID_NEW_CHAPTERS, notification(Notifications.CHANNEL_NEW_CHAPTERS) {
+ setSmallIcon(R.drawable.ic_tachiyomi_icon)
+ setLargeIcon(notificationBitmap)
+ setContentTitle(getString(R.string.notification_new_chapters))
+ color = ContextCompat.getColor(applicationContext, R.color.colorAccentLight)
+ setContentText(getString(R.string.notification_new_chapters_text, updates.size))
+ priority = NotificationCompat.PRIORITY_HIGH
+ setGroup(Notifications.GROUP_NEW_CHAPTERS)
+ setGroupSummary(true)
+ setContentIntent(getNotificationIntent())
+ setAutoCancel(true)
+ })
+ }
}
/**
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
index 11622c5057..84e49f19b1 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/NotificationReceiver.kt
@@ -1,9 +1,13 @@
package eu.kanade.tachiyomi.data.notification
+import android.app.Activity
+import android.app.KeyguardManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
+import android.content.ClipData
import android.content.Context
import android.content.Intent
+import android.os.Build
import android.os.Handler
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@@ -12,11 +16,17 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.source.SourceManager
+import eu.kanade.tachiyomi.ui.main.MainActivity
+import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.DiskUtil
import eu.kanade.tachiyomi.util.getUriCompat
import eu.kanade.tachiyomi.util.notificationManager
import eu.kanade.tachiyomi.util.toast
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.io.File
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
@@ -54,12 +64,21 @@ class NotificationReceiver : BroadcastReceiver() {
ACTION_DELETE_IMAGE -> deleteImage(context, intent.getStringExtra(EXTRA_FILE_LOCATION),
intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1))
// Cancel library update and dismiss notification
- ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context, Notifications.ID_LIBRARY_PROGRESS)
+ ACTION_CANCEL_LIBRARY_UPDATE -> cancelLibraryUpdate(context)
// Open reader activity
ACTION_OPEN_CHAPTER -> {
openChapter(context, intent.getLongExtra(EXTRA_MANGA_ID, -1),
intent.getLongExtra(EXTRA_CHAPTER_ID, -1))
}
+ ACTION_MARK_AS_READ -> {
+ val notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1)
+ if (notificationId > -1) dismissNotification(
+ context, notificationId, intent.getIntExtra(EXTRA_GROUP_ID, 0)
+ )
+ val urls = intent.getStringArrayExtra(EXTRA_CHAPTER_URL) ?: return
+ val mangaId = intent.getLongExtra(EXTRA_MANGA_ID, -1)
+ markAsRead(urls, mangaId)
+ }
}
}
@@ -80,17 +99,17 @@ class NotificationReceiver : BroadcastReceiver() {
* @param notificationId id of notification
*/
private fun shareImage(context: Context, path: String, notificationId: Int) {
+ val km = context.getSystemService(Activity.KEYGUARD_SERVICE) as KeyguardManager
// Create intent
val intent = Intent(Intent.ACTION_SEND).apply {
val uri = File(path).getUriCompat(context)
putExtra(Intent.EXTRA_STREAM, uri)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
+ clipData = ClipData.newRawUri(null, uri)
type = "image/*"
}
- // Dismiss notification
- dismissNotification(context, notificationId)
- // Launch share activity
- context.startActivity(intent)
+ // Close Navigation Shade
+
}
/**
@@ -101,17 +120,18 @@ class NotificationReceiver : BroadcastReceiver() {
* @param chapterId id of chapter
*/
internal fun openChapter(context: Context, mangaId: Long, chapterId: Long) {
+ dismissNotification(context, Notifications.ID_NEW_CHAPTERS)
val db = DatabaseHelper(context)
val manga = db.getManga(mangaId).executeAsBlocking()
val chapter = db.getChapter(chapterId).executeAsBlocking()
-
+ context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
if (manga != null && chapter != null) {
val intent = ReaderActivity.newIntent(context, manga, chapter).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
}
context.startActivity(intent)
} else {
- context.toast(context.getString(R.string.chapter_error))
+ context.toast(context.getString(R.string.no_next_chapter))
}
}
@@ -138,9 +158,31 @@ class NotificationReceiver : BroadcastReceiver() {
* @param context context of application
* @param notificationId id of notification
*/
- private fun cancelLibraryUpdate(context: Context, notificationId: Int) {
+ private fun cancelLibraryUpdate(context: Context) {
LibraryUpdateService.stop(context)
- Handler().post { dismissNotification(context, notificationId) }
+ Handler().post { dismissNotification(context, Notifications.ID_LIBRARY_PROGRESS) }
+ }
+
+ /**
+ * Method called when user wants to stop a library update
+ *
+ * @param context context of application
+ * @param notificationId id of notification
+ */
+ private fun markAsRead(chapterUrls: Array, mangaId: Long) {
+ val db: DatabaseHelper = Injekt.get()
+ chapterUrls.forEach {
+ val chapter = db.getChapter(it, mangaId).executeAsBlocking() ?: return
+ chapter.read = true
+ db.updateChapterProgress(chapter).executeAsBlocking()
+ val preferences: PreferencesHelper = Injekt.get()
+ if (preferences.removeAfterMarkedAsRead()) {
+ val manga = db.getManga(mangaId).executeAsBlocking() ?: return
+ val sourceManager: SourceManager = Injekt.get()
+ val source = sourceManager.get(manga.source) ?: return
+ downloadManager.deleteChapters(listOf(chapter), manga, source)
+ }
+ }
}
companion object {
@@ -155,6 +197,9 @@ class NotificationReceiver : BroadcastReceiver() {
// Called to cancel library update.
private const val ACTION_CANCEL_LIBRARY_UPDATE = "$ID.$NAME.CANCEL_LIBRARY_UPDATE"
+ // Called to cancel library update.
+ private const val ACTION_MARK_AS_READ = "$ID.$NAME.MARK_AS_READ"
+
// Called to open chapter
private const val ACTION_OPEN_CHAPTER = "$ID.$NAME.ACTION_OPEN_CHAPTER"
@@ -179,12 +224,18 @@ class NotificationReceiver : BroadcastReceiver() {
// Value containing notification id.
private const val EXTRA_NOTIFICATION_ID = "$ID.$NAME.NOTIFICATION_ID"
+ // Value containing group id.
+ private const val EXTRA_GROUP_ID = "$ID.$NAME.EXTRA_GROUP_ID"
+
// Value containing manga id.
private const val EXTRA_MANGA_ID = "$ID.$NAME.EXTRA_MANGA_ID"
// Value containing chapter id.
private const val EXTRA_CHAPTER_ID = "$ID.$NAME.EXTRA_CHAPTER_ID"
+ // Value containing chapter url.
+ private const val EXTRA_CHAPTER_URL = "$ID.$NAME.EXTRA_CHAPTER_URL"
+
/**
* Returns a [PendingIntent] that resumes the download of a chapter
*
@@ -246,6 +297,32 @@ class NotificationReceiver : BroadcastReceiver() {
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
+ /**
+ * Returns [PendingIntent] that starts a service which dismissed the notification
+ *
+ * @param context context of application
+ * @param notificationId id of notification
+ * @return [PendingIntent]
+ */
+ internal fun dismissNotification(context: Context, notificationId: Int, groupId: Int? =
+ null) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ val groupKey = context.notificationManager.activeNotifications.find {
+ it.id == notificationId
+ }?.groupKey
+ if (groupId != null && groupId != 0 && groupKey != null && groupKey.isNotEmpty()) {
+ val notifications = context.notificationManager.activeNotifications.filter {
+ it.groupKey == groupKey
+ }
+ if (notifications.size == 2) {
+ context.notificationManager.cancel(groupId)
+ return
+ }
+ }
+ }
+ context.notificationManager.cancel(notificationId)
+ }
+
/**
* Returns [PendingIntent] that starts a service which cancels the notification and starts a share activity
*
@@ -255,12 +332,17 @@ class NotificationReceiver : BroadcastReceiver() {
* @return [PendingIntent]
*/
internal fun shareImagePendingBroadcast(context: Context, path: String, notificationId: Int): PendingIntent {
- val intent = Intent(context, NotificationReceiver::class.java).apply {
- action = ACTION_SHARE_IMAGE
- putExtra(EXTRA_FILE_LOCATION, path)
- putExtra(EXTRA_NOTIFICATION_ID, notificationId)
+ //val shareIntent = ShareStartingActivity.newIntent(context, path)
+ val shareIntent = Intent(Intent.ACTION_SEND).apply {
+ val uri = File(path).getUriCompat(context)
+ putExtra(Intent.EXTRA_STREAM, uri)
+ flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ clipData = ClipData.newRawUri(null, uri)
+ type = "image/*"
}
- return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
+ //val shareIntent2 = Intent.createChooser(shareIntent, context.getString(R.string.action_share))
+ return PendingIntent.getActivity(context, 0, shareIntent, PendingIntent
+ .FLAG_CANCEL_CURRENT)
}
/**
@@ -281,19 +363,55 @@ class NotificationReceiver : BroadcastReceiver() {
}
/**
- * Returns [PendingIntent] that start a reader activity containing chapter.
+ * Returns [PendingIntent] that starts a reader activity containing chapter.
*
* @param context context of application
* @param manga manga of chapter
* @param chapter chapter that needs to be opened
*/
- internal fun openChapterPendingBroadcast(context: Context, manga: Manga, chapter: Chapter): PendingIntent {
- val intent = Intent(context, NotificationReceiver::class.java).apply {
- action = ACTION_OPEN_CHAPTER
+ internal fun openChapterPendingActivity(context: Context, manga: Manga, chapter:
+ Chapter): PendingIntent {
+ val newIntent = ReaderActivity.newIntent(context, manga, chapter)
+ return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent
+ .FLAG_UPDATE_CURRENT)
+ }
+
+ /**
+ * Returns [PendingIntent] that opens the manga info controller.
+ *
+ * @param context context of application
+ * @param manga manga of chapter
+ */
+ internal fun openChapterPendingActivity(context: Context, manga: Manga, groupId: Int):
+ PendingIntent {
+ val newIntent =
+ Intent(context, MainActivity::class.java).setAction(MainActivity.SHORTCUT_MANGA)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(MangaController.MANGA_EXTRA, manga.id)
+ .putExtra("notificationId", manga.id.hashCode())
+ .putExtra("groupId", groupId)
+ return PendingIntent.getActivity(
+ context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ )
+ }
+
+ /**
+ * Returns [PendingIntent] that marks a chapter as read and deletes it if preferred
+ *
+ * @param context context of application
+ * @param manga manga of chapter
+ */
+ internal fun markAsReadPendingBroadcast(context: Context, manga: Manga, chapters:
+ Array, groupId: Int):
+ PendingIntent {
+ val newIntent = Intent(context, NotificationReceiver::class.java).apply {
+ action = ACTION_MARK_AS_READ
+ putExtra(EXTRA_CHAPTER_URL, chapters.map { it.url }.toTypedArray())
putExtra(EXTRA_MANGA_ID, manga.id)
- putExtra(EXTRA_CHAPTER_ID, chapter.id)
+ putExtra(EXTRA_NOTIFICATION_ID, manga.id.hashCode())
+ putExtra(EXTRA_GROUP_ID, groupId)
}
- return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
+ return PendingIntent.getBroadcast(context, manga.id.hashCode(), newIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
/**
@@ -309,4 +427,4 @@ class NotificationReceiver : BroadcastReceiver() {
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
index be537dd14f..b99c44cadd 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt
@@ -23,15 +23,21 @@ object Notifications {
* Notification channel and ids used by the library updater.
*/
const val CHANNEL_LIBRARY = "library_channel"
- const val ID_LIBRARY_PROGRESS = 101
- const val ID_LIBRARY_RESULT = 102
+ const val ID_LIBRARY_PROGRESS = -101
/**
* Notification channel and ids used by the downloader.
*/
const val CHANNEL_DOWNLOADER = "downloader_channel"
- const val ID_DOWNLOAD_CHAPTER = 201
- const val ID_DOWNLOAD_CHAPTER_ERROR = 202
+ const val ID_DOWNLOAD_CHAPTER = -201
+ const val ID_DOWNLOAD_CHAPTER_ERROR = -202
+
+ /**
+ * Notification channel and ids used by the library updater.
+ */
+ const val CHANNEL_NEW_CHAPTERS = "new_chapters_channel"
+ const val ID_NEW_CHAPTERS = -301
+ const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS"
/**
* Creates the notification channels introduced in Android Oreo.
@@ -44,10 +50,16 @@ object Notifications {
val channels = listOf(
NotificationChannel(CHANNEL_COMMON, context.getString(R.string.channel_common),
NotificationManager.IMPORTANCE_LOW),
- NotificationChannel(CHANNEL_LIBRARY, context.getString(R.string.channel_library),
- NotificationManager.IMPORTANCE_LOW),
+ NotificationChannel(CHANNEL_LIBRARY, context.getString(R.string.channel_library_updates),
+ NotificationManager.IMPORTANCE_LOW).apply {
+ setShowBadge(false)
+ },
NotificationChannel(CHANNEL_DOWNLOADER, context.getString(R.string.channel_downloader),
- NotificationManager.IMPORTANCE_LOW)
+ NotificationManager.IMPORTANCE_LOW).apply {
+ setShowBadge(false)
+ },
+ NotificationChannel(CHANNEL_NEW_CHAPTERS, context.getString(R.string.channel_new_chapters),
+ NotificationManager.IMPORTANCE_DEFAULT)
)
context.notificationManager.createNotificationChannels(channels)
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/EmptyPreferenceDataStore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/EmptyPreferenceDataStore.kt
index 10e83b84eb..d162cfd659 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/EmptyPreferenceDataStore.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/EmptyPreferenceDataStore.kt
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.preference
-import android.support.v7.preference.PreferenceDataStore
+import androidx.preference.PreferenceDataStore
class EmptyPreferenceDataStore : PreferenceDataStore() {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
index 68e6371ee7..8af98a9e83 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt
@@ -33,7 +33,7 @@ class PreferencesHelper(val context: Context) {
fun clear() = prefs.edit().clear().apply()
- fun theme() = prefs.getInt(Keys.theme, 1)
+ fun theme() = prefs.getInt(Keys.theme, 5)
fun rotation() = rxPrefs.getInteger(Keys.rotation, 1)
@@ -65,7 +65,7 @@ class PreferencesHelper(val context: Context) {
fun zoomStart() = rxPrefs.getInteger(Keys.zoomStart, 1)
- fun readerTheme() = rxPrefs.getInteger(Keys.readerTheme, 0)
+ fun readerTheme() = rxPrefs.getInteger(Keys.readerTheme, 2)
fun cropBorders() = rxPrefs.getBoolean(Keys.cropBorders, false)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt
index bb07bb0a52..03a4d17187 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/SharedPreferencesDataStore.kt
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.preference
import android.content.SharedPreferences
-import android.support.v7.preference.PreferenceDataStore
+import androidx.preference.PreferenceDataStore
class SharedPreferencesDataStore(private val prefs: SharedPreferences) : PreferenceDataStore() {
@@ -46,7 +46,7 @@ class SharedPreferencesDataStore(private val prefs: SharedPreferences) : Prefere
}
override fun getStringSet(key: String?, defValues: MutableSet?): MutableSet {
- return prefs.getStringSet(key, defValues)
+ return prefs.getStringSet(key, defValues)!!
}
override fun putStringSet(key: String?, values: MutableSet?) {
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt
index 9397f71e42..417e8ba5ce 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/TrackService.kt
@@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.track
-import android.support.annotation.CallSuper
-import android.support.annotation.DrawableRes
+import androidx.annotation.CallSuper
+import androidx.annotation.DrawableRes
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
index 041852ea0f..92c01aac93 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.asObservableSuccess
import okhttp3.MediaType
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
@@ -18,7 +19,7 @@ import java.util.Calendar
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
private val parser = JsonParser()
- private val jsonMime = MediaType.parse("application/json; charset=utf-8")
+ private val jsonMime = "application/json; charset=utf-8".toMediaTypeOrNull()
private val authClient = client.newBuilder().addInterceptor(interceptor).build()
@@ -45,7 +46,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
return authClient.newCall(request)
.asObservableSuccess()
.map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
netResponse.close()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
@@ -128,7 +129,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
return authClient.newCall(request)
.asObservableSuccess()
.map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
}
@@ -189,7 +190,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
return authClient.newCall(request)
.asObservableSuccess()
.map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
}
@@ -235,7 +236,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
return authClient.newCall(request)
.asObservableSuccess()
.map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
index 661c265236..c678372c6b 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
@@ -84,7 +84,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
return authClient.newCall(request)
.asObservableSuccess()
.map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
}
@@ -127,7 +127,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
.asObservableSuccess()
.map { netResponse ->
// get comic info
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
jsonToTrack(parser.parse(responseBody).obj)
}
}
@@ -144,7 +144,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
return authClient.newCall(requestUserRead)
.asObservableSuccess()
.map { netResponse ->
- val resp = netResponse.body()?.string()
+ val resp = netResponse.body?.string()
val coll = gson.fromJson(resp, Collection::class.java)
track.status = coll.status?.id!!
track.last_chapter_read = coll.ep_status!!
@@ -154,7 +154,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
fun accessToken(code: String): Observable {
return client.newCall(accessTokenRequest(code)).asObservableSuccess().map { netResponse ->
- val responseBody = netResponse.body()?.string().orEmpty()
+ val responseBody = netResponse.body?.string().orEmpty()
if (responseBody.isEmpty()) {
throw Exception("Null Response")
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt
index 69565f447b..b403daf8a9 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt
@@ -14,7 +14,7 @@ class BangumiInterceptor(val bangumi: Bangumi, val gson: Gson) : Interceptor {
fun addTocken(tocken: String, oidFormBody: FormBody): FormBody {
val newFormBody = FormBody.Builder()
- for (i in 0 until oidFormBody.size()) {
+ for (i in 0 until oidFormBody.size) {
newFormBody.add(oidFormBody.name(i), oidFormBody.value(i))
}
newFormBody.add("access_token", tocken)
@@ -29,18 +29,18 @@ class BangumiInterceptor(val bangumi: Bangumi, val gson: Gson) : Interceptor {
if (currAuth.isExpired()) {
val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!))
if (response.isSuccessful) {
- newAuth(gson.fromJson(response.body()!!.string(), OAuth::class.java))
+ newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java))
} else {
response.close()
}
}
- var authRequest = if (originalRequest.method() == "GET") originalRequest.newBuilder()
+ var authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder()
.header("User-Agent", "Tachiyomi")
- .url(originalRequest.url().newBuilder()
+ .url(originalRequest.url.newBuilder()
.addQueryParameter("access_token", currAuth.access_token).build())
.build() else originalRequest.newBuilder()
- .post(addTocken(currAuth.access_token, originalRequest.body() as FormBody))
+ .post(addTocken(currAuth.access_token, originalRequest.body as FormBody))
.header("User-Agent", "Tachiyomi")
.build()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuInterceptor.kt
index 8810dd2743..1a74b8d9ec 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuInterceptor.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuInterceptor.kt
@@ -22,7 +22,7 @@ class KitsuInterceptor(val kitsu: Kitsu, val gson: Gson) : Interceptor {
if (currAuth.isExpired()) {
val response = chain.proceed(KitsuApi.refreshTokenRequest(refreshToken))
if (response.isSuccessful) {
- newAuth(gson.fromJson(response.body()!!.string(), OAuth::class.java))
+ newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java))
} else {
response.close()
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt
index ca0de7d3d3..5a3df974b3 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt
@@ -1,6 +1,6 @@
package eu.kanade.tachiyomi.data.track.kitsu
-import android.support.annotation.CallSuper
+import androidx.annotation.CallSuper
import com.github.salomonbrys.kotson.*
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.data.database.models.Track
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt
index fbfc1e019b..35d821111c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch
import okhttp3.HttpUrl
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import rx.Completable
import rx.Observable
import java.lang.Exception
@@ -134,7 +135,7 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) {
override fun logout() {
super.logout()
preferences.trackToken(this).delete()
- networkService.cookieManager.remove(HttpUrl.parse(BASE_URL)!!)
+ networkService.cookieManager.remove(BASE_URL.toHttpUrlOrNull()!!)
}
val isAuthorized: Boolean
@@ -148,9 +149,9 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) {
private fun checkCookies(): Boolean {
var ckCount = 0
- val url = HttpUrl.parse(BASE_URL)!!
+ val url = BASE_URL.toHttpUrlOrNull()!!
for (ck in networkService.cookieManager.get(url)) {
- if (ck.name() == USER_SESSION_COOKIE || ck.name() == LOGGED_IN_COOKIE)
+ if (ck.name == USER_SESSION_COOKIE || ck.name == LOGGED_IN_COOKIE)
ckCount++
}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt
index 0a032c6a5b..9089c3a343 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt
@@ -12,7 +12,7 @@ class MyAnimeListInterceptor(private val myanimelist: Myanimelist): Interceptor
myanimelist.ensureLoggedIn()
var request = chain.request()
- request.body()?.let {
+ request.body?.let {
val contentType = it.contentType().toString()
val updatedBody = when {
contentType.contains("x-www-form-urlencoded") -> updateFormBody(it)
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyanimelistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyanimelistApi.kt
index efc3abefc0..5462eb4f92 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyanimelistApi.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyanimelistApi.kt
@@ -11,6 +11,8 @@ import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.util.selectInt
import eu.kanade.tachiyomi.util.selectText
import okhttp3.*
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
@@ -85,7 +87,7 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.map {response ->
var libTrack: Track? = null
response.use {
- if (it.priorResponse()?.isRedirect != true) {
+ if (it.priorResponse?.isRedirect != true) {
val trackForm = Jsoup.parse(it.consumeBody())
libTrack = Track.create(TrackManager.MYANIMELIST).apply {
@@ -125,7 +127,7 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
val response = client.newCall(POST(url = loginUrl(), body = loginPostBody(username, password, csrf))).execute()
response.use {
- if (response.priorResponse()?.code() != 302) throw Exception("Authentication error")
+ if (response.priorResponse?.code != 302) throw Exception("Authentication error")
}
}
@@ -172,15 +174,15 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
private fun Response.consumeBody(): String? {
use {
- if (it.code() != 200) throw Exception("HTTP error ${it.code()}")
- return it.body()?.string()
+ if (it.code != 200) throw Exception("HTTP error ${it.code}")
+ return it.body?.string()
}
}
private fun Response.consumeXmlBody(): String? {
use { res ->
- if (res.code() != 200) throw Exception("Export list error")
- BufferedReader(InputStreamReader(GZIPInputStream(res.body()?.source()?.inputStream()))).use { reader ->
+ if (res.code != 200) throw Exception("Export list error")
+ BufferedReader(InputStreamReader(GZIPInputStream(res.body?.source()?.inputStream()))).use { reader ->
val sb = StringBuilder()
reader.forEachLine { line ->
sb.append(line)
@@ -262,7 +264,7 @@ class MyanimelistApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.put("score", track.score)
.put("num_read_chapters", track.last_chapter_read)
- return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body.toString())
+ return body.toString().toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
}
private fun Element.searchTitle() = select("strong").text()!!
diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
index 0180e015eb..afef886bab 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
@@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess
import okhttp3.*
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
import rx.Observable
import uy.kohesive.injekt.injectLazy
@@ -22,7 +23,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
private val gson: Gson by injectLazy()
private val parser = JsonParser()
- private val jsonime = MediaType.parse("application/json; charset=utf-8")
+ private val jsonime = "application/json; charset=utf-8".toMediaTypeOrNull()
private val authClient = client.newBuilder().addInterceptor(interceptor).build()
fun addLibManga(track: Track, user_id: String): Observable