mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-06-17 04:49:20 +00:00
Reformated all the code
This commit is contained in:
@ -12,220 +12,264 @@ import com.looker.droidify.R
|
||||
import com.looker.droidify.entity.Release
|
||||
import com.looker.droidify.utility.KParcelable
|
||||
import com.looker.droidify.utility.PackageItemResolver
|
||||
import com.looker.droidify.utility.extension.android.*
|
||||
import com.looker.droidify.utility.extension.text.*
|
||||
import com.looker.droidify.utility.extension.android.Android
|
||||
import com.looker.droidify.utility.extension.text.nullIfEmpty
|
||||
|
||||
class MessageDialog(): DialogFragment() {
|
||||
companion object {
|
||||
private const val EXTRA_MESSAGE = "message"
|
||||
}
|
||||
|
||||
sealed class Message: KParcelable {
|
||||
object DeleteRepositoryConfirm: Message() {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator { DeleteRepositoryConfirm }
|
||||
class MessageDialog() : DialogFragment() {
|
||||
companion object {
|
||||
private const val EXTRA_MESSAGE = "message"
|
||||
}
|
||||
|
||||
object CantEditSyncing: Message() {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator { CantEditSyncing }
|
||||
}
|
||||
|
||||
class Link(val uri: Uri): Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeString(uri.toString())
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator {
|
||||
val uri = Uri.parse(it.readString()!!)
|
||||
Link(uri)
|
||||
sealed class Message : KParcelable {
|
||||
object DeleteRepositoryConfirm : Message() {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator { DeleteRepositoryConfirm }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Permissions(val group: String?, val permissions: List<String>): Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeString(group)
|
||||
dest.writeStringList(permissions)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator {
|
||||
val group = it.readString()
|
||||
val permissions = it.createStringArrayList()!!
|
||||
Permissions(group, permissions)
|
||||
object CantEditSyncing : Message() {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator { CantEditSyncing }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ReleaseIncompatible(val incompatibilities: List<Release.Incompatibility>,
|
||||
val platforms: List<String>, val minSdkVersion: Int, val maxSdkVersion: Int): Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeInt(incompatibilities.size)
|
||||
for (incompatibility in incompatibilities) {
|
||||
when (incompatibility) {
|
||||
is Release.Incompatibility.MinSdk -> {
|
||||
dest.writeInt(0)
|
||||
class Link(val uri: Uri) : Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeString(uri.toString())
|
||||
}
|
||||
is Release.Incompatibility.MaxSdk -> {
|
||||
dest.writeInt(1)
|
||||
}
|
||||
is Release.Incompatibility.Platform -> {
|
||||
dest.writeInt(2)
|
||||
}
|
||||
is Release.Incompatibility.Feature -> {
|
||||
dest.writeInt(3)
|
||||
dest.writeString(incompatibility.feature)
|
||||
}
|
||||
}::class
|
||||
}
|
||||
dest.writeStringList(platforms)
|
||||
dest.writeInt(minSdkVersion)
|
||||
dest.writeInt(maxSdkVersion)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator {
|
||||
val count = it.readInt()
|
||||
val incompatibilities = generateSequence {
|
||||
when (it.readInt()) {
|
||||
0 -> Release.Incompatibility.MinSdk
|
||||
1 -> Release.Incompatibility.MaxSdk
|
||||
2 -> Release.Incompatibility.Platform
|
||||
3 -> Release.Incompatibility.Feature(it.readString()!!)
|
||||
else -> throw RuntimeException()
|
||||
companion object {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator {
|
||||
val uri = Uri.parse(it.readString()!!)
|
||||
Link(uri)
|
||||
}
|
||||
}
|
||||
}.take(count).toList()
|
||||
val platforms = it.createStringArrayList()!!
|
||||
val minSdkVersion = it.readInt()
|
||||
val maxSdkVersion = it.readInt()
|
||||
ReleaseIncompatible(incompatibilities, platforms, minSdkVersion, maxSdkVersion)
|
||||
}
|
||||
}
|
||||
|
||||
class Permissions(val group: String?, val permissions: List<String>) : Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeString(group)
|
||||
dest.writeStringList(permissions)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator {
|
||||
val group = it.readString()
|
||||
val permissions = it.createStringArrayList()!!
|
||||
Permissions(group, permissions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ReleaseIncompatible(
|
||||
val incompatibilities: List<Release.Incompatibility>,
|
||||
val platforms: List<String>, val minSdkVersion: Int, val maxSdkVersion: Int
|
||||
) : Message() {
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
dest.writeInt(incompatibilities.size)
|
||||
for (incompatibility in incompatibilities) {
|
||||
when (incompatibility) {
|
||||
is Release.Incompatibility.MinSdk -> {
|
||||
dest.writeInt(0)
|
||||
}
|
||||
is Release.Incompatibility.MaxSdk -> {
|
||||
dest.writeInt(1)
|
||||
}
|
||||
is Release.Incompatibility.Platform -> {
|
||||
dest.writeInt(2)
|
||||
}
|
||||
is Release.Incompatibility.Feature -> {
|
||||
dest.writeInt(3)
|
||||
dest.writeString(incompatibility.feature)
|
||||
}
|
||||
}::class
|
||||
}
|
||||
dest.writeStringList(platforms)
|
||||
dest.writeInt(minSdkVersion)
|
||||
dest.writeInt(maxSdkVersion)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator {
|
||||
val count = it.readInt()
|
||||
val incompatibilities = generateSequence {
|
||||
when (it.readInt()) {
|
||||
0 -> Release.Incompatibility.MinSdk
|
||||
1 -> Release.Incompatibility.MaxSdk
|
||||
2 -> Release.Incompatibility.Platform
|
||||
3 -> Release.Incompatibility.Feature(it.readString()!!)
|
||||
else -> throw RuntimeException()
|
||||
}
|
||||
}.take(count).toList()
|
||||
val platforms = it.createStringArrayList()!!
|
||||
val minSdkVersion = it.readInt()
|
||||
val maxSdkVersion = it.readInt()
|
||||
ReleaseIncompatible(incompatibilities, platforms, minSdkVersion, maxSdkVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ReleaseOlder : Message() {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator { ReleaseOlder }
|
||||
}
|
||||
|
||||
object ReleaseSignatureMismatch : Message() {
|
||||
@Suppress("unused")
|
||||
@JvmField
|
||||
val CREATOR = KParcelable.creator { ReleaseSignatureMismatch }
|
||||
}
|
||||
}
|
||||
|
||||
object ReleaseOlder: Message() {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator { ReleaseOlder }
|
||||
constructor(message: Message) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(EXTRA_MESSAGE, message)
|
||||
}
|
||||
}
|
||||
|
||||
object ReleaseSignatureMismatch: Message() {
|
||||
@Suppress("unused") @JvmField val CREATOR = KParcelable.creator { ReleaseSignatureMismatch }
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
show(fragmentManager, this::class.java.name)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(message: Message): this() {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(EXTRA_MESSAGE, message)
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): AlertDialog {
|
||||
val dialog = AlertDialog.Builder(requireContext())
|
||||
when (val message = requireArguments().getParcelable<Message>(EXTRA_MESSAGE)!!) {
|
||||
is Message.DeleteRepositoryConfirm -> {
|
||||
dialog.setTitle(R.string.confirmation)
|
||||
dialog.setMessage(R.string.delete_repository_DESC)
|
||||
dialog.setPositiveButton(R.string.delete) { _, _ -> (parentFragment as RepositoryFragment).onDeleteConfirm() }
|
||||
dialog.setNegativeButton(R.string.cancel, null)
|
||||
}
|
||||
is Message.CantEditSyncing -> {
|
||||
dialog.setTitle(R.string.action_failed)
|
||||
dialog.setMessage(R.string.cant_edit_sync_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.Link -> {
|
||||
dialog.setTitle(R.string.confirmation)
|
||||
dialog.setMessage(getString(R.string.open_DESC_FORMAT, message.uri.toString()))
|
||||
dialog.setPositiveButton(R.string.ok) { _, _ ->
|
||||
try {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, message.uri))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
dialog.setNegativeButton(R.string.cancel, null)
|
||||
}
|
||||
is Message.Permissions -> {
|
||||
val packageManager = requireContext().packageManager
|
||||
val builder = StringBuilder()
|
||||
val localCache = PackageItemResolver.LocalCache()
|
||||
val title = if (message.group != null) {
|
||||
val name = try {
|
||||
val permissionGroupInfo =
|
||||
packageManager.getPermissionGroupInfo(message.group, 0)
|
||||
PackageItemResolver.loadLabel(
|
||||
requireContext(),
|
||||
localCache,
|
||||
permissionGroupInfo
|
||||
)
|
||||
?.nullIfEmpty()?.let { if (it == message.group) null else it }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
name ?: getString(R.string.unknown)
|
||||
} else {
|
||||
getString(R.string.other)
|
||||
}
|
||||
for (permission in message.permissions) {
|
||||
val description = try {
|
||||
val permissionInfo = packageManager.getPermissionInfo(permission, 0)
|
||||
PackageItemResolver.loadDescription(
|
||||
requireContext(),
|
||||
localCache,
|
||||
permissionInfo
|
||||
)
|
||||
?.nullIfEmpty()?.let { if (it == permission) null else it }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
description?.let { builder.append(it).append("\n\n") }
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.delete(builder.length - 2, builder.length)
|
||||
} else {
|
||||
builder.append(getString(R.string.no_description_available_DESC))
|
||||
}
|
||||
dialog.setTitle(title)
|
||||
dialog.setMessage(builder)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseIncompatible -> {
|
||||
val builder = StringBuilder()
|
||||
val minSdkVersion = if (Release.Incompatibility.MinSdk in message.incompatibilities)
|
||||
message.minSdkVersion else null
|
||||
val maxSdkVersion = if (Release.Incompatibility.MaxSdk in message.incompatibilities)
|
||||
message.maxSdkVersion else null
|
||||
if (minSdkVersion != null || maxSdkVersion != null) {
|
||||
val versionMessage = minSdkVersion?.let {
|
||||
getString(
|
||||
R.string.incompatible_api_min_DESC_FORMAT,
|
||||
it
|
||||
)
|
||||
}
|
||||
?: maxSdkVersion?.let {
|
||||
getString(
|
||||
R.string.incompatible_api_max_DESC_FORMAT,
|
||||
it
|
||||
)
|
||||
}
|
||||
builder.append(
|
||||
getString(
|
||||
R.string.incompatible_api_DESC_FORMAT,
|
||||
Android.name, Android.sdk, versionMessage.orEmpty()
|
||||
)
|
||||
).append("\n\n")
|
||||
}
|
||||
if (Release.Incompatibility.Platform in message.incompatibilities) {
|
||||
builder.append(
|
||||
getString(
|
||||
R.string.incompatible_platforms_DESC_FORMAT,
|
||||
Android.primaryPlatform ?: getString(R.string.unknown),
|
||||
message.platforms.joinToString(separator = ", ")
|
||||
)
|
||||
).append("\n\n")
|
||||
}
|
||||
val features =
|
||||
message.incompatibilities.mapNotNull { it as? Release.Incompatibility.Feature }
|
||||
if (features.isNotEmpty()) {
|
||||
builder.append(getString(R.string.incompatible_features_DESC))
|
||||
for (feature in features) {
|
||||
builder.append("\n\u2022 ").append(feature.feature)
|
||||
}
|
||||
builder.append("\n\n")
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.delete(builder.length - 2, builder.length)
|
||||
}
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(builder)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseOlder -> {
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(R.string.incompatible_older_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseSignatureMismatch -> {
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(R.string.incompatible_signature_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
}::class
|
||||
return dialog.create()
|
||||
}
|
||||
}
|
||||
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
show(fragmentManager, this::class.java.name)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): AlertDialog {
|
||||
val dialog = AlertDialog.Builder(requireContext())
|
||||
when (val message = requireArguments().getParcelable<Message>(EXTRA_MESSAGE)!!) {
|
||||
is Message.DeleteRepositoryConfirm -> {
|
||||
dialog.setTitle(R.string.confirmation)
|
||||
dialog.setMessage(R.string.delete_repository_DESC)
|
||||
dialog.setPositiveButton(R.string.delete) { _, _ -> (parentFragment as RepositoryFragment).onDeleteConfirm() }
|
||||
dialog.setNegativeButton(R.string.cancel, null)
|
||||
}
|
||||
is Message.CantEditSyncing -> {
|
||||
dialog.setTitle(R.string.action_failed)
|
||||
dialog.setMessage(R.string.cant_edit_sync_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.Link -> {
|
||||
dialog.setTitle(R.string.confirmation)
|
||||
dialog.setMessage(getString(R.string.open_DESC_FORMAT, message.uri.toString()))
|
||||
dialog.setPositiveButton(R.string.ok) { _, _ ->
|
||||
try {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, message.uri))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
dialog.setNegativeButton(R.string.cancel, null)
|
||||
}
|
||||
is Message.Permissions -> {
|
||||
val packageManager = requireContext().packageManager
|
||||
val builder = StringBuilder()
|
||||
val localCache = PackageItemResolver.LocalCache()
|
||||
val title = if (message.group != null) {
|
||||
val name = try {
|
||||
val permissionGroupInfo = packageManager.getPermissionGroupInfo(message.group, 0)
|
||||
PackageItemResolver.loadLabel(requireContext(), localCache, permissionGroupInfo)
|
||||
?.nullIfEmpty()?.let { if (it == message.group) null else it }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
name ?: getString(R.string.unknown)
|
||||
} else {
|
||||
getString(R.string.other)
|
||||
}
|
||||
for (permission in message.permissions) {
|
||||
val description = try {
|
||||
val permissionInfo = packageManager.getPermissionInfo(permission, 0)
|
||||
PackageItemResolver.loadDescription(requireContext(), localCache, permissionInfo)
|
||||
?.nullIfEmpty()?.let { if (it == permission) null else it }
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
description?.let { builder.append(it).append("\n\n") }
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.delete(builder.length - 2, builder.length)
|
||||
} else {
|
||||
builder.append(getString(R.string.no_description_available_DESC))
|
||||
}
|
||||
dialog.setTitle(title)
|
||||
dialog.setMessage(builder)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseIncompatible -> {
|
||||
val builder = StringBuilder()
|
||||
val minSdkVersion = if (Release.Incompatibility.MinSdk in message.incompatibilities)
|
||||
message.minSdkVersion else null
|
||||
val maxSdkVersion = if (Release.Incompatibility.MaxSdk in message.incompatibilities)
|
||||
message.maxSdkVersion else null
|
||||
if (minSdkVersion != null || maxSdkVersion != null) {
|
||||
val versionMessage = minSdkVersion?.let { getString(R.string.incompatible_api_min_DESC_FORMAT, it) }
|
||||
?: maxSdkVersion?.let { getString(R.string.incompatible_api_max_DESC_FORMAT, it) }
|
||||
builder.append(getString(R.string.incompatible_api_DESC_FORMAT,
|
||||
Android.name, Android.sdk, versionMessage.orEmpty())).append("\n\n")
|
||||
}
|
||||
if (Release.Incompatibility.Platform in message.incompatibilities) {
|
||||
builder.append(getString(R.string.incompatible_platforms_DESC_FORMAT,
|
||||
Android.primaryPlatform ?: getString(R.string.unknown),
|
||||
message.platforms.joinToString(separator = ", "))).append("\n\n")
|
||||
}
|
||||
val features = message.incompatibilities.mapNotNull { it as? Release.Incompatibility.Feature }
|
||||
if (features.isNotEmpty()) {
|
||||
builder.append(getString(R.string.incompatible_features_DESC))
|
||||
for (feature in features) {
|
||||
builder.append("\n\u2022 ").append(feature.feature)
|
||||
}
|
||||
builder.append("\n\n")
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.delete(builder.length - 2, builder.length)
|
||||
}
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(builder)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseOlder -> {
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(R.string.incompatible_older_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
is Message.ReleaseSignatureMismatch -> {
|
||||
dialog.setTitle(R.string.incompatible_version)
|
||||
dialog.setMessage(R.string.incompatible_signature_DESC)
|
||||
dialog.setPositiveButton(R.string.ok, null)
|
||||
}
|
||||
}::class
|
||||
return dialog.create()
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package com.looker.droidify.screen
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
open class ScreenFragment: Fragment() {
|
||||
val screenActivity: ScreenActivity
|
||||
get() = requireActivity() as ScreenActivity
|
||||
open class ScreenFragment : Fragment() {
|
||||
val screenActivity: ScreenActivity
|
||||
get() = requireActivity() as ScreenActivity
|
||||
|
||||
open fun onBackPressed(): Boolean = false
|
||||
open fun onBackPressed(): Boolean = false
|
||||
}
|
||||
|
@ -15,10 +15,6 @@ import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.MarginPageTransformer
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import com.looker.droidify.R
|
||||
import com.looker.droidify.database.Database
|
||||
import com.looker.droidify.entity.Product
|
||||
@ -26,208 +22,245 @@ import com.looker.droidify.entity.Repository
|
||||
import com.looker.droidify.graphics.PaddingDrawable
|
||||
import com.looker.droidify.network.PicassoDownloader
|
||||
import com.looker.droidify.utility.RxUtils
|
||||
import com.looker.droidify.utility.extension.android.*
|
||||
import com.looker.droidify.utility.extension.android.Android
|
||||
import com.looker.droidify.utility.extension.resources.*
|
||||
import com.looker.droidify.widget.StableRecyclerAdapter
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
|
||||
class ScreenshotsFragment(): DialogFragment() {
|
||||
companion object {
|
||||
private const val EXTRA_PACKAGE_NAME = "packageName"
|
||||
private const val EXTRA_REPOSITORY_ID = "repositoryId"
|
||||
private const val EXTRA_IDENTIFIER = "identifier"
|
||||
class ScreenshotsFragment() : DialogFragment() {
|
||||
companion object {
|
||||
private const val EXTRA_PACKAGE_NAME = "packageName"
|
||||
private const val EXTRA_REPOSITORY_ID = "repositoryId"
|
||||
private const val EXTRA_IDENTIFIER = "identifier"
|
||||
|
||||
private const val STATE_IDENTIFIER = "identifier"
|
||||
}
|
||||
|
||||
constructor(packageName: String, repositoryId: Long, identifier: String): this() {
|
||||
arguments = Bundle().apply {
|
||||
putString(EXTRA_PACKAGE_NAME, packageName)
|
||||
putLong(EXTRA_REPOSITORY_ID, repositoryId)
|
||||
putString(EXTRA_IDENTIFIER, identifier)
|
||||
private const val STATE_IDENTIFIER = "identifier"
|
||||
}
|
||||
}
|
||||
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
show(fragmentManager, this::class.java.name)
|
||||
}
|
||||
|
||||
private var viewPager: ViewPager2? = null
|
||||
|
||||
private var productDisposable: Disposable? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val packageName = requireArguments().getString(EXTRA_PACKAGE_NAME)!!
|
||||
val repositoryId = requireArguments().getLong(EXTRA_REPOSITORY_ID)
|
||||
val dialog = Dialog(requireContext(), R.style.Theme_Main_Dark)
|
||||
|
||||
val window = dialog.window!!
|
||||
val decorView = window.decorView
|
||||
val background = dialog.context.getColorFromAttr(android.R.attr.colorBackground).defaultColor
|
||||
decorView.setBackgroundColor(background.let { ColorUtils.blendARGB(0x00ffffff and it, it, 0.9f) })
|
||||
decorView.setPadding(0, 0, 0, 0)
|
||||
background.let { ColorUtils.blendARGB(0x00ffffff and it, it, 0.8f) }.let {
|
||||
window.statusBarColor = it
|
||||
window.navigationBarColor = it
|
||||
}
|
||||
window.attributes = window.attributes.apply {
|
||||
title = ScreenshotsFragment::class.java.name
|
||||
format = PixelFormat.TRANSLUCENT
|
||||
windowAnimations = run {
|
||||
val typedArray = dialog.context.obtainStyledAttributes(null,
|
||||
intArrayOf(android.R.attr.windowAnimationStyle), android.R.attr.dialogTheme, 0)
|
||||
try {
|
||||
typedArray.getResourceId(0, 0)
|
||||
} finally {
|
||||
typedArray.recycle()
|
||||
constructor(packageName: String, repositoryId: Long, identifier: String) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putString(EXTRA_PACKAGE_NAME, packageName)
|
||||
putLong(EXTRA_REPOSITORY_ID, repositoryId)
|
||||
putString(EXTRA_IDENTIFIER, identifier)
|
||||
}
|
||||
}
|
||||
if (Android.sdk(28)) {
|
||||
layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
}
|
||||
}
|
||||
|
||||
val hideFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
val applyHide = Runnable { decorView.systemUiVisibility = decorView.systemUiVisibility or hideFlags }
|
||||
val handleClick = {
|
||||
decorView.removeCallbacks(applyHide)
|
||||
if ((decorView.systemUiVisibility and hideFlags) == hideFlags) {
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility and hideFlags.inv()
|
||||
} else {
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility or hideFlags
|
||||
}
|
||||
fun show(fragmentManager: FragmentManager) {
|
||||
show(fragmentManager, this::class.java.name)
|
||||
}
|
||||
decorView.postDelayed(applyHide, 2000L)
|
||||
decorView.setOnClickListener { handleClick() }
|
||||
|
||||
val viewPager = ViewPager2(dialog.context)
|
||||
viewPager.adapter = Adapter(packageName) { handleClick() }
|
||||
viewPager.setPageTransformer(MarginPageTransformer(resources.sizeScaled(16)))
|
||||
viewPager.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
(viewPager.adapter as Adapter).size = Pair(viewPager.width, viewPager.height)
|
||||
}
|
||||
dialog.addContentView(viewPager, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT))
|
||||
this.viewPager = viewPager
|
||||
private var viewPager: ViewPager2? = null
|
||||
|
||||
var restored = false
|
||||
productDisposable = Observable.just(Unit)
|
||||
.concatWith(Database.observable(Database.Subject.Products))
|
||||
.observeOn(Schedulers.io())
|
||||
.flatMapSingle { RxUtils.querySingle { Database.ProductAdapter.get(packageName, it) } }
|
||||
.map { Pair(it.find { it.repositoryId == repositoryId }, Database.RepositoryAdapter.get(repositoryId)) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
val (product, repository) = it
|
||||
val screenshots = product?.screenshots.orEmpty()
|
||||
(viewPager.adapter as Adapter).update(repository, screenshots)
|
||||
if (!restored) {
|
||||
restored = true
|
||||
val identifier = savedInstanceState?.getString(STATE_IDENTIFIER)
|
||||
?: requireArguments().getString(STATE_IDENTIFIER)
|
||||
if (identifier != null) {
|
||||
val index = screenshots.indexOfFirst { it.identifier == identifier }
|
||||
if (index >= 0) {
|
||||
viewPager.setCurrentItem(index, false)
|
||||
private var productDisposable: Disposable? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val packageName = requireArguments().getString(EXTRA_PACKAGE_NAME)!!
|
||||
val repositoryId = requireArguments().getLong(EXTRA_REPOSITORY_ID)
|
||||
val dialog = Dialog(requireContext(), R.style.Theme_Main_Dark)
|
||||
|
||||
val window = dialog.window!!
|
||||
val decorView = window.decorView
|
||||
val background =
|
||||
dialog.context.getColorFromAttr(android.R.attr.colorBackground).defaultColor
|
||||
decorView.setBackgroundColor(background.let {
|
||||
ColorUtils.blendARGB(
|
||||
0x00ffffff and it,
|
||||
it,
|
||||
0.9f
|
||||
)
|
||||
})
|
||||
decorView.setPadding(0, 0, 0, 0)
|
||||
background.let { ColorUtils.blendARGB(0x00ffffff and it, it, 0.8f) }.let {
|
||||
window.statusBarColor = it
|
||||
window.navigationBarColor = it
|
||||
}
|
||||
window.attributes = window.attributes.apply {
|
||||
title = ScreenshotsFragment::class.java.name
|
||||
format = PixelFormat.TRANSLUCENT
|
||||
windowAnimations = run {
|
||||
val typedArray = dialog.context.obtainStyledAttributes(
|
||||
null,
|
||||
intArrayOf(android.R.attr.windowAnimationStyle), android.R.attr.dialogTheme, 0
|
||||
)
|
||||
try {
|
||||
typedArray.getResourceId(0, 0)
|
||||
} finally {
|
||||
typedArray.recycle()
|
||||
}
|
||||
}
|
||||
if (Android.sdk(28)) {
|
||||
layoutInDisplayCutoutMode =
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
||||
viewPager = null
|
||||
|
||||
productDisposable?.dispose()
|
||||
productDisposable = null
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
val viewPager = viewPager
|
||||
if (viewPager != null) {
|
||||
val identifier = (viewPager.adapter as Adapter).getCurrentIdentifier(viewPager)
|
||||
identifier?.let { outState.putString(STATE_IDENTIFIER, it) }
|
||||
}
|
||||
}
|
||||
|
||||
private class Adapter(private val packageName: String, private val onClick: () -> Unit):
|
||||
StableRecyclerAdapter<Adapter.ViewType, RecyclerView.ViewHolder>() {
|
||||
enum class ViewType { SCREENSHOT }
|
||||
|
||||
private class ViewHolder(context: Context): RecyclerView.ViewHolder(ImageView(context)) {
|
||||
val image: ImageView
|
||||
get() = itemView as ImageView
|
||||
|
||||
val placeholder: Drawable
|
||||
|
||||
init {
|
||||
itemView.layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,
|
||||
RecyclerView.LayoutParams.MATCH_PARENT)
|
||||
|
||||
val placeholder = itemView.context.getDrawableCompat(R.drawable.ic_photo_camera).mutate()
|
||||
placeholder.setTint(itemView.context.getColorFromAttr(android.R.attr.textColorPrimary).defaultColor
|
||||
.let { ColorUtils.blendARGB(0x00ffffff and it, it, 0.25f) })
|
||||
this.placeholder = PaddingDrawable(placeholder, 4f)
|
||||
}
|
||||
}
|
||||
|
||||
private var repository: Repository? = null
|
||||
private var screenshots = emptyList<Product.Screenshot>()
|
||||
|
||||
fun update(repository: Repository?, screenshots: List<Product.Screenshot>) {
|
||||
this.repository = repository
|
||||
this.screenshots = screenshots
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
var size = Pair(0, 0)
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
val hideFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||
decorView.systemUiVisibility =
|
||||
decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
val applyHide =
|
||||
Runnable { decorView.systemUiVisibility = decorView.systemUiVisibility or hideFlags }
|
||||
val handleClick = {
|
||||
decorView.removeCallbacks(applyHide)
|
||||
if ((decorView.systemUiVisibility and hideFlags) == hideFlags) {
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility and hideFlags.inv()
|
||||
} else {
|
||||
decorView.systemUiVisibility = decorView.systemUiVisibility or hideFlags
|
||||
}
|
||||
}
|
||||
}
|
||||
decorView.postDelayed(applyHide, 2000L)
|
||||
decorView.setOnClickListener { handleClick() }
|
||||
|
||||
fun getCurrentIdentifier(viewPager: ViewPager2): String? {
|
||||
val position = viewPager.currentItem
|
||||
return screenshots.getOrNull(position)?.identifier
|
||||
}
|
||||
|
||||
override val viewTypeClass: Class<ViewType>
|
||||
get() = ViewType::class.java
|
||||
|
||||
override fun getItemCount(): Int = screenshots.size
|
||||
override fun getItemDescriptor(position: Int): String = screenshots[position].identifier
|
||||
override fun getItemEnumViewType(position: Int): ViewType = ViewType.SCREENSHOT
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: ViewType): RecyclerView.ViewHolder {
|
||||
return ViewHolder(parent.context).apply {
|
||||
itemView.setOnClickListener { onClick() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
holder as ViewHolder
|
||||
val screenshot = screenshots[position]
|
||||
val (width, height) = size
|
||||
if (width > 0 && height > 0) {
|
||||
holder.image.load(PicassoDownloader.createScreenshotUri(repository!!, packageName, screenshot)) {
|
||||
placeholder(holder.placeholder)
|
||||
error(holder.placeholder)
|
||||
resize(width, height)
|
||||
centerInside()
|
||||
val viewPager = ViewPager2(dialog.context)
|
||||
viewPager.adapter = Adapter(packageName) { handleClick() }
|
||||
viewPager.setPageTransformer(MarginPageTransformer(resources.sizeScaled(16)))
|
||||
viewPager.viewTreeObserver.addOnGlobalLayoutListener {
|
||||
(viewPager.adapter as Adapter).size = Pair(viewPager.width, viewPager.height)
|
||||
}
|
||||
dialog.addContentView(
|
||||
viewPager, ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
)
|
||||
this.viewPager = viewPager
|
||||
|
||||
var restored = false
|
||||
productDisposable = Observable.just(Unit)
|
||||
.concatWith(Database.observable(Database.Subject.Products))
|
||||
.observeOn(Schedulers.io())
|
||||
.flatMapSingle { RxUtils.querySingle { Database.ProductAdapter.get(packageName, it) } }
|
||||
.map { it ->
|
||||
Pair(
|
||||
it.find { it.repositoryId == repositoryId },
|
||||
Database.RepositoryAdapter.get(repositoryId)
|
||||
)
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { it ->
|
||||
val (product, repository) = it
|
||||
val screenshots = product?.screenshots.orEmpty()
|
||||
(viewPager.adapter as Adapter).update(repository, screenshots)
|
||||
if (!restored) {
|
||||
restored = true
|
||||
val identifier = savedInstanceState?.getString(STATE_IDENTIFIER)
|
||||
?: requireArguments().getString(STATE_IDENTIFIER)
|
||||
if (identifier != null) {
|
||||
val index = screenshots.indexOfFirst { it.identifier == identifier }
|
||||
if (index >= 0) {
|
||||
viewPager.setCurrentItem(index, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
||||
viewPager = null
|
||||
|
||||
productDisposable?.dispose()
|
||||
productDisposable = null
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
val viewPager = viewPager
|
||||
if (viewPager != null) {
|
||||
val identifier = (viewPager.adapter as Adapter).getCurrentIdentifier(viewPager)
|
||||
identifier?.let { outState.putString(STATE_IDENTIFIER, it) }
|
||||
}
|
||||
}
|
||||
|
||||
private class Adapter(private val packageName: String, private val onClick: () -> Unit) :
|
||||
StableRecyclerAdapter<Adapter.ViewType, RecyclerView.ViewHolder>() {
|
||||
enum class ViewType { SCREENSHOT }
|
||||
|
||||
private class ViewHolder(context: Context) : RecyclerView.ViewHolder(ImageView(context)) {
|
||||
val image: ImageView
|
||||
get() = itemView as ImageView
|
||||
|
||||
val placeholder: Drawable
|
||||
|
||||
init {
|
||||
itemView.layoutParams = RecyclerView.LayoutParams(
|
||||
RecyclerView.LayoutParams.MATCH_PARENT,
|
||||
RecyclerView.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
val placeholder =
|
||||
itemView.context.getDrawableCompat(R.drawable.ic_photo_camera).mutate()
|
||||
placeholder.setTint(itemView.context.getColorFromAttr(android.R.attr.textColorPrimary).defaultColor
|
||||
.let { ColorUtils.blendARGB(0x00ffffff and it, it, 0.25f) })
|
||||
this.placeholder = PaddingDrawable(placeholder, 4f)
|
||||
}
|
||||
}
|
||||
|
||||
private var repository: Repository? = null
|
||||
private var screenshots = emptyList<Product.Screenshot>()
|
||||
|
||||
fun update(repository: Repository?, screenshots: List<Product.Screenshot>) {
|
||||
this.repository = repository
|
||||
this.screenshots = screenshots
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
var size = Pair(0, 0)
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun getCurrentIdentifier(viewPager: ViewPager2): String? {
|
||||
val position = viewPager.currentItem
|
||||
return screenshots.getOrNull(position)?.identifier
|
||||
}
|
||||
|
||||
override val viewTypeClass: Class<ViewType>
|
||||
get() = ViewType::class.java
|
||||
|
||||
override fun getItemCount(): Int = screenshots.size
|
||||
override fun getItemDescriptor(position: Int): String = screenshots[position].identifier
|
||||
override fun getItemEnumViewType(position: Int): ViewType = ViewType.SCREENSHOT
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: ViewType
|
||||
): RecyclerView.ViewHolder {
|
||||
return ViewHolder(parent.context).apply {
|
||||
itemView.setOnClickListener { onClick() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
holder as ViewHolder
|
||||
val screenshot = screenshots[position]
|
||||
val (width, height) = size
|
||||
if (width > 0 && height > 0) {
|
||||
holder.image.load(
|
||||
PicassoDownloader.createScreenshotUri(
|
||||
repository!!,
|
||||
packageName,
|
||||
screenshot
|
||||
)
|
||||
) {
|
||||
placeholder(holder.placeholder)
|
||||
error(holder.placeholder)
|
||||
resize(width, height)
|
||||
centerInside()
|
||||
}
|
||||
} else {
|
||||
holder.image.clear()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
holder.image.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user