Refactor objects to classes
This commit is contained in:
@@ -8,7 +8,7 @@ import android.view.ViewGroup
|
|||||||
import androidx.appcompat.app.AppCompatDialog
|
import androidx.appcompat.app.AppCompatDialog
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import org.koitharu.kotatsu.utils.UiUtils
|
import org.koitharu.kotatsu.R
|
||||||
|
|
||||||
abstract class BaseBottomSheet<B : ViewBinding> :
|
abstract class BaseBottomSheet<B : ViewBinding> :
|
||||||
BottomSheetDialogFragment() {
|
BottomSheetDialogFragment() {
|
||||||
@@ -34,7 +34,7 @@ abstract class BaseBottomSheet<B : ViewBinding> :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
return if (UiUtils.isTablet(requireContext())) {
|
return if (resources.getBoolean(R.bool.is_tablet)) {
|
||||||
AppCompatDialog(context, theme)
|
AppCompatDialog(context, theme)
|
||||||
} else super.onCreateDialog(savedInstanceState)
|
} else super.onCreateDialog(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class CrashActivity : Activity(), View.OnClickListener {
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.action_share -> {
|
R.id.action_share -> {
|
||||||
ShareHelper.shareText(this, binding.textView.text.toString() ?: return false)
|
ShareHelper(this).shareText(binding.textView.text.toString())
|
||||||
}
|
}
|
||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,9 +127,9 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
|||||||
R.id.action_share -> {
|
R.id.action_share -> {
|
||||||
viewModel.manga.value?.let {
|
viewModel.manga.value?.let {
|
||||||
if (it.source == MangaSource.LOCAL) {
|
if (it.source == MangaSource.LOCAL) {
|
||||||
ShareHelper.shareCbz(this, Uri.parse(it.url).toFile())
|
ShareHelper(this).shareCbz(Uri.parse(it.url).toFile())
|
||||||
} else {
|
} else {
|
||||||
ShareHelper.shareMangaLink(this, it)
|
ShareHelper(this).shareMangaLink(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ class LocalListViewModel(
|
|||||||
fun importFile(uri: Uri) {
|
fun importFile(uri: Uri) {
|
||||||
launchLoadingJob {
|
launchLoadingJob {
|
||||||
val contentResolver = context.contentResolver
|
val contentResolver = context.contentResolver
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.IO) {
|
||||||
val name = MediaStoreCompat.getName(contentResolver, uri)
|
val name = MediaStoreCompat(contentResolver).getName(uri)
|
||||||
?: throw IOException("Cannot fetch name from uri: $uri")
|
?: throw IOException("Cannot fetch name from uri: $uri")
|
||||||
if (!LocalMangaRepository.isFileSupported(name)) {
|
if (!LocalMangaRepository.isFileSupported(name)) {
|
||||||
throw UnsupportedFileException("Unsupported file on $uri")
|
throw UnsupportedFileException("Unsupported file on $uri")
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ class PageLoader(
|
|||||||
private val tasks = ArrayMap<String, Deferred<File>>()
|
private val tasks = ArrayMap<String, Deferred<File>>()
|
||||||
private val convertLock = Mutex()
|
private val convertLock = Mutex()
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
|
||||||
suspend fun loadFile(url: String, force: Boolean): File {
|
suspend fun loadFile(url: String, force: Boolean): File {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
cache[url]?.let {
|
cache[url]?.let {
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
|||||||
Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_LONG)
|
Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_LONG)
|
||||||
.setAnchorView(binding.appbarBottom)
|
.setAnchorView(binding.appbarBottom)
|
||||||
.setAction(R.string.share) {
|
.setAction(R.string.share) {
|
||||||
ShareHelper.shareImage(this, uri)
|
ShareHelper(this).shareImage(uri)
|
||||||
}.show()
|
}.show()
|
||||||
} else {
|
} else {
|
||||||
Snackbar.make(binding.container, R.string.error_occurred, Snackbar.LENGTH_SHORT)
|
Snackbar.make(binding.container, R.string.error_occurred, Snackbar.LENGTH_SHORT)
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class ReaderViewModel(
|
|||||||
response.contentDisposition,
|
response.contentDisposition,
|
||||||
response.mimeType
|
response.mimeType
|
||||||
)
|
)
|
||||||
MediaStoreCompat.insertImage(resolver, fileName) {
|
MediaStoreCompat(resolver).insertImage(fileName) {
|
||||||
checkNotNull(response.body).byteStream().copyTo(it)
|
checkNotNull(response.body).byteStream().copyTo(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class BackupDialogFragment : AlertDialogFragment<DialogProgressBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onBackupDone(file: File) {
|
private fun onBackupDone(file: File) {
|
||||||
ShareHelper.shareBackup(context ?: return, file)
|
ShareHelper(context ?: return).shareBackup(file)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,9 @@ import androidx.core.database.getStringOrNull
|
|||||||
import org.koitharu.kotatsu.BuildConfig
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
|
|
||||||
object MediaStoreCompat {
|
class MediaStoreCompat(private val contentResolver: ContentResolver) {
|
||||||
|
|
||||||
fun insertImage(
|
fun insertImage(
|
||||||
resolver: ContentResolver,
|
|
||||||
fileName: String,
|
fileName: String,
|
||||||
block: (OutputStream) -> Unit
|
block: (OutputStream) -> Unit
|
||||||
): Uri? {
|
): Uri? {
|
||||||
@@ -34,26 +33,26 @@ object MediaStoreCompat {
|
|||||||
}
|
}
|
||||||
var uri: Uri? = null
|
var uri: Uri? = null
|
||||||
try {
|
try {
|
||||||
uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cv)
|
uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cv)
|
||||||
resolver.openOutputStream(uri!!)?.use(block)
|
contentResolver.openOutputStream(uri!!)?.use(block)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
cv.clear()
|
cv.clear()
|
||||||
cv.put(MediaStore.Images.Media.IS_PENDING, 0)
|
cv.put(MediaStore.Images.Media.IS_PENDING, 0)
|
||||||
resolver.update(uri, cv, null, null)
|
contentResolver.update(uri, cv, null, null)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
uri?.let {
|
uri?.let {
|
||||||
resolver.delete(it, null, null)
|
contentResolver.delete(it, null, null)
|
||||||
}
|
}
|
||||||
uri = null
|
uri = null
|
||||||
}
|
}
|
||||||
return uri
|
return uri
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getName(contentResolver: ContentResolver, uri: Uri): String? =
|
fun getName(uri: Uri): String? =
|
||||||
(if (uri.scheme == "content") {
|
(if (uri.scheme == "content") {
|
||||||
contentResolver.query(uri, null, null, null, null)?.use {
|
contentResolver.query(uri, null, null, null, null)?.use {
|
||||||
if (it.moveToFirst()) {
|
if (it.moveToFirst()) {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.model.Manga
|
import org.koitharu.kotatsu.core.model.Manga
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object ShareHelper {
|
class ShareHelper(private val context: Context) {
|
||||||
|
|
||||||
fun shareMangaLink(context: Context, manga: Manga) {
|
fun shareMangaLink(manga: Manga) {
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
intent.type = "text/plain"
|
intent.type = "text/plain"
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, buildString {
|
intent.putExtra(Intent.EXTRA_TEXT, buildString {
|
||||||
@@ -24,7 +24,7 @@ object ShareHelper {
|
|||||||
context.startActivity(shareIntent)
|
context.startActivity(shareIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareCbz(context: Context, file: File) {
|
fun shareCbz(file: File) {
|
||||||
val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", file)
|
val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", file)
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
||||||
@@ -34,7 +34,7 @@ object ShareHelper {
|
|||||||
context.startActivity(shareIntent)
|
context.startActivity(shareIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareBackup(context: Context, file: File) {
|
fun shareBackup(file: File) {
|
||||||
val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", file)
|
val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", file)
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
||||||
@@ -44,7 +44,7 @@ object ShareHelper {
|
|||||||
context.startActivity(shareIntent)
|
context.startActivity(shareIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareImage(context: Context, uri: Uri) {
|
fun shareImage(uri: Uri) {
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
intent.setDataAndType(uri, context.contentResolver.getType(uri))
|
||||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
@@ -52,7 +52,7 @@ object ShareHelper {
|
|||||||
context.startActivity(shareIntent)
|
context.startActivity(shareIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shareText(context: Context, text: String) {
|
fun shareText(text: String) {
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
intent.type = "text/plain"
|
intent.type = "text/plain"
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, text)
|
intent.putExtra(Intent.EXTRA_TEXT, text)
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.utils
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.View
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import org.koin.core.component.KoinComponent
|
|
||||||
import org.koin.core.component.get
|
|
||||||
import org.koitharu.kotatsu.R
|
|
||||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
|
||||||
import org.koitharu.kotatsu.utils.ext.measureWidth
|
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
object UiUtils : KoinComponent {
|
|
||||||
|
|
||||||
fun resolveGridSpanCount(context: Context, width: Int = 0): Int {
|
|
||||||
val scaleFactor = get<AppSettings>().gridSize / 100f
|
|
||||||
val cellWidth = context.resources.getDimension(R.dimen.preferred_grid_width) * scaleFactor
|
|
||||||
val screenWidth = (if (width <= 0) {
|
|
||||||
context.resources.displayMetrics.widthPixels
|
|
||||||
} else width).toDouble()
|
|
||||||
val estimatedCount = (screenWidth / cellWidth).roundToInt()
|
|
||||||
return estimatedCount.coerceAtLeast(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isTablet(context: Context) = context.resources.getBoolean(R.bool.is_tablet)
|
|
||||||
|
|
||||||
@Deprecated("Use MangaListSpanResolver")
|
|
||||||
object SpanCountResolver : View.OnLayoutChangeListener {
|
|
||||||
override fun onLayoutChange(
|
|
||||||
v: View?, left: Int, top: Int, right: Int, bottom: Int,
|
|
||||||
oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int
|
|
||||||
) {
|
|
||||||
val rv = v as? RecyclerView ?: return
|
|
||||||
val width = abs(right - left)
|
|
||||||
if (width == 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(rv.layoutManager as? GridLayoutManager)?.spanCount =
|
|
||||||
resolveGridSpanCount(rv.context, width)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(rv: RecyclerView) {
|
|
||||||
val width = rv.measureWidth()
|
|
||||||
if (width > 0) {
|
|
||||||
(rv.layoutManager as? GridLayoutManager)?.spanCount =
|
|
||||||
resolveGridSpanCount(rv.context, width)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,4 +16,7 @@ data class Progress(
|
|||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isIndeterminate: Boolean
|
||||||
|
get() = total <= 0
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user