Added installing external modules from storage
This commit is contained in:
parent
711799b194
commit
0f140b408c
@ -81,6 +81,13 @@ class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
|
|||||||
override fun itemSameAs(other: RepoRvItem): Boolean = item.id == other.item.id
|
override fun itemSameAs(other: RepoRvItem): Boolean = item.id == other.item.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object InstallModule : ComparableRvItem<InstallModule>() {
|
||||||
|
override val layoutRes = R.layout.item_module_download
|
||||||
|
|
||||||
|
override fun contentSameAs(other: InstallModule) = this == other
|
||||||
|
override fun itemSameAs(other: InstallModule) = this === other
|
||||||
|
}
|
||||||
|
|
||||||
class SectionTitle(
|
class SectionTitle(
|
||||||
val title: Int,
|
val title: Int,
|
||||||
val button: Int = 0,
|
val button: Int = 0,
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.topjohnwu.magisk.model.events
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.topjohnwu.magisk.Const
|
||||||
|
import com.topjohnwu.magisk.base.BaseActivity
|
||||||
|
import com.topjohnwu.magisk.intent
|
||||||
|
import com.topjohnwu.magisk.ui.flash.FlashActivity
|
||||||
|
|
||||||
|
class InstallExternalModuleEvent : ViewEvent(), ActivityExecutor {
|
||||||
|
|
||||||
|
override fun invoke(activity: AppCompatActivity) {
|
||||||
|
activity as BaseActivity<*, *>
|
||||||
|
activity.withExternalRW {
|
||||||
|
onSuccess {
|
||||||
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||||
|
intent.type = "application/zip"
|
||||||
|
activity.startActivityForResult(intent, Const.ID.FETCH_ZIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun onActivityResult(context: Context, requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) {
|
||||||
|
// Get the URI of the selected file
|
||||||
|
val intent = context.intent(FlashActivity::class.java)
|
||||||
|
intent.setData(data.data).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.redesign.module
|
package com.topjohnwu.magisk.redesign.module
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Insets
|
import android.graphics.Insets
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
@ -9,6 +10,7 @@ import android.view.View
|
|||||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||||
|
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
||||||
import com.topjohnwu.magisk.redesign.MainActivity
|
import com.topjohnwu.magisk.redesign.MainActivity
|
||||||
import com.topjohnwu.magisk.redesign.ReselectionTarget
|
import com.topjohnwu.magisk.redesign.ReselectionTarget
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||||
@ -27,6 +29,11 @@ class ModuleFragment : CompatFragment<ModuleViewModel, FragmentModuleMd2Binding>
|
|||||||
|
|
||||||
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
InstallExternalModuleEvent.onActivityResult(requireContext(), requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
@ -15,9 +15,11 @@ import com.topjohnwu.magisk.model.download.RemoteFileService
|
|||||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||||
import com.topjohnwu.magisk.model.entity.module.Module
|
import com.topjohnwu.magisk.model.entity.module.Module
|
||||||
import com.topjohnwu.magisk.model.entity.module.Repo
|
import com.topjohnwu.magisk.model.entity.module.Repo
|
||||||
|
import com.topjohnwu.magisk.model.entity.recycler.InstallModule
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
|
import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.RepoItem
|
import com.topjohnwu.magisk.model.entity.recycler.RepoItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.SectionTitle
|
import com.topjohnwu.magisk.model.entity.recycler.SectionTitle
|
||||||
|
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
|
||||||
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
|
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
import com.topjohnwu.magisk.redesign.compat.Queryable
|
import com.topjohnwu.magisk.redesign.compat.Queryable
|
||||||
@ -219,10 +221,12 @@ class ModuleViewModel(
|
|||||||
fun download(item: RepoItem) = ModuleInstallDialog(item.item).publish()
|
fun download(item: RepoItem) = ModuleInstallDialog(item.item).publish()
|
||||||
|
|
||||||
fun sectionPressed(item: SectionTitle) = when (item) {
|
fun sectionPressed(item: SectionTitle) = when (item) {
|
||||||
sectionActive -> reboot()
|
sectionActive -> reboot() //TODO add reboot picker, regular reboot is not always preferred
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun installPressed() = InstallExternalModuleEvent().publish()
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
/** Callable only from worker thread because of expensive list filtering */
|
/** Callable only from worker thread because of expensive list filtering */
|
||||||
@ -230,7 +234,7 @@ class ModuleViewModel(
|
|||||||
private fun build(
|
private fun build(
|
||||||
active: List<ModuleItem> = itemsInstalled,
|
active: List<ModuleItem> = itemsInstalled,
|
||||||
remote: List<RepoItem> = itemsRemote
|
remote: List<RepoItem> = itemsRemote
|
||||||
) = active.prependIfNotEmpty { sectionActive } +
|
) = (active + InstallModule).prependIfNotEmpty { sectionActive } +
|
||||||
remote.prependIfNotEmpty { sectionRemote }
|
remote.prependIfNotEmpty { sectionRemote }
|
||||||
|
|
||||||
private fun <T> List<T>.prependIfNotEmpty(item: () -> T) =
|
private fun <T> List<T>.prependIfNotEmpty(item: () -> T) =
|
||||||
|
10
app/src/main/res/drawable/ic_module_storage_md2.xml
Normal file
10
app/src/main/res/drawable/ic_module_storage_md2.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?colorOnSurface"
|
||||||
|
android:pathData="M2,10.96C1.5,10.68 1.35,10.07 1.63,9.59L3.13,7C3.24,6.8 3.41,6.66 3.6,6.58L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.66,6.72 20.82,6.88 20.91,7.08L22.36,9.6C22.64,10.08 22.47,10.69 22,10.96L21,11.54V16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V10.96C2.7,11.13 2.32,11.14 2,10.96M12,4.15V4.15L12,10.85V10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V12.69L14,15.59C13.67,15.77 13.3,15.76 13,15.6V19.29L19,15.91M13.85,13.36L20.13,9.73L19.55,8.72L13.27,12.35L13.85,13.36Z" />
|
||||||
|
</vector>
|
30
app/src/main/res/layout/item_module_download.xml
Normal file
30
app/src/main/res/layout/item_module_download.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout 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">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="item"
|
||||||
|
type="com.topjohnwu.magisk.model.entity.recycler.InstallModule" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.topjohnwu.magisk.redesign.module.ModuleViewModel" />
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="?styleButtonText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:onClick="@{() -> viewModel.installPressed()}"
|
||||||
|
android:text="@string/module_action_install_external"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:icon="@drawable/ic_module_storage_md2"
|
||||||
|
app:iconPadding="@dimen/l_50"
|
||||||
|
tools:layout_width="150dp" />
|
||||||
|
|
||||||
|
</layout>
|
@ -80,6 +80,7 @@
|
|||||||
<string name="module_section_remote">Remote</string>
|
<string name="module_section_remote">Remote</string>
|
||||||
<string name="module_state_remove">Remove</string>
|
<string name="module_state_remove">Remove</string>
|
||||||
<string name="module_state_restore">Restore</string>
|
<string name="module_state_restore">Restore</string>
|
||||||
|
<string name="module_action_install_external">Install from storage</string>
|
||||||
|
|
||||||
<string name="superuser_toggle_log">Toggles logging</string>
|
<string name="superuser_toggle_log">Toggles logging</string>
|
||||||
<string name="superuser_toggle_notification">Toggles “toast” notifications</string>
|
<string name="superuser_toggle_notification">Toggles “toast” notifications</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user