MISC: enhance code step 2 (runApt)
This commit is contained in:
parent
cc1fe9de00
commit
dc694aad9c
@ -11,28 +11,24 @@ import io.neoterm.frontend.session.shell.client.BasicSessionCallback
|
||||
import io.neoterm.frontend.session.shell.client.BasicViewClient
|
||||
import io.neoterm.utils.Terminals
|
||||
|
||||
typealias DialogSessionFinished = (TerminalDialog, TerminalSession?) -> Unit
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class TerminalDialog(val context: Context) {
|
||||
|
||||
interface SessionFinishedCallback {
|
||||
fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?)
|
||||
}
|
||||
|
||||
private var termWindowView = WindowTermView(context)
|
||||
private var terminalSessionCallback: BasicSessionCallback
|
||||
private val termWindowView = WindowTermView(context)
|
||||
private val terminalSessionCallback: BasicSessionCallback
|
||||
private var dialog: AlertDialog? = null
|
||||
private var terminalSession: TerminalSession? = null
|
||||
private var sessionFinishedCallback: SessionFinishedCallback? = null
|
||||
private var sessionFinishedCallback: DialogSessionFinished? = null
|
||||
private var cancelListener: DialogInterface.OnCancelListener? = null
|
||||
|
||||
init {
|
||||
termWindowView.setTerminalViewClient(BasicViewClient(termWindowView.terminalView))
|
||||
|
||||
terminalSessionCallback = object : BasicSessionCallback(termWindowView.terminalView) {
|
||||
override fun onSessionFinished(finishedSession: TerminalSession?) {
|
||||
sessionFinishedCallback?.onSessionFinished(this@TerminalDialog, finishedSession)
|
||||
sessionFinishedCallback?.let { it(this@TerminalDialog, finishedSession) }
|
||||
super.onSessionFinished(finishedSession)
|
||||
}
|
||||
}
|
||||
@ -74,7 +70,7 @@ class TerminalDialog(val context: Context) {
|
||||
return this
|
||||
}
|
||||
|
||||
fun onFinish(finishedCallback: SessionFinishedCallback): TerminalDialog {
|
||||
fun onFinish(finishedCallback: DialogSessionFinished): TerminalDialog {
|
||||
this.sessionFinishedCallback = finishedCallback
|
||||
return this
|
||||
}
|
||||
|
@ -16,12 +16,9 @@ import androidx.core.view.MenuItemCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.component.pm.*
|
||||
import io.neoterm.frontend.component.ComponentManager
|
||||
import io.neoterm.frontend.config.NeoPreference
|
||||
import io.neoterm.frontend.config.NeoTermPath
|
||||
import io.neoterm.frontend.floating.TerminalDialog
|
||||
import io.neoterm.ui.pm.adapter.PackageAdapter
|
||||
import io.neoterm.ui.pm.model.PackageModel
|
||||
import io.neoterm.ui.pm.utils.StringDistance
|
||||
@ -57,9 +54,9 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
AlertDialog.Builder(this@PackageManagerActivity)
|
||||
.setTitle(model.packageInfo.packageName)
|
||||
.setMessage(model.getPackageDetails(this@PackageManagerActivity))
|
||||
.setPositiveButton(R.string.install, { _, _ ->
|
||||
.setPositiveButton(R.string.install) { _, _ ->
|
||||
installPackage(model.packageInfo.packageName)
|
||||
})
|
||||
}
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show()
|
||||
}
|
||||
@ -74,21 +71,9 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
refreshPackageList()
|
||||
}
|
||||
|
||||
private fun installPackage(packageName: String?) {
|
||||
if (packageName != null) {
|
||||
TerminalDialog(this@PackageManagerActivity)
|
||||
.execute(
|
||||
NeoTermPath.APT_BIN_PATH,
|
||||
arrayOf("apt", "install", "-y", packageName)
|
||||
)
|
||||
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||
dialog.setTitle(getString(R.string.done))
|
||||
}
|
||||
})
|
||||
.imeEnabled(true)
|
||||
.show("Installing $packageName")
|
||||
Toast.makeText(this, R.string.installing_topic, Toast.LENGTH_LONG).show()
|
||||
private fun installPackage(packageName: String?) = packageName?.let {
|
||||
runApt("install", "-y", it, autoClose = false) {
|
||||
it.onSuccess { it.setTitle(getString(R.string.done)) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,18 +100,15 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
val sourceManager = ComponentManager.getComponent<PackageComponent>().sourceManager
|
||||
val sourceList = sourceManager.getAllSources()
|
||||
|
||||
val items = sourceList.map { "${it.url} :: ${it.repo}" }.toTypedArray()
|
||||
val selection = sourceList.map { it.enabled }.toBooleanArray()
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(R.string.pref_package_source)
|
||||
.setMultiChoiceItems(sourceList.map { "${it.url} :: ${it.repo}" }.toTypedArray(),
|
||||
sourceList.map { it.enabled }.toBooleanArray(), { dialog, which, isChecked ->
|
||||
sourceList[which].enabled = isChecked
|
||||
})
|
||||
.setPositiveButton(android.R.string.yes, { _, _ ->
|
||||
changeSourceInternal(sourceManager, sourceList)
|
||||
})
|
||||
.setNeutralButton(R.string.new_source, { _, _ ->
|
||||
changeSourceToUserInput(sourceManager)
|
||||
})
|
||||
.setMultiChoiceItems(items, selection) { _, which, isChecked ->
|
||||
sourceList[which].enabled = isChecked
|
||||
}
|
||||
.setPositiveButton(android.R.string.yes) { _, _ -> changeSourceInternal(sourceManager, sourceList) }
|
||||
.setNeutralButton(R.string.new_source) { _, _ -> changeSourceToUserInput(sourceManager) }
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show()
|
||||
}
|
||||
@ -145,7 +127,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
.setTitle(R.string.pref_package_source)
|
||||
.setView(view)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.setPositiveButton(android.R.string.yes, { _, _ ->
|
||||
.setPositiveButton(android.R.string.yes) { _, _ ->
|
||||
val url = urlEditor.text.toString()
|
||||
val repo = repoEditor.text.toString()
|
||||
var errored = false
|
||||
@ -163,7 +145,7 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
val source = urlEditor.text.toString()
|
||||
sourceManager.addSource(source, repo, true)
|
||||
postChangeSource(sourceManager)
|
||||
})
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
@ -179,30 +161,15 @@ class PackageManagerActivity : AppCompatActivity(), SearchView.OnQueryTextListen
|
||||
executeAptUpdate()
|
||||
}
|
||||
|
||||
private fun executeAptUpdate() = runApt("update", null) { exitStatus, dialog ->
|
||||
if (exitStatus != 0) {
|
||||
dialog.setTitle(getString(R.string.error))
|
||||
return@runApt
|
||||
}
|
||||
Toast.makeText(this, R.string.apt_update_ok, Toast.LENGTH_SHORT).show()
|
||||
dialog.dismiss()
|
||||
refreshPackageList()
|
||||
private fun executeAptUpdate() = runApt("update") {
|
||||
it.onSuccess { refreshPackageList() }
|
||||
}
|
||||
|
||||
private fun executeAptUpgrade() = runApt("update", null) { exitStatus, dialog ->
|
||||
if (exitStatus != 0) {
|
||||
dialog.setTitle(getString(R.string.error))
|
||||
return@runApt
|
||||
}
|
||||
dialog.dismiss()
|
||||
|
||||
runApt("upgrade", arrayOf("-y")) aptUpgrade@{ exitStatus, dialog ->
|
||||
if (exitStatus != 0) {
|
||||
dialog.setTitle(getString(R.string.error))
|
||||
return@aptUpgrade
|
||||
private fun executeAptUpgrade() = runApt("update") { update ->
|
||||
update.onSuccess {
|
||||
runApt("upgrade", "-y") {
|
||||
it.onSuccess { Toast.makeText(this, R.string.apt_upgrade_ok, Toast.LENGTH_SHORT).show() }
|
||||
}
|
||||
Toast.makeText(this, R.string.apt_upgrade_ok, Toast.LENGTH_SHORT).show()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,17 +40,12 @@ class GeneralSettingsActivity : BasePreferenceActivity() {
|
||||
.setTitle(getString(R.string.shell_not_found, shellName))
|
||||
.setMessage(R.string.shell_not_found_message)
|
||||
.setPositiveButton(R.string.install) { _, _ ->
|
||||
runApt("install", arrayOf("-y", shellName)) { exitStatus, dialog ->
|
||||
if (exitStatus == 0) {
|
||||
dialog.dismiss()
|
||||
postChangeShell(shellName)
|
||||
} else dialog.setTitle(getString(R.string.error))
|
||||
runApt("install", "-y", shellName) {
|
||||
it.onSuccess { postChangeShell(shellName) }
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.setOnDismissListener {
|
||||
postChangeShell(currentShell)
|
||||
}
|
||||
.setOnDismissListener { postChangeShell(currentShell) }
|
||||
.show()
|
||||
}
|
||||
|
||||
@ -59,8 +54,7 @@ class GeneralSettingsActivity : BasePreferenceActivity() {
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item?.itemId) {
|
||||
android.R.id.home ->
|
||||
finish()
|
||||
android.R.id.home -> finish()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
@ -234,11 +234,11 @@ class SetupActivity : AppCompatActivity(), View.OnClickListener, ResultListener
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeAptUpdate() = runApt("update")
|
||||
.onSuccess { executeAptUpgrade() }
|
||||
.onFailure { Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show() }
|
||||
private fun executeAptUpdate() = runApt("update") {
|
||||
it.onSuccess { executeAptUpgrade() }
|
||||
}
|
||||
|
||||
private fun executeAptUpgrade() = runApt("upgrade", "-y")
|
||||
.onSuccess { finish() }
|
||||
.onFailure { Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show() }
|
||||
private fun executeAptUpgrade() = runApt("upgrade", "-y") {
|
||||
it.onSuccess { finish() }
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.provider.DocumentsContract
|
||||
import android.provider.MediaStore
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.R
|
||||
import io.neoterm.frontend.config.NeoTermPath
|
||||
import io.neoterm.frontend.floating.TerminalDialog
|
||||
import java.io.File
|
||||
@ -49,23 +49,23 @@ fun Context.extractAssetsDir(dirName: String, extractDir: String) {
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.runApt(subCommand: String, vararg extraArgs: String): Result<TerminalDialog> = runAsyncCatching {
|
||||
val args = arrayOf(NeoTermPath.APT_BIN_PATH, subCommand, *extraArgs)
|
||||
TerminalDialog(this)
|
||||
.onFinish(object : TerminalDialog.SessionFinishedCallback {
|
||||
override fun onSessionFinished(dialog: TerminalDialog, finishedSession: TerminalSession?) {
|
||||
val exit = finishedSession?.exitStatus ?: 1
|
||||
if (exit == 0) {
|
||||
dialog.dismiss()
|
||||
throw SuccessResult(dialog)
|
||||
}
|
||||
else throw RuntimeException()
|
||||
}
|
||||
})
|
||||
.imeEnabled(true)
|
||||
.execute(NeoTermPath.APT_BIN_PATH, args)
|
||||
.show("apt $subCommand")
|
||||
}
|
||||
fun Context.runApt(
|
||||
subCommand: String, vararg extraArgs: String,
|
||||
autoClose: Boolean = true, block: (Result<TerminalDialog>) -> Unit
|
||||
) = TerminalDialog(this)
|
||||
.execute(NeoTermPath.APT_BIN_PATH, arrayOf(NeoTermPath.APT_BIN_PATH, subCommand, *extraArgs))
|
||||
.imeEnabled(true)
|
||||
.onFinish { dialog, session ->
|
||||
val exit = session?.exitStatus ?: 1
|
||||
if (exit == 0) {
|
||||
if (autoClose) dialog.dismiss()
|
||||
block(Result.success(dialog))
|
||||
} else {
|
||||
dialog.setTitle(getString(R.string.error))
|
||||
block(Result.failure(RuntimeException()))
|
||||
}
|
||||
}
|
||||
.show("apt $subCommand")
|
||||
|
||||
/**
|
||||
* Get a file path from a Uri. This will get the the path for Storage Access
|
||||
@ -121,15 +121,3 @@ private fun getDataColumn(context: Context, uri: Uri, selection: String?, select
|
||||
private fun isExternalStorageDocument(uri: Uri) = "com.android.externalstorage.documents" == uri.authority
|
||||
private fun isDownloadsDocument(uri: Uri) = "com.android.providers.downloads.documents" == uri.authority
|
||||
private fun isMediaDocument(uri: Uri) = "com.android.providers.media.documents" == uri.authority
|
||||
|
||||
data class SuccessResult(val data: Any) : RuntimeException()
|
||||
|
||||
inline fun <reified R> runAsyncCatching(block: () -> Unit): Result<R> = try {
|
||||
block()
|
||||
Result.failure(IllegalStateException())
|
||||
} catch (s: SuccessResult) {
|
||||
if (s.data is R) Result.success(s.data)
|
||||
else Result.failure(ClassCastException())
|
||||
} catch (e: Throwable) {
|
||||
Result.failure(e)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user