Skip to content

Conversation

@VolkovsaVSA
Copy link
Contributor

Summary

Add an optional onSave callback to ControlPanelModule that is invoked when the user saves changes in the Control Panel. This allows library consumers to persist values to external storage or perform custom actions when settings are saved.

Problem

Currently, the Control Panel module saves values internally using ControlPanelSettings, but there's no way for library consumers to:

  • Be notified when values are saved
  • Persist values to their own external storage
  • Synchronize Control Panel values with application-specific settings

Solution

Add an optional onSave callback parameter that receives all current values when the user presses "Save".

Changes

  • ControlPanelModule: Added onSave: ((Map<String, InputType>) -> Unit)? = null constructor parameter
  • DefaultControlPanelComponent: Invoke the callback in onSavePressed() after saving to internal settings

Usage Example

val controlPanelModule = ControlPanelModule(
    context = platformContext,
    items = listOf(
        ControlPanelItem("Feature A", InputType.Boolean(true)),
        ControlPanelItem("API URL", InputType.String("https://api.example.com")),
    ),
    onSave = { values ->
        // Persist to external storage
        values.forEach { (name, inputType) ->
            when (inputType) {
                is InputType.Boolean -> externalStorage.putBoolean(name, inputType.value)
                is InputType.String -> externalStorage.putString(name, inputType.value)
                is InputType.Int -> externalStorage.putInt(name, inputType.value)
            }
        }
    }
)

Backward Compatibility

Fully backward compatible - the callback is optional with a default value of null, so existing code continues to work without changes.

bartwell and others added 2 commits December 24, 2025 17:05
Add an optional onSave callback to ControlPanelModule that is invoked
when the user saves changes in the Control Panel. This allows library
consumers to persist values to external storage or perform custom
actions when settings are saved.

The callback receives a Map<String, InputType> containing all current
values from the Control Panel.
@bartwell bartwell changed the base branch from main to develop January 16, 2026 13:05
@bartwell
Copy link
Owner

Hello @VolkovsaVSA,
Thank you for supporting the library.

I have a couple of notes regarding your pull request:

  1. It would be better not to pass the callback via the module constructor for two reasons:
  • On iOS it will become a required parameter, because iOS does not support Kotlin default argument values.
  • It may be more convenient for users to set the callback wherever it makes sense in their code. Given that, it’s preferable to avoid constructor injection here and implement this via ControlPanelAccessor.
  1. When updating a module implementation, please make sure to also verify the corresponding stub module.

  2. One more thought: please avoid passing the whole Map<String, InputType> into onSave. Yes, users can read values via ControlPanelAccessor, but that requires an explicit action and makes the “data boundary” obvious. A callback that receives the entire map tends to be forwarded around and accidentally ends up in logs/analytics/crash reports. It also locks us into the current InputType structure (and is awkward on iOS), making future internal changes a breaking API change. I’d prefer onSave: () -> Unit (or onSave(changedKeys: Set)) and users can read what they need via the accessor.

@bartwell
Copy link
Owner

Please note that I’ve implemented an event Flow for the Control Panel module: #29

This provides a more flexible, cross-platform mechanism. It allows tracking value changes, button clicks, exiting the module, and saving changes.
With this in place, it seems the callback is no longer necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants