Drop support for Android 4.x (#2440)
* Bump minSdkVersion * Remove Android 4.x specific logic * Consolidate res assets * Add note about minimum Android version to README * Restore incorrectly removed method, remove unneeded Lollipop TargetApi annotations
This commit is contained in:
parent
b55814a1c0
commit
0d5099f230
33 changed files with 200 additions and 530 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
|
||||
# ![app icon](./.github/readme-images/app-icon.png)Tachiyomi
|
||||
Tachiyomi is a free and open source manga reader for Android.
|
||||
Tachiyomi is a free and open source manga reader for Android 5.0 and above.
|
||||
|
||||
![screenshots of app](./.github/readme-images/screens.png)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId "eu.kanade.tachiyomi"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 28
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
versionCode 41
|
||||
|
|
|
@ -1,35 +1,20 @@
|
|||
package eu.kanade.tachiyomi.network
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.CookieSyncManager
|
||||
import okhttp3.Cookie
|
||||
import okhttp3.CookieJar
|
||||
import okhttp3.HttpUrl
|
||||
|
||||
class AndroidCookieJar(context: Context) : CookieJar {
|
||||
class AndroidCookieJar : CookieJar {
|
||||
|
||||
private val manager = CookieManager.getInstance()
|
||||
|
||||
private val syncManager by lazy { CookieSyncManager.createInstance(context) }
|
||||
|
||||
init {
|
||||
// Init sync manager when using anything below L
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
syncManager
|
||||
}
|
||||
}
|
||||
|
||||
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
|
||||
val urlString = url.toString()
|
||||
|
||||
for (cookie in cookies) {
|
||||
manager.setCookie(urlString, cookie.toString())
|
||||
}
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
syncManager.sync()
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> {
|
||||
|
@ -39,7 +24,7 @@ class AndroidCookieJar(context: Context) : CookieJar {
|
|||
fun get(url: HttpUrl): List<Cookie> {
|
||||
val cookies = manager.getCookie(url.toString())
|
||||
|
||||
return if (cookies != null && !cookies.isEmpty()) {
|
||||
return if (cookies != null && cookies.isNotEmpty()) {
|
||||
cookies.split(";").mapNotNull { Cookie.parse(url, it) }
|
||||
} else {
|
||||
emptyList()
|
||||
|
@ -53,19 +38,10 @@ class AndroidCookieJar(context: Context) : CookieJar {
|
|||
cookies.split(";")
|
||||
.map { it.substringBefore("=") }
|
||||
.onEach { manager.setCookie(urlString, "$it=;Max-Age=-1") }
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
syncManager.sync()
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAll() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
manager.removeAllCookies {}
|
||||
} else {
|
||||
manager.removeAllCookie()
|
||||
syncManager.sync()
|
||||
}
|
||||
manager.removeAllCookies {}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,11 +28,7 @@ class CloudflareInterceptor(private val context: Context) : Interceptor {
|
|||
* Application class.
|
||||
*/
|
||||
private val initWebView by lazy {
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
WebSettings.getDefaultUserAgent(context)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
WebSettings.getDefaultUserAgent(context)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
package eu.kanade.tachiyomi.network
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import okhttp3.*
|
||||
import okhttp3.Cache
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.InetAddress
|
||||
import java.net.Socket
|
||||
import java.net.UnknownHostException
|
||||
import java.security.KeyManagementException
|
||||
import java.security.KeyStore
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import javax.net.ssl.*
|
||||
|
||||
class NetworkHelper(context: Context) {
|
||||
|
||||
|
@ -19,99 +11,15 @@ class NetworkHelper(context: Context) {
|
|||
|
||||
private val cacheSize = 5L * 1024 * 1024 // 5 MiB
|
||||
|
||||
val cookieManager = AndroidCookieJar(context)
|
||||
val cookieManager = AndroidCookieJar()
|
||||
|
||||
val client = OkHttpClient.Builder()
|
||||
.cookieJar(cookieManager)
|
||||
.cache(Cache(cacheDir, cacheSize))
|
||||
.enableTLS12()
|
||||
.build()
|
||||
|
||||
val cloudflareClient = client.newBuilder()
|
||||
.addInterceptor(CloudflareInterceptor(context))
|
||||
.build()
|
||||
|
||||
private fun OkHttpClient.Builder.enableTLS12(): OkHttpClient.Builder {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
|
||||
return this
|
||||
}
|
||||
|
||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
trustManagerFactory.init(null as KeyStore?)
|
||||
val trustManagers = trustManagerFactory.trustManagers
|
||||
if (trustManagers.size == 1 && trustManagers[0] is X509TrustManager) {
|
||||
class TLSSocketFactory @Throws(KeyManagementException::class, NoSuchAlgorithmException::class)
|
||||
constructor() : SSLSocketFactory() {
|
||||
|
||||
private val internalSSLSocketFactory: SSLSocketFactory
|
||||
|
||||
init {
|
||||
val context = SSLContext.getInstance("TLS")
|
||||
context.init(null, null, null)
|
||||
internalSSLSocketFactory = context.socketFactory
|
||||
}
|
||||
|
||||
override fun getDefaultCipherSuites(): Array<String> {
|
||||
return internalSSLSocketFactory.defaultCipherSuites
|
||||
}
|
||||
|
||||
override fun getSupportedCipherSuites(): Array<String> {
|
||||
return internalSSLSocketFactory.supportedCipherSuites
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket())
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose))
|
||||
}
|
||||
|
||||
@Throws(IOException::class, UnknownHostException::class)
|
||||
override fun createSocket(host: String, port: Int): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))
|
||||
}
|
||||
|
||||
@Throws(IOException::class, UnknownHostException::class)
|
||||
override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(host: InetAddress, port: Int): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket? {
|
||||
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort))
|
||||
}
|
||||
|
||||
private fun enableTLSOnSocket(socket: Socket?): Socket? {
|
||||
if (socket != null && socket is SSLSocket) {
|
||||
socket.enabledProtocols = socket.supportedProtocols
|
||||
}
|
||||
return socket
|
||||
}
|
||||
}
|
||||
|
||||
sslSocketFactory(TLSSocketFactory(), trustManagers[0] as X509TrustManager)
|
||||
}
|
||||
|
||||
val specCompat = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||
.tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
|
||||
.cipherSuites(
|
||||
*ConnectionSpec.MODERN_TLS.cipherSuites.orEmpty().toTypedArray(),
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||
)
|
||||
.build()
|
||||
|
||||
val specs = listOf(specCompat, ConnectionSpec.CLEARTEXT)
|
||||
connectionSpecs(specs)
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.ui.base.holder
|
||||
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
|
@ -51,10 +50,6 @@ interface SlicedHolder {
|
|||
slice.showRightTopRect(topRect)
|
||||
slice.showLeftBottomRect(bottomRect)
|
||||
slice.showRightBottomRect(bottomRect)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
slice.showTopEdgeShadow(topShadow)
|
||||
slice.showBottomEdgeShadow(bottomShadow)
|
||||
}
|
||||
setMargins(margin, if (topShadow) margin else 0, margin, if (bottomShadow) margin else 0)
|
||||
}
|
||||
|
||||
|
@ -68,4 +63,4 @@ interface SlicedHolder {
|
|||
val margin
|
||||
get() = 8.dpToPx
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.content.pm.ActivityInfo
|
|||
import android.content.res.Configuration
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.view.animation.Animation
|
||||
|
@ -21,9 +20,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.*
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||
|
@ -276,10 +273,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||
toolbarAnimation.setAnimationListener(object : SimpleAnimationListener() {
|
||||
override fun onAnimationStart(animation: Animation) {
|
||||
// Fix status bar being translucent the first time it's opened.
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
window.addFlags(
|
||||
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
}
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
}
|
||||
})
|
||||
toolbar.startAnimation(toolbarAnimation)
|
||||
|
@ -637,11 +631,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||
*/
|
||||
private fun setFullscreen(enabled: Boolean) {
|
||||
systemUi = if (enabled) {
|
||||
val level = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
SystemUiHelper.LEVEL_IMMERSIVE
|
||||
} else {
|
||||
SystemUiHelper.LEVEL_HIDE_STATUS_BAR
|
||||
}
|
||||
val level = SystemUiHelper.LEVEL_IMMERSIVE
|
||||
val flags = SystemUiHelper.FLAG_IMMERSIVE_STICKY or
|
||||
SystemUiHelper.FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES
|
||||
|
||||
|
|
|
@ -3,16 +3,14 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
|
|||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import android.util.AttributeSet
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.GestureDetectorWithLongTap
|
||||
|
||||
/**
|
||||
|
@ -58,7 +56,6 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
|||
firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
override fun onScrollStateChanged(state: Int) {
|
||||
super.onScrollStateChanged(state)
|
||||
val layoutManager = layoutManager
|
||||
|
|
|
@ -5,10 +5,9 @@ import android.app.Activity
|
|||
import android.app.Dialog
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceScreen
|
||||
import android.view.View
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
@ -106,21 +105,12 @@ class SettingsBackupController : SettingsController() {
|
|||
onClick {
|
||||
val currentDir = preferences.backupsDirectory().getOrDefault()
|
||||
try{
|
||||
val intent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Custom dir selected, open directory selector
|
||||
preferences.context.getFilePicker(currentDir)
|
||||
} else {
|
||||
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
}
|
||||
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
startActivityForResult(intent, CODE_BACKUP_DIR)
|
||||
} catch (e: ActivityNotFoundException){
|
||||
//Fall back to custom picker on error
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_DIR)
|
||||
}
|
||||
// Fall back to custom picker on error
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_DIR)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
preferences.backupsDirectory().asObservable()
|
||||
|
@ -154,37 +144,27 @@ class SettingsBackupController : SettingsController() {
|
|||
// Get uri of backup folder.
|
||||
val uri = data.data
|
||||
|
||||
// Get UriPermission so it's possible to write files post kitkat.
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
// Get UriPermission so it's possible to write files
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
|
||||
activity.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
}
|
||||
activity.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
|
||||
// Set backup Uri.
|
||||
// Set backup Uri
|
||||
preferences.backupsDirectory().set(uri.toString())
|
||||
}
|
||||
CODE_BACKUP_CREATE -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
val activity = activity ?: return
|
||||
val uri = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
val dir = data.data.path
|
||||
val file = File(dir, Backup.getDefaultFilename())
|
||||
|
||||
Uri.fromFile(file)
|
||||
} else {
|
||||
val uri = data.data
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
val uri = data.data
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
|
||||
activity.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
val file = UniFile.fromUri(activity, uri)
|
||||
|
||||
file.uri
|
||||
}
|
||||
activity.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
val file = UniFile.fromUri(activity, uri)
|
||||
|
||||
CreatingBackupDialog().showDialog(router, TAG_CREATING_BACKUP_DIALOG)
|
||||
BackupCreateService.makeBackup(activity, uri, backupFlags)
|
||||
BackupCreateService.makeBackup(activity, file.uri, backupFlags)
|
||||
}
|
||||
CODE_BACKUP_RESTORE -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
val uri = data.data
|
||||
|
@ -201,25 +181,17 @@ class SettingsBackupController : SettingsController() {
|
|||
val currentDir = preferences.backupsDirectory().getOrDefault()
|
||||
|
||||
try {
|
||||
// If API is lower than Lollipop use custom picker
|
||||
val intent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
preferences.context.getFilePicker(currentDir)
|
||||
} else {
|
||||
// Use Androids build in file creator
|
||||
Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
// Use Android's built-in file creator
|
||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.setType("application/*")
|
||||
.putExtra(Intent.EXTRA_TITLE, Backup.getDefaultFilename())
|
||||
}
|
||||
|
||||
startActivityForResult(intent, CODE_BACKUP_CREATE)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
// Handle errors where the android ROM doesn't support the built in picker
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_CREATE)
|
||||
}
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_CREATE)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CreateBackupDialog : DialogController() {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.app.Dialog
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -107,11 +106,7 @@ class SettingsDownloadController : SettingsController() {
|
|||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
DOWNLOAD_DIR_PRE_L -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
val uri = Uri.fromFile(File(data.data.path))
|
||||
preferences.downloadsDirectory().set(uri.toString())
|
||||
}
|
||||
DOWNLOAD_DIR_L -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
DOWNLOAD_DIR -> if (data != null && resultCode == Activity.RESULT_OK) {
|
||||
val context = applicationContext ?: return
|
||||
val uri = data.data
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
|
@ -132,19 +127,11 @@ class SettingsDownloadController : SettingsController() {
|
|||
}
|
||||
|
||||
fun customDirectorySelected(currentDir: String) {
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR_PRE_L)
|
||||
} else {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
try {
|
||||
startActivityForResult(intent, DOWNLOAD_DIR_L)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR_L)
|
||||
}
|
||||
}
|
||||
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||
try {
|
||||
startActivityForResult(intent, DOWNLOAD_DIR)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +170,6 @@ class SettingsDownloadController : SettingsController() {
|
|||
}
|
||||
|
||||
private companion object {
|
||||
const val DOWNLOAD_DIR_PRE_L = 103
|
||||
const val DOWNLOAD_DIR_L = 104
|
||||
const val DOWNLOAD_DIR = 104
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.util
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.EnvironmentCompat
|
||||
|
@ -45,13 +44,6 @@ object DiskUtil {
|
|||
}
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < 21) {
|
||||
val extStorages = System.getenv("SECONDARY_STORAGE")
|
||||
if (extStorages != null) {
|
||||
directories += extStorages.split(":").map(::File)
|
||||
}
|
||||
}
|
||||
|
||||
return directories
|
||||
}
|
||||
|
||||
|
@ -79,11 +71,7 @@ object DiskUtil {
|
|||
* Scans the given file so that it can be shown in gallery apps, for example.
|
||||
*/
|
||||
fun scanMedia(context: Context, uri: Uri) {
|
||||
val action = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||
Intent.ACTION_MEDIA_MOUNTED
|
||||
} else {
|
||||
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
|
||||
}
|
||||
val action = Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
|
||||
val mediaScanIntent = Intent(action)
|
||||
mediaScanIntent.data = uri
|
||||
context.sendBroadcast(mediaScanIntent)
|
||||
|
|
|
@ -36,7 +36,6 @@ abstract class WebViewClientCompat : WebViewClient() {
|
|||
return shouldOverrideUrlCompat(view, url)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
final override fun shouldInterceptRequest(
|
||||
view: WebView,
|
||||
request: WebResourceRequest
|
||||
|
|
|
@ -16,32 +16,26 @@ class ElevationAppBarLayout @JvmOverloads constructor(
|
|||
private var origStateAnimator: StateListAnimator? = null
|
||||
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
origStateAnimator = stateListAnimator
|
||||
}
|
||||
origStateAnimator = stateListAnimator
|
||||
}
|
||||
|
||||
fun enableElevation() {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
stateListAnimator = origStateAnimator
|
||||
}
|
||||
stateListAnimator = origStateAnimator
|
||||
}
|
||||
|
||||
fun disableElevation() {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
stateListAnimator = StateListAnimator().apply {
|
||||
val objAnimator = ObjectAnimator.ofFloat(this, "elevation", 0f)
|
||||
stateListAnimator = StateListAnimator().apply {
|
||||
val objAnimator = ObjectAnimator.ofFloat(this, "elevation", 0f)
|
||||
|
||||
// Enabled and collapsible, but not collapsed means not elevated
|
||||
addState(intArrayOf(android.R.attr.enabled, R.attr.state_collapsible, -R.attr.state_collapsed),
|
||||
objAnimator)
|
||||
// Enabled and collapsible, but not collapsed means not elevated
|
||||
addState(intArrayOf(android.R.attr.enabled, R.attr.state_collapsible, -R.attr.state_collapsed),
|
||||
objAnimator)
|
||||
|
||||
// Default enabled state
|
||||
addState(intArrayOf(android.R.attr.enabled), objAnimator)
|
||||
// Default enabled state
|
||||
addState(intArrayOf(android.R.attr.enabled), objAnimator)
|
||||
|
||||
// Disabled state
|
||||
addState(IntArray(0), objAnimator)
|
||||
}
|
||||
// Disabled state
|
||||
addState(IntArray(0), objAnimator)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,11 @@ package eu.kanade.tachiyomi.widget
|
|||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewAnimationUtils
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
View(context, attrs) {
|
||||
|
||||
|
@ -21,28 +18,25 @@ class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
* @param initialRadius size of radius of animation
|
||||
*/
|
||||
fun hideRevealEffect(centerX: Int, centerY: Int, initialRadius: Int) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
// Make the view visible.
|
||||
this.visibility = View.VISIBLE
|
||||
|
||||
// Make the view visible.
|
||||
this.visibility = View.VISIBLE
|
||||
// Create the animation (the final radius is zero).
|
||||
val anim = ViewAnimationUtils.createCircularReveal(
|
||||
this, centerX, centerY, initialRadius.toFloat(), 0f)
|
||||
|
||||
// Create the animation (the final radius is zero).
|
||||
val anim = ViewAnimationUtils.createCircularReveal(
|
||||
this, centerX, centerY, initialRadius.toFloat(), 0f)
|
||||
// Set duration of animation.
|
||||
anim.duration = 500
|
||||
|
||||
// Set duration of animation.
|
||||
anim.duration = 500
|
||||
// make the view invisible when the animation is done
|
||||
anim.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
super.onAnimationEnd(animation)
|
||||
this@RevealAnimationView.visibility = View.INVISIBLE
|
||||
}
|
||||
})
|
||||
|
||||
// make the view invisible when the animation is done
|
||||
anim.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
super.onAnimationEnd(animation)
|
||||
this@RevealAnimationView.visibility = View.INVISIBLE
|
||||
}
|
||||
})
|
||||
|
||||
anim.start()
|
||||
}
|
||||
anim.start()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,25 +49,20 @@ class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
* @return sdk version lower then 21
|
||||
*/
|
||||
fun showRevealEffect(centerX: Int, centerY: Int, listener: Animator.AnimatorListener): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
this.visibility = View.VISIBLE
|
||||
|
||||
this.visibility = View.VISIBLE
|
||||
val height = this.height
|
||||
|
||||
val height = this.height
|
||||
// Create animation
|
||||
val anim = ViewAnimationUtils.createCircularReveal(
|
||||
this, centerX, centerY, 0f, height.toFloat())
|
||||
|
||||
// Create animation
|
||||
val anim = ViewAnimationUtils.createCircularReveal(
|
||||
this, centerX, centerY, 0f, height.toFloat())
|
||||
// Set duration of animation
|
||||
anim.duration = 350
|
||||
|
||||
// Set duration of animation
|
||||
anim.duration = 350
|
||||
|
||||
anim.addListener(listener)
|
||||
anim.start()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
anim.addListener(listener)
|
||||
anim.start()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/selectorColorDark"
|
||||
>
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorDark"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorDark"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/md_black_1000"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/colorAccentDark"
|
||||
>
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorDark"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorDark"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/backgroundDark"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/colorAccentLight"
|
||||
>
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorLight"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorLight"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/backgroundLight"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorDark"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorDark"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/md_black_1000"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorDark"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorDark"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/dialogDark"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorLight">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorLight"/>
|
||||
</item>
|
||||
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorLight"/>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<color android:color="@color/dialogLight"/>
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/selectorColorDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorDark" />
|
||||
</item>
|
||||
|
||||
<item android:state_focused="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:state_pressed="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:state_activated="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:drawable="@color/md_black_1000"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorDark" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/md_black_1000" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/colorAccentDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorDark" />
|
||||
</item>
|
||||
|
||||
<item android:state_focused="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:state_pressed="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:state_activated="true" android:drawable="@color/selectorColorDark"/>
|
||||
<item android:drawable="@color/backgroundDark"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorDark" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/backgroundDark" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/colorAccentLight">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/selectorColorLight" />
|
||||
</item>
|
||||
|
||||
<item android:state_focused="true" android:drawable="@color/selectorColorLight"/>
|
||||
<item android:state_pressed="true" android:drawable="@color/selectorColorLight"/>
|
||||
<item android:state_activated="true" android:drawable="@color/selectorColorLight"/>
|
||||
<item android:drawable="@color/backgroundLight"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/selectorColorLight" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/backgroundLight" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:exitFadeDuration="@android:integer/config_longAnimTime">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorDark" />
|
||||
</item>
|
||||
|
||||
<item android:drawable="@color/rippleColorDark" android:state_focused="true"/>
|
||||
<item android:drawable="@color/rippleColorDark" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/rippleColorDark" android:state_activated="true"/>
|
||||
<item android:drawable="@color/md_black_1000"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorDark" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/md_black_1000" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:exitFadeDuration="@android:integer/config_longAnimTime">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorDark">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorDark" />
|
||||
</item>
|
||||
|
||||
<item android:drawable="@color/rippleColorDark" android:state_focused="true"/>
|
||||
<item android:drawable="@color/rippleColorDark" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/rippleColorDark" android:state_activated="true"/>
|
||||
<item android:drawable="@color/dialogDark"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorDark" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/dialogDark" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:exitFadeDuration="@android:integer/config_longAnimTime">
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/rippleColorLight">
|
||||
<item>
|
||||
<selector>
|
||||
<item android:state_selected="true">
|
||||
<color android:color="@color/rippleColorLight" />
|
||||
</item>
|
||||
|
||||
<item android:drawable="@color/rippleColorLight" android:state_focused="true"/>
|
||||
<item android:drawable="@color/rippleColorLight" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/rippleColorLight" android:state_activated="true"/>
|
||||
<item android:drawable="@color/dialogLight"/>
|
||||
<item android:state_activated="true">
|
||||
<color android:color="@color/rippleColorLight" />
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
<item>
|
||||
<color android:color="@color/dialogLight" />
|
||||
</item>
|
||||
</selector>
|
||||
</item>
|
||||
</ripple>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--Nav header-->
|
||||
<dimen name="navigation_drawer_header_margin">41dp</dimen>
|
||||
</resources>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- String Fonts -->
|
||||
<string name="font_roboto_medium" translatable="false">sans-serif-medium</string>
|
||||
<string name="font_roboto_regular" translatable="false">sans-serif-regular</string>
|
||||
</resources>
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--===========-->
|
||||
<!-- Main Theme-->
|
||||
<!--===========-->
|
||||
<style name="Theme.Tachiyomi" parent="Theme.Base">
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<!--=============-->
|
||||
<!-- Dark Themes -->
|
||||
<!--=============-->
|
||||
<style name="Theme.Tachiyomi.Dark" parent="Theme.Base.Dark">
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Tachiyomi.DarkBlue" parent="Theme.Base.Dark">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<!--==============-->
|
||||
<!-- Amoled Theme -->
|
||||
<!--==============-->
|
||||
<style name="Theme.Tachiyomi.Amoled" parent="Theme.Base.Amoled">
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<!--==============-->
|
||||
<!-- Reader Theme -->
|
||||
<!--==============-->
|
||||
<style name="Theme.Reader" parent="Theme.Base.Reader.Dark">
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:statusBarColor">?colorPrimaryDark</item>
|
||||
<item name="android:navigationBarColor">?colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Reader.Light" parent="Theme.Base.Reader.Light">
|
||||
<!-- Attributes specific for SDK 21 and up -->
|
||||
<item name="android:statusBarColor">?colorPrimaryDark</item>
|
||||
<item name="android:navigationBarColor">?colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -20,10 +20,9 @@
|
|||
<dimen name="text_body">16sp</dimen>
|
||||
<dimen name="text_small_body">14sp</dimen>
|
||||
|
||||
|
||||
<!--Nav header-->
|
||||
<dimen name="navigation_drawer_header_height">158dp</dimen>
|
||||
<dimen name="navigation_drawer_header_margin">16dp</dimen>
|
||||
<dimen name="navigation_drawer_header_margin">41dp</dimen>
|
||||
|
||||
<dimen name="bottom_sheet_width">0dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- String Fonts -->
|
||||
<string name="font_roboto_medium" translatable="false">sans-serif</string>
|
||||
<string name="font_roboto_regular" translatable="false">sans-serif</string>
|
||||
</resources>
|
|
@ -50,7 +50,7 @@
|
|||
</style>
|
||||
|
||||
<style name="TextAppearance.Regular">
|
||||
<item name="android:fontFamily">@string/font_roboto_regular</item>
|
||||
<item name="android:fontFamily">sans-serif-regular</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Regular.Body1">
|
||||
|
@ -102,7 +102,7 @@
|
|||
</style>
|
||||
|
||||
<style name="TextAppearance.Medium">
|
||||
<item name="android:fontFamily">@string/font_roboto_medium</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Medium.Title">
|
||||
|
|
|
@ -39,8 +39,13 @@
|
|||
<item name="icon_color">@color/iconColorLight</item>
|
||||
</style>
|
||||
|
||||
<!--===========-->
|
||||
<!-- Main Theme-->
|
||||
<!--===========-->
|
||||
<style name="Theme.Tachiyomi" parent="Theme.Base">
|
||||
<!-- Attributes specific for SDK 16 to SDK 20 -->
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<!--=============-->
|
||||
|
@ -61,6 +66,10 @@
|
|||
<item name="android:divider">@color/dividerDark</item>
|
||||
<item name="android:listDivider">@drawable/line_divider_dark</item>
|
||||
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
|
||||
|
||||
<!-- Themes -->
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
|
||||
|
@ -86,6 +95,10 @@
|
|||
<style name="Theme.Tachiyomi.DarkBlue" parent="Theme.Base.Dark">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<!--==============-->
|
||||
|
@ -96,6 +109,10 @@
|
|||
<item name="colorPrimaryDark">@color/colorAmoledPrimary</item>
|
||||
<item name="android:colorBackground">@color/md_black_1000</item>
|
||||
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
|
||||
<!-- Custom Attributes-->
|
||||
<item name="selectable_list_drawable">@drawable/list_item_selector_amoled</item>
|
||||
<item name="selectable_library_drawable">@drawable/library_item_selector_amoled</item>
|
||||
|
@ -113,12 +130,18 @@
|
|||
<item name="colorPrimary">@color/colorDarkPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorDarkPrimaryDark</item>
|
||||
<item name="android:colorBackground">@android:color/black</item>
|
||||
|
||||
<item name="android:statusBarColor">?colorPrimaryDark</item>
|
||||
<item name="android:navigationBarColor">?colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Base.Reader.Light" parent="Theme.Base">
|
||||
<item name="colorPrimary">@color/colorDarkPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorDarkPrimaryDark</item>
|
||||
<item name="android:colorBackground">@android:color/white</item>
|
||||
|
||||
<item name="android:statusBarColor">?colorPrimaryDark</item>
|
||||
<item name="android:navigationBarColor">?colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Reader" parent="Theme.Base.Reader.Dark">
|
||||
|
|
Reference in a new issue