MISC: enhance code step 2 (runApt)

This commit is contained in:
imkiva 2021-05-08 16:41:20 +08:00 committed by Kiva Oyama
parent cc1fe9de00
commit dc694aad9c
5 changed files with 55 additions and 110 deletions

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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)
}

View File

@ -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() }
}
}

View File

@ -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)
}