feat(scripting): compose alert dialog

This commit is contained in:
rhunk 2023-12-26 13:09:52 +01:00
parent 72c9b92a3e
commit fe5c6306e1
3 changed files with 54 additions and 21 deletions

View File

@ -1,5 +1,8 @@
package me.rhunk.snapenhance.common.scripting.ui package me.rhunk.snapenhance.common.scripting.ui
import android.app.Activity
import android.app.AlertDialog
import androidx.compose.runtime.remember
import me.rhunk.snapenhance.common.scripting.bindings.AbstractBinding import me.rhunk.snapenhance.common.scripting.bindings.AbstractBinding
import me.rhunk.snapenhance.common.scripting.bindings.BindingSide import me.rhunk.snapenhance.common.scripting.bindings.BindingSide
import me.rhunk.snapenhance.common.scripting.ktx.contextScope import me.rhunk.snapenhance.common.scripting.ktx.contextScope
@ -9,6 +12,7 @@ import me.rhunk.snapenhance.common.scripting.ui.components.NodeType
import me.rhunk.snapenhance.common.scripting.ui.components.impl.ActionNode import me.rhunk.snapenhance.common.scripting.ui.components.impl.ActionNode
import me.rhunk.snapenhance.common.scripting.ui.components.impl.ActionType import me.rhunk.snapenhance.common.scripting.ui.components.impl.ActionType
import me.rhunk.snapenhance.common.scripting.ui.components.impl.RowColumnNode import me.rhunk.snapenhance.common.scripting.ui.components.impl.RowColumnNode
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
import org.mozilla.javascript.Function import org.mozilla.javascript.Function
import org.mozilla.javascript.annotations.JSFunction import org.mozilla.javascript.annotations.JSFunction
@ -74,6 +78,7 @@ class InterfaceBuilder {
@Suppress("unused")
class InterfaceManager : AbstractBinding("interface-manager", BindingSide.COMMON) { class InterfaceManager : AbstractBinding("interface-manager", BindingSide.COMMON) {
private val interfaces = mutableMapOf<String, (args: Map<String, Any?>) -> InterfaceBuilder?>() private val interfaces = mutableMapOf<String, (args: Map<String, Any?>) -> InterfaceBuilder?>()
@ -93,7 +98,6 @@ class InterfaceManager : AbstractBinding("interface-manager", BindingSide.COMMON
return interfaces.containsKey(scriptInterfaces.key) return interfaces.containsKey(scriptInterfaces.key)
} }
@Suppress("unused")
@JSFunction fun create(name: String, callback: Function) { @JSFunction fun create(name: String, callback: Function) {
interfaces[name] = { args -> interfaces[name] = { args ->
val interfaceBuilder = InterfaceBuilder() val interfaceBuilder = InterfaceBuilder()
@ -112,5 +116,21 @@ class InterfaceManager : AbstractBinding("interface-manager", BindingSide.COMMON
} }
} }
@JSFunction fun createAlertDialog(activity: Activity, builder: (AlertDialog.Builder) -> Unit, callback: (interfaceBuilder: InterfaceBuilder, alertDialog: AlertDialog) -> Unit): AlertDialog {
return createComposeAlertDialog(activity, builder = builder) { alertDialog ->
ScriptInterface(interfaceBuilder = remember {
InterfaceBuilder().also {
contextScope {
callback(it, alertDialog)
}
}
})
}
}
@JSFunction fun createAlertDialog(activity: Activity, callback: (interfaceBuilder: InterfaceBuilder, alertDialog: AlertDialog) -> Unit): AlertDialog {
return createAlertDialog(activity, {}, callback)
}
override fun getObject() = this override fun getObject() = this
} }

View File

@ -1,12 +1,18 @@
package me.rhunk.snapenhance.common.ui package me.rhunk.snapenhance.common.ui
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.WindowManager
import androidx.activity.OnBackPressedDispatcher import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.Recomposer import androidx.compose.runtime.Recomposer
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.AndroidUiDispatcher import androidx.compose.ui.platform.AndroidUiDispatcher
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.platform.ViewCompositionStrategy
@ -58,6 +64,26 @@ fun createComposeView(context: Context, content: @Composable () -> Unit) = Compo
} }
} }
fun createComposeAlertDialog(context: Context, builder: AlertDialog.Builder.() -> Unit = {}, content: @Composable (alertDialog: AlertDialog) -> Unit): AlertDialog {
lateinit var alertDialog: AlertDialog
return AlertDialog.Builder(context)
.apply(builder)
.setView(createComposeView(context) {
Surface(
modifier = Modifier.fillMaxWidth(),
color = MaterialTheme.colorScheme.surface
) {
content(alertDialog)
}
})
.create().apply {
alertDialog = this
window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
}
private class OverlayLifecycleOwner : SavedStateRegistryOwner { private class OverlayLifecycleOwner : SavedStateRegistryOwner {
private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this) private var mLifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
private var mSavedStateRegistryController: SavedStateRegistryController = private var mSavedStateRegistryController: SavedStateRegistryController =

View File

@ -3,7 +3,6 @@ package me.rhunk.snapenhance.core.action.impl
import android.app.AlertDialog import android.app.AlertDialog
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Environment import android.os.Environment
import android.view.WindowManager
import androidx.compose.foundation.ScrollState import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -26,7 +25,7 @@ import androidx.compose.ui.unit.dp
import kotlinx.coroutines.* import kotlinx.coroutines.*
import me.rhunk.snapenhance.common.data.ContentType import me.rhunk.snapenhance.common.data.ContentType
import me.rhunk.snapenhance.common.database.impl.FriendFeedEntry import me.rhunk.snapenhance.common.database.impl.FriendFeedEntry
import me.rhunk.snapenhance.common.ui.createComposeView import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
import me.rhunk.snapenhance.core.action.AbstractAction import me.rhunk.snapenhance.core.action.AbstractAction
import me.rhunk.snapenhance.core.features.impl.messaging.Messaging import me.rhunk.snapenhance.core.features.impl.messaging.Messaging
import me.rhunk.snapenhance.core.logger.CoreLogger import me.rhunk.snapenhance.core.logger.CoreLogger
@ -255,24 +254,12 @@ class ExportChatMessages : AbstractAction() {
override fun run() { override fun run() {
context.coroutineScope.launch(Dispatchers.Main) { context.coroutineScope.launch(Dispatchers.Main) {
lateinit var exporterDialog: AlertDialog createComposeAlertDialog(context.mainActivity!!) { alertDialog ->
ViewAppearanceHelper.newAlertDialogBuilder(context.mainActivity) ExporterDialog { alertDialog }
.setTitle(translation["select_conversation"]) }.apply {
.setView(createComposeView(context.mainActivity!!) { setCanceledOnTouchOutside(false)
Surface( show()
modifier = Modifier.fillMaxWidth(), }
color = MaterialTheme.colorScheme.surface
) {
ExporterDialog { exporterDialog }
}
})
.create().apply {
exporterDialog = this
setCanceledOnTouchOutside(false)
show()
window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
}
} }
} }