joaomgcd / TaskerPluginSample

A library to help speed up building a Tasker plugin
GNU General Public License v3.0
58 stars 23 forks source link

Usage with Jetpack Compose? #23

Open Myzel394 opened 10 months ago

Myzel394 commented 10 months ago

I don't know whether this is a mistake on my side, but I don't know how create a State with Jetpack Compose.

So I got a audio recording app and I want the user to be able to detect what state it is currently running.

@TaskerInputRoot
class AudioRecorderInput(
    @field:TaskerInputField(VAR_STATE, labelResIdName = "ui_audioRecorder_recordingState_label") var state: String? = null
) {
    companion object {
        const val VAR_STATE = "audioRecorderState"
    }
}

@TaskerOutputObject
class AudioRecorderOutput(
    @get:TaskerOutputVariable(VAR_STATE, labelResIdName = "ui_audioRecorder_recordingState_label") val state: String = RecorderState.IDLE.name
) {
    companion object {
        const val VAR_STATE = "audioRecorderState"
    }
}

Then, in the runner I check whether the given state by the user matches the current state:

class AudioRecorderRunner : TaskerPluginRunnerConditionState<AudioRecorderInput, AudioRecorderOutput>() {
    override fun getSatisfiedCondition(context: Context, input: TaskerInput<AudioRecorderInput>, update: Unit?): TaskerPluginResultCondition<AudioRecorderOutput> {
        return if (state.name == input.regular.state)
            TaskerPluginResultConditionSatisfied(context)
        else TaskerPluginResultConditionUnsatisfied()
    }

    companion object {
        var state: RecorderState = RecorderState.IDLE
        fun change(context: Context, newState: RecorderState) {
            state = newState
            AudioRecorderActivity::class.java.requestQuery(context)
        }
    }
}

This is the helper:

class AudioRecorderHelper(config: TaskerPluginConfig<AudioRecorderInput>) : TaskerPluginConfigHelper<AudioRecorderInput, AudioRecorderOutput, AudioRecorderRunner>(config) {
    override val runnerClass = AudioRecorderRunner::class.java
    override val inputClass = AudioRecorderInput::class.java
    override val outputClass = AudioRecorderOutput::class.java
}

and in the activity I show a dropdown for the user to select from - but how do I pass that information back to Tasker?

class AudioRecorderActivity : AppCompatActivity(), TaskerPluginConfig<AudioRecorderInput> {
    override val inputForTasker: TaskerInput<AudioRecorderInput>
        get() = TaskerInput(AudioRecorderInput(selectedState.name))

    override val context: Context
        get() = applicationContext

    override fun assignFromInput(input: TaskerInput<AudioRecorderInput>) {
        // println("test") // Does not seem to be called
        input.regular.run {
            selectedState = RecorderState.valueOf(state ?: RecorderState.IDLE.name)
        }
    }

    var selectedState by mutableStateOf(RecorderState.IDLE)

    override fun onStart() {
        super.onStart()

        WindowCompat.setDecorFitsSystemWindows(window, false)

        setContent {
            var selectedState by remember { mutableStateOf(RecorderState.IDLE) }

            AlibiTheme {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(MaterialTheme.colorScheme.background)
                        .padding(horizontal = 16.dp, vertical = 32.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.SpaceBetween,
                ) {
                    Box {}
                    Text(
                        "Configure Audio Recorder State",
                        style = MaterialTheme.typography.headlineLarge,
                        color = MaterialTheme.colorScheme.onBackground,
                        textAlign = TextAlign.Center,
                    )
                    Box {}

                    var opened by remember { mutableStateOf(false) }
                    Column {
                        Box {
                            Button(
                                onClick = {
                                    opened = true
                                },
                                colors = ButtonDefaults.filledTonalButtonColors(
                                    containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
                                        4.dp
                                    ),
                                ),
                                shape = MaterialTheme.shapes.small,
                            ) {
                                Text(
                                    getString(ENUM_LABEL_MAP[selectedState]!!)
                                )
                            }
                            DropdownMenu(
                                expanded = opened,
                                onDismissRequest = { opened = false },
                            ) {
                                RecorderState.values().forEach { state ->
                                    DropdownMenuItem(
                                        onClick = {
                                            opened = false

                                            selectedState = state
                                        },
                                        text = {
                                            val resourceId = ENUM_LABEL_MAP[state]!!
                                            val text = getString(resourceId)

                                            Text(text)
                                        }
                                    )
                                }
                            }
                        }
                    }

                    Button(
                        onClick = {
                            val helper = AudioRecorderHelper(this@AudioRecorderActivity)

                            helper.finishForTasker()
                        },
                    ) {
                        Text(
                            stringResource(id = R.string.dialog_close_neutral_label)
                        )
                    }
                }
            }
        }
    }
}
joaomgcd commented 7 months ago

Hi! I'm very sorry for taking so long to respond. I must've missed this somehow! Were you able to figure it out?

Looking at your code real quick it seems like you're doing it right... You should call finishForTasker() which will then get your input from inputForTasker.

Let me know, thanks!

Myzel394 commented 7 months ago

Unfortunately, I was not able to figure it out. It's been a while since I've worked on the code, but I will definitely take a look at it later as I still would like to add Tasker support :D

Won't happen today or tomorrow, I'll ping you once I've tried it out and taken a closer look at it.

joaomgcd commented 7 months ago

Thanks :) But I think you have the right idea. Must be something small that's missing somewhere...