mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-06-09 09:19:55 +00:00
Add: Long Press on Source Icon to copy link
Fix: Installer Spamming coroutines Remove: Unused Variables and methods/functions
This commit is contained in:
parent
229a7a3c09
commit
acc5d78664
@ -2,8 +2,6 @@ package com.looker.droidify.installer
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.looker.droidify.utility.Utils.rootInstallerEnabled
|
import com.looker.droidify.utility.Utils.rootInstallerEnabled
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
abstract class AppInstaller {
|
abstract class AppInstaller {
|
||||||
abstract val defaultInstaller: BaseInstaller?
|
abstract val defaultInstaller: BaseInstaller?
|
||||||
@ -11,21 +9,19 @@ abstract class AppInstaller {
|
|||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var INSTANCE: AppInstaller? = null
|
private var INSTANCE: AppInstaller? = null
|
||||||
suspend fun getInstance(context: Context?): AppInstaller? {
|
fun getInstance(context: Context?): AppInstaller? {
|
||||||
if (INSTANCE == null) {
|
if (INSTANCE == null) {
|
||||||
withContext(Dispatchers.IO) {
|
synchronized(AppInstaller::class.java) {
|
||||||
synchronized(AppInstaller::class.java) {
|
if (INSTANCE == null) {
|
||||||
if (INSTANCE == null) {
|
context?.let {
|
||||||
context?.let {
|
INSTANCE = object : AppInstaller() {
|
||||||
INSTANCE = object : AppInstaller() {
|
override val defaultInstaller: BaseInstaller
|
||||||
override val defaultInstaller: BaseInstaller
|
get() {
|
||||||
get() {
|
return when (rootInstallerEnabled) {
|
||||||
return when (rootInstallerEnabled) {
|
false -> DefaultInstaller(it)
|
||||||
false -> DefaultInstaller(it)
|
true -> RootInstaller(it)
|
||||||
true -> RootInstaller(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ abstract class BaseInstaller(val context: Context) : InstallationEvents {
|
|||||||
companion object {
|
companion object {
|
||||||
const val ROOT_INSTALL_PACKAGE = "cat %s | pm install --user %s -t -r -S %s"
|
const val ROOT_INSTALL_PACKAGE = "cat %s | pm install --user %s -t -r -S %s"
|
||||||
const val ROOT_UNINSTALL_PACKAGE = "pm uninstall --user %s %s"
|
const val ROOT_UNINSTALL_PACKAGE = "pm uninstall --user %s %s"
|
||||||
|
const val DELETE_PACKAGE = "%s rm %s"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
|
@ -26,7 +26,7 @@ class RootInstaller(context: Context) : BaseInstaller(context) {
|
|||||||
scope.launch { mRootUninstaller(packageName) }
|
scope.launch { mRootUninstaller(packageName) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun mRootInstaller(cacheFile: File) {
|
private fun mRootInstaller(cacheFile: File) {
|
||||||
if (rootInstallerEnabled) {
|
if (rootInstallerEnabled) {
|
||||||
val installCommand =
|
val installCommand =
|
||||||
String.format(
|
String.format(
|
||||||
@ -35,15 +35,16 @@ class RootInstaller(context: Context) : BaseInstaller(context) {
|
|||||||
getCurrentUserState,
|
getCurrentUserState,
|
||||||
cacheFile.length()
|
cacheFile.length()
|
||||||
)
|
)
|
||||||
Log.e("Install", installCommand)
|
val deleteCommand =
|
||||||
withContext(Dispatchers.IO) {
|
String.format(
|
||||||
launch {
|
DELETE_PACKAGE,
|
||||||
val result = Shell.su(installCommand).exec()
|
getUtilBoxPath,
|
||||||
launch {
|
cacheFile.absolutePath.quote
|
||||||
if (result.isSuccess) {
|
)
|
||||||
Shell.su("$getUtilBoxPath rm ${cacheFile.absolutePath.quote}")
|
scope.launch {
|
||||||
.submit()
|
Shell.su(installCommand).submit {
|
||||||
}
|
if (it.isSuccess) {
|
||||||
|
Shell.su(deleteCommand).submit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1151,7 +1151,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
|||||||
ViewType.HEADER -> {
|
ViewType.HEADER -> {
|
||||||
holder as HeaderViewHolder
|
holder as HeaderViewHolder
|
||||||
item as Item.HeaderItem
|
item as Item.HeaderItem
|
||||||
val installedItem = installedItem
|
|
||||||
val updateStatus = Payload.STATUS in payloads
|
val updateStatus = Payload.STATUS in payloads
|
||||||
val updateAll = !updateStatus
|
val updateAll = !updateStatus
|
||||||
if (updateAll) {
|
if (updateAll) {
|
||||||
@ -1170,8 +1169,6 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
|||||||
holder.icon.setImageDrawable(holder.defaultIcon)
|
holder.icon.setImageDrawable(holder.defaultIcon)
|
||||||
}
|
}
|
||||||
holder.name.text = item.product.name
|
holder.name.text = item.product.name
|
||||||
val canUpdate = item.product.canUpdate(installedItem) &&
|
|
||||||
!ProductPreferences[item.product.packageName].shouldIgnoreUpdate(item.product.versionCode)
|
|
||||||
holder.packageName.apply {
|
holder.packageName.apply {
|
||||||
text = item.product.packageName
|
text = item.product.packageName
|
||||||
setTextSizeScaled(15)
|
setTextSizeScaled(15)
|
||||||
@ -1264,6 +1261,10 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
|||||||
holder.dev.setOnClickListener {
|
holder.dev.setOnClickListener {
|
||||||
context.startActivity(Intent(Intent.ACTION_VIEW, product?.source?.toUri()))
|
context.startActivity(Intent(Intent.ACTION_VIEW, product?.source?.toUri()))
|
||||||
}
|
}
|
||||||
|
holder.dev.setOnLongClickListener {
|
||||||
|
product?.source?.let { copyLinkToClipboard(context, it) }
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ViewType.SWITCH -> {
|
ViewType.SWITCH -> {
|
||||||
holder as SwitchViewHolder
|
holder as SwitchViewHolder
|
||||||
|
@ -16,7 +16,6 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.looker.droidify.R
|
import com.looker.droidify.R
|
||||||
import com.looker.droidify.content.ProductPreferences
|
import com.looker.droidify.content.ProductPreferences
|
||||||
@ -329,7 +328,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
|||||||
(it.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() != 0
|
(it.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() != 0
|
||||||
} == true
|
} == true
|
||||||
|
|
||||||
(toolbar.parent as CollapsingToolbarLayout).title =
|
collapsingToolbar.title =
|
||||||
if (showPackageName) products[0].first.name.trimAfter(' ', 2)
|
if (showPackageName) products[0].first.name.trimAfter(' ', 2)
|
||||||
else getString(R.string.application)
|
else getString(R.string.application)
|
||||||
}
|
}
|
||||||
@ -372,12 +371,12 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
|
|||||||
if (state is DownloadService.State.Success && isResumed) {
|
if (state is DownloadService.State.Success && isResumed) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
state.consume()
|
state.consume()
|
||||||
AppInstaller
|
|
||||||
.getInstance(context)?.defaultInstaller?.install(
|
|
||||||
"",
|
|
||||||
state.release.cacheFileName
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
AppInstaller
|
||||||
|
.getInstance(context)?.defaultInstaller?.install(
|
||||||
|
"",
|
||||||
|
state.release.cacheFileName
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,14 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
|
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
import com.looker.droidify.R
|
import com.looker.droidify.R
|
||||||
|
|
||||||
open class ScreenFragment : BaseFragment() {
|
open class ScreenFragment : BaseFragment() {
|
||||||
lateinit var toolbar: Toolbar
|
lateinit var toolbar: Toolbar
|
||||||
|
lateinit var collapsingToolbar: CollapsingToolbarLayout
|
||||||
|
lateinit var appBar: AppBarLayout
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@ -17,6 +21,8 @@ open class ScreenFragment : BaseFragment() {
|
|||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment, container, false)
|
val view = inflater.inflate(R.layout.fragment, container, false)
|
||||||
this.toolbar = view.findViewById(R.id.toolbar)
|
this.toolbar = view.findViewById(R.id.toolbar)
|
||||||
|
this.collapsingToolbar = view.findViewById(R.id.collapsing_toolbar)
|
||||||
|
this.appBar = view.findViewById(R.id.appbar_layout)
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
|
||||||
import com.google.android.material.imageview.ShapeableImageView
|
import com.google.android.material.imageview.ShapeableImageView
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
@ -109,12 +107,6 @@ class TabsFragment : ScreenFragment() {
|
|||||||
toolbar.isFocusableInTouchMode = true
|
toolbar.isFocusableInTouchMode = true
|
||||||
|
|
||||||
val searchView = FocusSearchView(toolbar.context).apply {
|
val searchView = FocusSearchView(toolbar.context).apply {
|
||||||
setOnSearchClickListener {
|
|
||||||
((toolbar.parent as CollapsingToolbarLayout).parent as AppBarLayout).setExpanded(
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
maxWidth = Int.MAX_VALUE
|
maxWidth = Int.MAX_VALUE
|
||||||
queryHint = getString(R.string.search)
|
queryHint = getString(R.string.search)
|
||||||
setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||||
@ -131,6 +123,7 @@ class TabsFragment : ScreenFragment() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
setOnSearchClickListener { appBar.setExpanded(false, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
toolbar.menu.apply {
|
toolbar.menu.apply {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
android:id="@+id/collapsing_toolbar_layout"
|
android:id="@+id/collapsing_toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
|
android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
|
||||||
app:contentScrim="@android:color/transparent"
|
app:contentScrim="@android:color/transparent"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user