Compare commits
1 Commits
ui
...
v0.3-legac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fe40ac17e |
@@ -12,13 +12,14 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdkVersion 21
|
||||
minSdkVersion 16
|
||||
maxSdkVersion 20
|
||||
targetSdkVersion 29
|
||||
versionCode gitCommits
|
||||
versionName '0.3'
|
||||
|
||||
buildConfigField 'String', 'GIT_BRANCH', "\"${gitBranch}\""
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
kapt {
|
||||
arguments {
|
||||
arg('room.schemaLocation', "$projectDir/schemas".toString())
|
||||
@@ -82,7 +83,7 @@ dependencies {
|
||||
implementation 'com.github.moxy-community:moxy-ktx:2.1.2'
|
||||
kapt 'com.github.moxy-community:moxy-compiler:2.1.2'
|
||||
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.5.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.10'
|
||||
implementation 'com.squareup.okio:okio:2.5.0'
|
||||
implementation 'org.jsoup:jsoup:1.13.1'
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class KotatsuApp : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
initKoin()
|
||||
initCoil()
|
||||
Thread.setDefaultUncaughtExceptionHandler(AppCrashHandler(applicationContext))
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.koitharu.kotatsu.core.local.cookies
|
||||
|
||||
import org.koitharu.kotatsu.core.local.cookies.persistence.CookiePersistor
|
||||
import okhttp3.Cookie
|
||||
import okhttp3.HttpUrl
|
||||
import org.koitharu.kotatsu.core.local.cookies.cache.CookieCache
|
||||
import org.koitharu.kotatsu.core.local.cookies.persistence.CookiePersistor
|
||||
import java.util.*
|
||||
|
||||
class PersistentCookieJar(
|
||||
@@ -72,7 +72,7 @@ class PersistentCookieJar(
|
||||
fun filterPersistentCookies(cookies: List<Cookie>): List<Cookie> {
|
||||
val persistentCookies: MutableList<Cookie> = ArrayList()
|
||||
for (cookie in cookies) {
|
||||
if (cookie.persistent) {
|
||||
if (cookie.persistent()) {
|
||||
persistentCookies.add(cookie)
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ class PersistentCookieJar(
|
||||
|
||||
@JvmStatic
|
||||
fun isCookieExpired(cookie: Cookie): Boolean {
|
||||
return cookie.expiresAt < System.currentTimeMillis()
|
||||
return cookie.expiresAt() < System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,18 +30,18 @@ internal class IdentifiableCookie(val cookie: Cookie) {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is IdentifiableCookie) return false
|
||||
return other.cookie.name == cookie.name && other.cookie.domain == cookie.domain
|
||||
&& other.cookie.path == cookie.path && other.cookie.secure == cookie.secure
|
||||
&& other.cookie.hostOnly == cookie.hostOnly
|
||||
return other.cookie.name() == cookie.name() && other.cookie.domain() == cookie.domain()
|
||||
&& other.cookie.path() == cookie.path() && other.cookie.secure() == cookie.secure()
|
||||
&& other.cookie.hostOnly() == cookie.hostOnly()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var hash = 17
|
||||
hash = 31 * hash + cookie.name.hashCode()
|
||||
hash = 31 * hash + cookie.domain.hashCode()
|
||||
hash = 31 * hash + cookie.path.hashCode()
|
||||
hash = 31 * hash + if (cookie.secure) 0 else 1
|
||||
hash = 31 * hash + if (cookie.hostOnly) 0 else 1
|
||||
hash = 31 * hash + cookie.name().hashCode()
|
||||
hash = 31 * hash + cookie.domain().hashCode()
|
||||
hash = 31 * hash + cookie.path().hashCode()
|
||||
hash = 31 * hash + if (cookie.secure()) 0 else 1
|
||||
hash = 31 * hash + if (cookie.hostOnly()) 0 else 1
|
||||
return hash
|
||||
}
|
||||
|
||||
|
||||
@@ -73,14 +73,14 @@ class SerializableCookie : Serializable {
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun writeObject(out: ObjectOutputStream) {
|
||||
out.writeObject(cookie!!.name)
|
||||
out.writeObject(cookie!!.value)
|
||||
out.writeLong(if (cookie!!.persistent) cookie!!.expiresAt else NON_VALID_EXPIRES_AT)
|
||||
out.writeObject(cookie!!.domain)
|
||||
out.writeObject(cookie!!.path)
|
||||
out.writeBoolean(cookie!!.secure)
|
||||
out.writeBoolean(cookie!!.httpOnly)
|
||||
out.writeBoolean(cookie!!.hostOnly)
|
||||
out.writeObject(cookie!!.name())
|
||||
out.writeObject(cookie!!.value())
|
||||
out.writeLong(if (cookie!!.persistent()) cookie!!.expiresAt() else NON_VALID_EXPIRES_AT)
|
||||
out.writeObject(cookie!!.domain())
|
||||
out.writeObject(cookie!!.path())
|
||||
out.writeBoolean(cookie!!.secure())
|
||||
out.writeBoolean(cookie!!.httpOnly())
|
||||
out.writeBoolean(cookie!!.hostOnly())
|
||||
}
|
||||
|
||||
@Throws(IOException::class, ClassNotFoundException::class)
|
||||
|
||||
@@ -64,7 +64,7 @@ class SharedPrefsCookiePersistor(private val sharedPreferences: SharedPreference
|
||||
private companion object {
|
||||
|
||||
fun createCookieKey(cookie: Cookie): String {
|
||||
return (if (cookie.secure) "https" else "http") + "://" + cookie.domain + cookie.path + "|" + cookie.name
|
||||
return (if (cookie.secure()) "https" else "http") + "://" + cookie.domain() + cookie.path() + "|" + cookie.name()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.parser
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
import org.koin.core.KoinComponent
|
||||
@@ -14,6 +15,7 @@ import org.koitharu.kotatsu.utils.AlphanumComparator
|
||||
import org.koitharu.kotatsu.utils.ext.longHashCode
|
||||
import org.koitharu.kotatsu.utils.ext.readText
|
||||
import org.koitharu.kotatsu.utils.ext.safe
|
||||
import org.koitharu.kotatsu.utils.ext.sub
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
@@ -29,8 +31,11 @@ class LocalMangaRepository : MangaRepository, KoinComponent {
|
||||
sortOrder: SortOrder?,
|
||||
tag: MangaTag?
|
||||
): List<Manga> {
|
||||
val files = context.getExternalFilesDirs("manga")
|
||||
.flatMap { x -> x?.listFiles(CbzFilter())?.toList().orEmpty() }
|
||||
val files = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
context.getExternalFilesDirs("manga") + context.filesDir.sub("manga")
|
||||
} else {
|
||||
arrayOf(context.getExternalFilesDir("manga"), context.filesDir.sub("manga"))
|
||||
}.flatMap { x -> x?.listFiles(CbzFilter())?.toList().orEmpty() }
|
||||
return files.mapNotNull { x -> safe { getFromFile(x) } }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.koitharu.kotatsu.domain
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Size
|
||||
import android.graphics.Point
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.koin.core.KoinComponent
|
||||
@@ -29,10 +29,10 @@ object MangaUtils : KoinComponent {
|
||||
.get()
|
||||
.build()
|
||||
val size = client.newCall(request).await().use {
|
||||
getBitmapSize(it.body?.byteStream())
|
||||
getBitmapSize(it.body()?.byteStream())
|
||||
}
|
||||
return when {
|
||||
size.width * 2 < size.height -> ReaderMode.WEBTOON
|
||||
size.x * 2 < size.y -> ReaderMode.WEBTOON
|
||||
else -> ReaderMode.STANDARD
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -44,7 +44,7 @@ object MangaUtils : KoinComponent {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun getBitmapSize(input: InputStream?): Size {
|
||||
private fun getBitmapSize(input: InputStream?): Point {
|
||||
val options = BitmapFactory.Options().apply {
|
||||
inJustDecodeBounds = true
|
||||
}
|
||||
@@ -52,6 +52,6 @@ object MangaUtils : KoinComponent {
|
||||
val imageHeight: Int = options.outHeight
|
||||
val imageWidth: Int = options.outWidth
|
||||
check(imageHeight > 0 && imageWidth > 0)
|
||||
return Size(imageWidth, imageHeight)
|
||||
return Point(imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,9 @@ class MangaZip(val file: File) {
|
||||
if (!file.exists()) {
|
||||
return
|
||||
}
|
||||
dir.listFiles()?.forEach {
|
||||
it?.deleteRecursively()
|
||||
}
|
||||
ZipInputStream(file.inputStream()).use { input ->
|
||||
while (true) {
|
||||
val entry = input.nextEntry ?: return
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.koitharu.kotatsu.ui.browser
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.annotation.RequiresApi
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.koin.core.KoinComponent
|
||||
@@ -38,6 +40,7 @@ class BrowserClient(private val callback: BrowserCallback) : WebViewClient(), Ko
|
||||
return url?.let(::doRequest)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
|
||||
return request?.url?.toString()?.let(::doRequest)
|
||||
}
|
||||
@@ -47,11 +50,11 @@ class BrowserClient(private val callback: BrowserCallback) : WebViewClient(), Ko
|
||||
.url(url)
|
||||
.build()
|
||||
val response = okHttp.newCall(request).execute()
|
||||
val ct = response.body?.contentType()
|
||||
val ct = response.body()?.contentType()
|
||||
WebResourceResponse(
|
||||
"${ct?.type}/${ct?.subtype}",
|
||||
"${ct?.type()}/${ct?.subtype()}",
|
||||
ct?.charset()?.name() ?: "utf-8",
|
||||
response.body?.byteStream()
|
||||
response.body()?.byteStream()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,21 @@ abstract class BaseActivity : MvpAppCompatActivity(), KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||
val keyCode = event.keyCode
|
||||
val action = event.action
|
||||
val isDown = action == KeyEvent.ACTION_DOWN
|
||||
return if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||
if (isDown) {
|
||||
onKeyDown(keyCode, event)
|
||||
} else {
|
||||
onKeyUp(keyCode, event)
|
||||
}
|
||||
} else {
|
||||
super.dispatchKeyEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
//TODO remove. Just for testing
|
||||
if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
|
||||
|
||||
@@ -1,36 +1,37 @@
|
||||
package org.koitharu.kotatsu.ui.common
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
|
||||
|
||||
abstract class BaseFullscreenActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
with(window) {
|
||||
// addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
statusBarColor = Color.TRANSPARENT
|
||||
navigationBarColor = Color.TRANSPARENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
}
|
||||
}
|
||||
showSystemUI()
|
||||
}
|
||||
|
||||
protected fun hideSystemUI() {
|
||||
window.decorView.systemUiVisibility = (
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
)
|
||||
window.decorView.systemUiVisibility =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
)
|
||||
} else {
|
||||
(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@ package org.koitharu.kotatsu.ui.common.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import kotlinx.android.synthetic.main.item_storage.view.*
|
||||
@@ -15,6 +17,7 @@ import org.koitharu.kotatsu.utils.ext.inflate
|
||||
import org.koitharu.kotatsu.utils.ext.longHashCode
|
||||
import java.io.File
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class StorageSelectDialog private constructor(private val delegate: AlertDialog) :
|
||||
DialogInterface by delegate {
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.koitharu.kotatsu.ui.common.list
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.util.*
|
||||
|
||||
class AdapterUpdater<T>(oldList: List<T>, newList: List<T>, getId: (T) -> Long) {
|
||||
|
||||
@@ -12,7 +11,7 @@ class AdapterUpdater<T>(oldList: List<T>, newList: List<T>, getId: (T) -> Long)
|
||||
getId(oldList[oldItemPosition]) == getId(newList[newItemPosition])
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
|
||||
Objects.equals(oldList[oldItemPosition], newList[newItemPosition])
|
||||
oldList[oldItemPosition]?.equals(newList[newItemPosition]) == true
|
||||
|
||||
override fun getOldListSize() = oldList.size
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ package org.koitharu.kotatsu.ui.common.list
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import okhttp3.internal.toImmutableList
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koitharu.kotatsu.utils.ext.replaceWith
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecyclerItemClickListener<T>? = null) :
|
||||
RecyclerView.Adapter<BaseViewHolder<T, E>>(),
|
||||
@@ -12,7 +13,8 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
|
||||
|
||||
protected val dataSet = ArrayList<T>() //TODO make private
|
||||
|
||||
val items get() = dataSet.toImmutableList()
|
||||
val items: List<T>
|
||||
get() = Collections.unmodifiableList(dataSet)
|
||||
|
||||
val hasItems get() = dataSet.isNotEmpty()
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class DownloadNotification(private val context: Context) {
|
||||
fun fillFrom(manga: Manga) {
|
||||
builder.setContentTitle(manga.title)
|
||||
builder.setContentText(context.getString(R.string.manga_downloading_))
|
||||
builder.setTicker(context.getString(R.string.manga_downloading_))
|
||||
builder.setProgress(1, 0, true)
|
||||
builder.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||
builder.setLargeIcon(null)
|
||||
@@ -56,7 +57,7 @@ class DownloadNotification(private val context: Context) {
|
||||
} else {
|
||||
val intent = DownloadService.getCancelIntent(context, startId)
|
||||
builder.addAction(
|
||||
R.drawable.ic_cross,
|
||||
R.drawable.ic_cross_compat,
|
||||
context.getString(android.R.string.cancel),
|
||||
PendingIntent.getService(
|
||||
context,
|
||||
|
||||
@@ -80,7 +80,10 @@ class DownloadService : BaseService() {
|
||||
notification.setCancelId(startId)
|
||||
startForeground(DownloadNotification.NOTIFICATION_ID, notification())
|
||||
}
|
||||
val destination = getExternalFilesDir("manga")!!
|
||||
val destination = getExternalFilesDir("manga") ?: filesDir.sub("manga").takeIf {
|
||||
it.exists() || it.mkdir()
|
||||
}
|
||||
checkNotNull(destination) { "Cannot find place to store file" }
|
||||
var output: MangaZip? = null
|
||||
try {
|
||||
val repo = MangaProviderFactory.create(manga.source)
|
||||
@@ -146,6 +149,7 @@ class DownloadService : BaseService() {
|
||||
notification.update()
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
withContext(Dispatchers.Main) {
|
||||
notification.setError(e)
|
||||
notification.setCancelId(0)
|
||||
@@ -179,7 +183,7 @@ class DownloadService : BaseService() {
|
||||
okHttp.newCall(request).await().use { response ->
|
||||
val file = destination.sub("page.tmp")
|
||||
file.outputStream().use { out ->
|
||||
response.body!!.byteStream().copyTo(out)
|
||||
response.body()!!.byteStream().copyTo(out)
|
||||
}
|
||||
file
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
navigationView.setNavigationItemSelectedListener(this)
|
||||
settings.subscribe(this)
|
||||
|
||||
fab.imageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
fab.supportImageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
fab.isVisible = true
|
||||
fab.setOnClickListener {
|
||||
presenter.openLastReader()
|
||||
|
||||
@@ -160,7 +160,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
.show()
|
||||
} else {
|
||||
textView_holder.text = e.getDisplayMessage(resources)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
textView_holder.setCompoundDrawablesWithIntrinsicBounds(
|
||||
0,
|
||||
R.drawable.ic_error_large,
|
||||
0,
|
||||
@@ -221,7 +221,7 @@ abstract class MangaListFragment<E> : BaseFragment(R.layout.fragment_list), Mang
|
||||
}
|
||||
|
||||
protected open fun setUpEmptyListHolder() {
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
|
||||
textView_holder.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
textView_holder.setText(R.string.nothing_found)
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ abstract class MangaListSheet<E> : BaseBottomSheet(R.layout.sheet_list), MangaLi
|
||||
if (dialog !is BottomSheetDialog) {
|
||||
toolbar.isVisible = true
|
||||
textView_title.isVisible = false
|
||||
appbar.elevation = resources.getDimension(R.dimen.elevation_large)
|
||||
// appbar.elevation = resources.getDimension(R.dimen.elevation_large)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +93,11 @@ abstract class MangaListSheet<E> : BaseBottomSheet(R.layout.sheet_list), MangaLi
|
||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
toolbar.isVisible = true
|
||||
textView_title.isVisible = false
|
||||
appbar.elevation = elevation
|
||||
// appbar.elevation = elevation
|
||||
} else {
|
||||
toolbar.isVisible = false
|
||||
textView_title.isVisible = true
|
||||
appbar.elevation = 0f
|
||||
// appbar.elevation = 0f
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -39,7 +39,7 @@ class FavouritesListFragment : MangaListFragment<Unit>(), MangaListView<Unit> {
|
||||
|
||||
override fun setUpEmptyListHolder() {
|
||||
textView_holder.setText(R.string.you_have_not_favourites_yet)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
textView_holder.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -33,7 +33,7 @@ class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener<Favourite
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_categories)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
fab_add.imageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
fab_add.supportImageTintList = ColorStateList.valueOf(Color.WHITE)
|
||||
adapter = CategoriesAdapter(this)
|
||||
recyclerView.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL))
|
||||
recyclerView.adapter = adapter
|
||||
|
||||
@@ -49,7 +49,7 @@ class HistoryListFragment : MangaListFragment<MangaHistory>(), MangaListView<Man
|
||||
|
||||
override fun setUpEmptyListHolder() {
|
||||
textView_holder.setText(R.string.text_history_holder)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
textView_holder.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
override fun onCreatePopupMenu(inflater: MenuInflater, menu: Menu, data: Manga) {
|
||||
|
||||
@@ -60,7 +60,7 @@ class LocalListFragment : MangaListFragment<File>() {
|
||||
|
||||
override fun setUpEmptyListHolder() {
|
||||
textView_holder.setText(R.string.text_local_holder)
|
||||
textView_holder.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
|
||||
textView_holder.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
|
||||
@@ -51,13 +51,13 @@ class PageLoader : KoinComponent, CoroutineScope, DisposableHandle {
|
||||
.cacheControl(CacheUtils.CONTROL_DISABLED)
|
||||
.build()
|
||||
okHttp.newCall(request).await().use { response ->
|
||||
val body = response.body!!
|
||||
val body = response.body()!!
|
||||
val type = body.contentType()
|
||||
check(type?.type == "image") {
|
||||
"Unexpected content type ${type?.type}/${type?.subtype}"
|
||||
check(type?.type() == "image") {
|
||||
"Unexpected content type ${type?.type()}/${type?.subtype()}"
|
||||
}
|
||||
cache.put(url) { out ->
|
||||
response.body!!.byteStream().copyTo(out)
|
||||
response.body()!!.byteStream().copyTo(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.commit
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_reader.*
|
||||
@@ -79,10 +78,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
||||
getString(R.string.chapter_d_of_d, state.chapter?.number ?: 0, size)
|
||||
}
|
||||
|
||||
appbar_bottom.setOnApplyWindowInsetsListener { view, insets ->
|
||||
/*appbar_bottom.setOnApplyWindowInsetsListener { view, insets ->
|
||||
view.updatePadding(bottom = insets.systemWindowInsetBottom)
|
||||
insets
|
||||
}
|
||||
}*/
|
||||
|
||||
settings.subscribe(this)
|
||||
loadSettings()
|
||||
@@ -286,6 +285,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh
|
||||
setUiIsVisible(!appbar_top.isVisible)
|
||||
true
|
||||
}
|
||||
KeyEvent.KEYCODE_MENU -> {
|
||||
setUiIsVisible(!appbar_top.isVisible)
|
||||
true
|
||||
}
|
||||
else -> super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ class ReaderPresenter : BasePresenter<ReaderView>() {
|
||||
val fileName =
|
||||
URLUtil.guessFileName(url, response.contentDisposition, response.mimeType)
|
||||
MediaStoreCompat.insertImage(resolver, fileName) {
|
||||
response.body!!.byteStream().copyTo(it)
|
||||
response.body()!!.byteStream().copyTo(it)
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
|
||||
@@ -13,14 +13,14 @@ class PageAnimTransformer : ViewPager2.PageTransformer {
|
||||
position <= 0 -> { // [-1,0]
|
||||
alpha = 1f
|
||||
translationX = 0f
|
||||
translationZ = 0f
|
||||
// translationZ = 0f
|
||||
scaleX = 1 + FACTOR * position
|
||||
scaleY = 1f
|
||||
}
|
||||
position <= 1 -> { // (0,1]
|
||||
alpha = 1f
|
||||
translationX = pageWidth * -position
|
||||
translationZ = -1f
|
||||
// translationZ = -1f
|
||||
scaleX = 1f
|
||||
scaleY = 1f
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages),
|
||||
if (dialog !is BottomSheetDialog) {
|
||||
toolbar.isVisible = true
|
||||
textView_title.isVisible = false
|
||||
appbar.elevation = resources.getDimension(R.dimen.elevation_large)
|
||||
// appbar.elevation = resources.getDimension(R.dimen.elevation_large)
|
||||
}
|
||||
recyclerView.addOnLayoutChangeListener(UiUtils.SpanCountResolver)
|
||||
}
|
||||
@@ -57,11 +57,11 @@ class PagesThumbnailsSheet : BaseBottomSheet(R.layout.sheet_pages),
|
||||
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
toolbar.isVisible = true
|
||||
textView_title.isVisible = false
|
||||
appbar.elevation = elevation
|
||||
// appbar.elevation = elevation
|
||||
} else {
|
||||
toolbar.isVisible = false
|
||||
textView_title.isVisible = true
|
||||
appbar.elevation = 0f
|
||||
// appbar.elevation = 0f
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -116,9 +116,8 @@ class AppUpdateService : BaseService() {
|
||||
private const val CHANNEL_ID = "update"
|
||||
private val PERIOD = TimeUnit.HOURS.toMillis(6)
|
||||
|
||||
fun isUpdateSupported(context: Context): Boolean {
|
||||
return getCertificateSHA1Fingerprint(context) == CERT_SHA1
|
||||
}
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun isUpdateSupported(context: Context) = false
|
||||
|
||||
fun startIfRequired(context: Context) {
|
||||
if (!isUpdateSupported(context)) {
|
||||
|
||||
@@ -3,8 +3,6 @@ package org.koitharu.kotatsu.ui.settings
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.transition.Slide
|
||||
import android.view.Gravity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.preference.Preference
|
||||
@@ -24,7 +22,7 @@ class SettingsActivity : BaseActivity(),
|
||||
if (supportFragmentManager.findFragmentById(R.id.container) == null) {
|
||||
supportFragmentManager.commit {
|
||||
replace(R.id.container, MainSettingsFragment().also {
|
||||
it.exitTransition = Slide(Gravity.START)
|
||||
// it.exitTransition = Slide(Gravity.START)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -48,8 +46,8 @@ class SettingsActivity : BaseActivity(),
|
||||
}
|
||||
|
||||
private fun openFragment(fragment: Fragment) {
|
||||
fragment.enterTransition = Slide(Gravity.END)
|
||||
fragment.exitTransition = Slide(Gravity.START)
|
||||
// fragment.enterTransition = Slide(Gravity.END)
|
||||
// fragment.exitTransition = Slide(Gravity.START)
|
||||
supportFragmentManager.commit {
|
||||
replace(R.id.container, fragment)
|
||||
addToBackStack(null)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.koitharu.kotatsu.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.annotation.WorkerThread
|
||||
import okhttp3.Cache
|
||||
import okhttp3.CacheControl
|
||||
@@ -17,8 +18,11 @@ object CacheUtils {
|
||||
.build()
|
||||
|
||||
@JvmStatic
|
||||
fun getCacheDirs(context: Context) = (context.externalCacheDirs + context.cacheDir)
|
||||
.filterNotNull()
|
||||
fun getCacheDirs(context: Context) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
(context.externalCacheDirs + context.cacheDir)
|
||||
} else {
|
||||
arrayOf(context.externalCacheDir, context.cacheDir)
|
||||
}.filterNotNull()
|
||||
.distinctBy { it.absolutePath }
|
||||
|
||||
@JvmStatic
|
||||
@@ -35,7 +39,7 @@ object CacheUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun createHttpCache(context: Context) = Cache(
|
||||
directory = (context.externalCacheDir ?: context.cacheDir).sub("http"),
|
||||
maxSize = FileSizeUtils.mbToBytes(60)
|
||||
(context.externalCacheDir ?: context.cacheDir).sub("http"),
|
||||
FileSizeUtils.mbToBytes(60)
|
||||
)
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.koitharu.kotatsu.utils.ext
|
||||
import okhttp3.Response
|
||||
|
||||
val Response.mimeType: String?
|
||||
get() = body?.contentType()?.run { "$type/$subtype" }
|
||||
get() = body()?.contentType()?.run { "${type()}/${subtype()}" }
|
||||
|
||||
val Response.contentDisposition: String?
|
||||
get() = header("Content-Disposition")
|
||||
@@ -1,30 +1,30 @@
|
||||
package org.koitharu.kotatsu.utils.ext
|
||||
|
||||
import okhttp3.Response
|
||||
import okhttp3.internal.closeQuietly
|
||||
import okhttp3.internal.Util.closeQuietly
|
||||
import org.json.JSONObject
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
|
||||
fun Response.parseHtml(): Document {
|
||||
try {
|
||||
val stream = body?.byteStream() ?: throw NullPointerException("Response body is null")
|
||||
val charset = body!!.contentType()?.charset()?.name()
|
||||
val stream = body()?.byteStream() ?: throw NullPointerException("Response body is null")
|
||||
val charset = body()!!.contentType()?.charset()?.name()
|
||||
return Jsoup.parse(
|
||||
stream,
|
||||
charset,
|
||||
request.url.toString()
|
||||
request().url().toString()
|
||||
)
|
||||
} finally {
|
||||
closeQuietly()
|
||||
closeQuietly(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun Response.parseJson(): JSONObject {
|
||||
try {
|
||||
val string = body?.string() ?: throw NullPointerException("Response body is null")
|
||||
val string = body()?.string() ?: throw NullPointerException("Response body is null")
|
||||
return JSONObject(string)
|
||||
} finally {
|
||||
closeQuietly()
|
||||
closeQuietly(this)
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_cross_compat.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_cross_compat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 319 B |
BIN
app/src/main/res/drawable-mdpi/ic_cross_compat.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_cross_compat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 B |
BIN
app/src/main/res/drawable-xhdpi/ic_cross_compat.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_cross_compat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 254 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_cross_compat.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_cross_compat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 534 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_cross_compat.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_cross_compat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 462 B |
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="?colorAccent" />
|
||||
<solid android:color="@color/red_accent" />
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="2dp"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="?android:textColorTertiary" />
|
||||
<solid android:color="@android:color/darker_gray" />
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="2dp"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<corners android:radius="5dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="?android:textColorTertiary" />
|
||||
android:color="@android:color/darker_gray" />
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="2dp"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<corners android:radius="5dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="?android:colorAccent" />
|
||||
android:color="@color/red_accent" />
|
||||
<padding
|
||||
android:bottom="2dp"
|
||||
android:left="2dp"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:tint="@android:color/darker_gray"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="12dp"
|
||||
android:height="12dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:tint="?attr/android:textColorPrimary"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="12dp"
|
||||
android:height="12dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:tint="?attr/android:textColorPrimary"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:tint="?attr/android:textColorPrimary"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="60dp"
|
||||
android:height="60dp"
|
||||
android:tint="?android:textColorTertiary"
|
||||
android:tint="?attr/android:textColorTertiary"
|
||||
android:viewportWidth="60"
|
||||
android:viewportHeight="60">
|
||||
<path
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:colorControlNormal"
|
||||
android:tint="?attr/android:textColorPrimary"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
android:fillColor="?attr/colorAccent"
|
||||
android:pathData="M12,15.4l-3.76,2.27l1,-4.28l-3.32,-2.88l4.38,-0.38l1.7,-4.03l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28z" />
|
||||
<path
|
||||
android:fillColor="?android:textColorPrimary"
|
||||
android:fillColor="?attr/android:textColorPrimary"
|
||||
android:pathData="M22,9.24l-7.19,-0.62L12,2L9.19,8.63L2,9.24l5.46,4.73L5.82,21L12,17.27L18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27l1,-4.28l-3.32,-2.88l4.38,-0.38L12,6.1l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28L12,15.4z" />
|
||||
</vector>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
android:tint="?attr/android:textColorPrimary"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
app:layout_constraintDimensionRatio="13:18"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_percent="0.3" />
|
||||
app:layout_constraintWidth_percent="0.3"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
@@ -73,7 +74,8 @@
|
||||
app:icon="@drawable/ic_read"
|
||||
app:iconPadding="12dp"
|
||||
app:layout_constraintEnd_toEndOf="@id/textView_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/ratingBar" />
|
||||
app:layout_constraintTop_toBottomOf="@id/ratingBar"
|
||||
android:layout_marginRight="4dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_favourite"
|
||||
@@ -83,12 +85,13 @@
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/add_to_favourites"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_tag_heart_outline"
|
||||
app:srcCompat="@drawable/ic_tag_heart_outline"
|
||||
app:layout_constraintBottom_toBottomOf="@id/button_read"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_read"
|
||||
app:layout_constraintTop_toTopOf="@id/button_read"
|
||||
app:tint="?colorAccent" />
|
||||
app:tint="?colorAccent"
|
||||
android:layout_marginRight="4dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider_top"
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/add_new_category"
|
||||
android:src="@drawable/ic_add"
|
||||
app:srcCompat="@drawable/ic_add"
|
||||
app:backgroundTint="?colorAccent"
|
||||
app:fabSize="normal"
|
||||
app:layout_anchor="@id/recyclerView"
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
android:layout_marginBottom="2dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
@@ -31,7 +33,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toStartOf="@id/button_restart"
|
||||
android:text="@string/close" />
|
||||
android:text="@string/close"
|
||||
android:layout_toLeftOf="@id/button_restart" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_restart"
|
||||
@@ -40,6 +43,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:text="@string/restart" />
|
||||
android:text="@string/restart"
|
||||
android:layout_alignParentRight="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -39,7 +39,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_read_fill"
|
||||
app:srcCompat="@drawable/ic_read_fill"
|
||||
android:visibility="gone"
|
||||
app:fabSize="normal"
|
||||
app:backgroundTint="?colorAccent"
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd">
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft">
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@android:id/checkbox"
|
||||
|
||||
@@ -40,12 +40,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:drawableEnd="@drawable/ic_add"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:text="@string/add_new_category"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textColor="?android:textColorPrimary" />
|
||||
android:textColor="?android:textColorPrimary"
|
||||
app:drawableEndCompat="@drawable/ic_add"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -20,7 +20,8 @@
|
||||
app:layout_constraintDimensionRatio="13:18"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_percent="0.3" />
|
||||
app:layout_constraintWidth_percent="0.3"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
@@ -76,7 +77,8 @@
|
||||
app:layout_constraintBottom_toBottomOf="@id/imageView_cover"
|
||||
app:layout_constraintEnd_toEndOf="@id/textView_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/ratingBar"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
app:layout_constraintVertical_bias="1"
|
||||
android:layout_marginRight="4dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView_favourite"
|
||||
@@ -86,14 +88,15 @@
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/add_to_favourites"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_tag_heart_outline"
|
||||
app:srcCompat="@drawable/ic_tag_heart_outline"
|
||||
app:layout_constraintBottom_toBottomOf="@id/button_read"
|
||||
app:layout_constraintDimensionRatio="1:1"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_read"
|
||||
app:layout_constraintTop_toTopOf="@id/button_read"
|
||||
app:layout_constraintStart_toStartOf="@id/textView_title"
|
||||
app:tint="?colorAccent" />
|
||||
app:tint="?colorAccent"
|
||||
android:layout_marginRight="4dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier_title"
|
||||
|
||||
@@ -11,4 +11,6 @@
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:text="@tools:sample/lorem[4]" />
|
||||
tools:text="@tools:sample/lorem[4]"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight" />
|
||||
@@ -13,4 +13,6 @@
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
tools:checked="true"
|
||||
tools:text="@tools:sample/lorem[4]" />
|
||||
tools:text="@tools:sample/lorem[4]"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight" />
|
||||
@@ -28,6 +28,7 @@
|
||||
android:maxLines="2"
|
||||
android:text="?android:textColorPrimary"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="@tools:sample/lorem[15]" />
|
||||
tools:text="@tools:sample/lorem[15]"
|
||||
android:layout_marginLeft="10dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -2,6 +2,7 @@
|
||||
<CheckedTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
@@ -11,4 +12,7 @@
|
||||
android:gravity="center_vertical|start"
|
||||
android:paddingStart="?android:listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:listPreferredItemPaddingEnd"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
tools:text="@tools:sample/full_names"
|
||||
android:drawableLeft="?android:listChoiceIndicatorSingle"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight" />
|
||||
@@ -12,4 +12,6 @@
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textStyle="bold"
|
||||
tools:text="@tools:sample/lorem[2]" />
|
||||
tools:text="@tools:sample/lorem[2]"
|
||||
android:paddingLeft="?android:listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?android:listPreferredItemPaddingRight" />
|
||||
@@ -8,7 +8,7 @@
|
||||
app:cardBackgroundColor="?android:windowBackground"
|
||||
app:cardElevation="0dp"
|
||||
app:cardMaxElevation="0dp"
|
||||
app:strokeColor="?android:colorControlNormal"
|
||||
app:strokeColor="?attr/colorControlNormal"
|
||||
app:strokeWidth="1px">
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
app:cardBackgroundColor="?android:windowBackground"
|
||||
app:cardElevation="0dp"
|
||||
app:cardMaxElevation="0dp"
|
||||
app:strokeColor="?android:colorControlNormal"
|
||||
app:strokeColor="?attr/colorControlNormal"
|
||||
app:strokeWidth="1px">
|
||||
|
||||
<LinearLayout
|
||||
@@ -89,10 +89,10 @@
|
||||
android:id="@+id/textView_rating"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@drawable/ic_star_rating"
|
||||
android:drawablePadding="4dp"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
tools:text="10/10" />
|
||||
tools:text="10/10"
|
||||
app:drawableStartCompat="@drawable/ic_star_rating" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:background="?android:windowBackground"
|
||||
android:layout_width="match_parent"
|
||||
@@ -33,11 +34,11 @@
|
||||
android:id="@+id/textView_error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_error_large"
|
||||
android:drawablePadding="12dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="@tools:sample/lorem[6]" />
|
||||
tools:text="@tools:sample/lorem[6]"
|
||||
app:drawableTopCompat="@drawable/ic_error_large" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_retry"
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
android:id="@+id/textView_error"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_error_large"
|
||||
android:drawablePadding="12dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="@tools:sample/lorem[6]" />
|
||||
tools:text="@tools:sample/lorem[6]"
|
||||
app:drawableTopCompat="@drawable/ic_error_large" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_retry"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?listPreferredItemHeightSmall"
|
||||
android:background="?selectableItemBackground"
|
||||
android:drawableStart="@drawable/ic_history"
|
||||
android:drawablePadding="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?listPreferredItemPaddingStart"
|
||||
@@ -13,4 +13,7 @@
|
||||
android:textAppearance="?textAppearanceListItemSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:theme="@style/AppPopupTheme"
|
||||
tools:text="@tools:sample/full_names" />
|
||||
tools:text="@tools:sample/full_names"
|
||||
app:drawableStartCompat="@drawable/ic_history"
|
||||
android:paddingLeft="?listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?listPreferredItemPaddingRight" />
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:listPreferredItemHeightSmall"
|
||||
@@ -14,7 +15,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="?listPreferredItemPaddingStart"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_reorder_handle" />
|
||||
app:srcCompat="@drawable/ic_reorder_handle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
@@ -44,6 +45,6 @@
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:padding="?listPreferredItemPaddingEnd"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_settings" />
|
||||
app:srcCompat="@drawable/ic_settings" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -9,7 +9,9 @@
|
||||
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?selectableItemBackground"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="?listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?listPreferredItemPaddingRight">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_title"
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="92dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_launcher_foreground"
|
||||
app:srcCompat="@drawable/ic_launcher_foreground"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true" />
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentLeft="true" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
@@ -17,6 +19,8 @@
|
||||
android:background="?android:listDivider"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true" />
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -2,7 +2,7 @@
|
||||
<appwidget-provider
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/widget_recent"
|
||||
android:minWidth="40dp"
|
||||
android:minWidth="110dp"
|
||||
android:minHeight="110dp"
|
||||
android:minResizeWidth="40dp"
|
||||
android:minResizeHeight="40dp"
|
||||
|
||||
Reference in New Issue
Block a user