Skip to main content

Maestro Panel SDK Documentation

Overview

This SDK simplifies integrating interactive panels into your Jetpack Compose Android applications. It provides APIs for event handling, user interaction, and UI updates, enabling rich user experiences. The core composable is MaestroPanel(), which displays the panel. MaestroManager is a singleton object used for SDK initialization and management.

Installation

Define the dependency in your build.gradle (app/module level):

implementation("com.lessthan3:maestropanel:3.2.0")

In settings.gradle, add the maven repository:

maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/lessthan3/MaestroKit.android")
credentials {
username = "your_git_username"
password = "your_git_personal_access_token"
}
}

Use your own Github username and generate your own PAT. Note: the PAT must have a validity of at most 1 year.

Key Concepts and Interfaces

The SDK uses these key interfaces:

  1. MaestroManager: A singleton used for SDK initialization and configuration.
  2. MaestroSDKInstance: Represents a single initialized Maestro SDK session. Returned by the configure call from the MaestroManager.
  3. MaestroEventDelegate: A delegate interface implemented by the client app let the SDK notify the app of relevant events.
  4. MaestroEventInterface: The API used to let the client app notify the SDK of certain events and thus control UI functionalities. Implemented by MaestroEventViewModel.

Usage

1. Initialize the SDK

At app launch, configure the MaestroManager singleton to obtain the SDK instance:

val sdk =  MaestroManager.configure(
context = applicationContext,
maestroEventDelegate = this,
params = MaestroSDKParameters(
siteId = "your site ID",
eventData = null, // Provide the initial event data, if any
),
)

2. Displaying the Panel and Initializing the ViewModel

To display MaestroPanel(), first initialize MaestroEventViewModel. You can use the maestroEventViewModel composable function or manually instantiate it, but make sure that the key corresponds to the SDK instance (to make sure the lifecycle of the viewmodel corresponds to the SDK instance's lifecycle):


@Composable
fun maestroEventViewModel(sdk: MaestroSDKInstance) = viewModel(
modelClass = MaestroEventViewModel::class.java,
factory = MaestroEventViewModelFactory(sdk = sdk),
key = "eventVM" + sdk.hashCode().toString(),
)

MaestroPanel(
maestroEventViewModel = maestroEventViewModel(sdk)
)

API Reference

MaestroManager

object MaestroManagerInterface {
/** An overridable custom error handler for any SDK-reported errors. By default, it prints to the console. */
var customExceptionHandler: ((e: Throwable?, message: String, fatal: Boolean) -> Unit)

/** An overridable custom breadcrumb handler for any SDK-reported breadcrumb events. By default, it prints to the console. */
var breadcrumbHandler: ((tag: String?, message: String, e: Throwable?) -> Unit)

/**
* Configure a new SDK instance.
* Only one instance can be configured at a time,
* any previously initialized instances will be detached and should not be used anymore.
*/
fun configure(
context: Context,
maestroEventDelegate: MaestroEventDelegate,
params: MaestroSDKParameters,
): MaestroSDKInstance
}

MaestroSDKInstance

interface MaestroSDKInstance {
/** Notifies the SDK that the pinch back mode was entered (the client app went full-screen). */
fun onPinchBackEntered()

/** Notifies the SDK that the pinch back mode was exited (the client app exited full-screen and the Maestro panel is visible). */
fun onPinchBackExited()

/** Notifies the SDK about the new state of the currently-played event. */
fun onEventDataUpdated(data: MaestroEventData?)

/** Update the user-specific configuration of the SDK. Changes will be reflected dynamically. */
fun updateConfig(config: UserConfig)

/** Notifies the SDK that the current play-head time-code was updated to a new value. */
fun onPlayerTimecodeUpdated(absoluteTimeMillis: Long?)

/**
* Detaches the SDK and stops all the work it may be doing.
* The SDK cannot be used after this method is invoked.
*/
fun detach()
}

MaestroEventDelegate

/**
* A delegate interface implemented by the client app.
* Serves two purposes:
* 1) lets the app communicate any data changes (key plays, auth, ...) to the SDK
* 2) lets the SDK communicate certain events which the app should/may respond to
*/
interface MaestroEventDelegate {
/** A flow of key plays data managed by the client app that the SDK will collect and display. */
fun keyPlaysData(): StateFlow<MaestroLoadableResult<MaestroKeyPlaysResponse>>

/** A flow of authentication data to be used by the SDK to load relevant data. */
fun authData(): StateFlow<MaestroAuthData?>

/**
* Notifies the client app that a particular key plays clip should be played, given its flattened [index] in the key plays list.
* Note that the [MaestroKeyPlaysResponse] subdivides the key plays by section, so the [index] referenced here
* is the global index in the flattened list of key plays across all sections.
*/
fun playClip(index: Int, clipId: String?)

/** Notifies the client app to make a new load of the key plays data */
fun onKeyPlaysRefreshNeeded()

/** Notifies the client app that the panel should be displayed. */
fun shouldShowPanel()

/** Notifies the client app that the panel should be dismissed. */
fun shouldHidePanel()

/** Notifies the client app that the given overlay should be displayed. */
fun shouldShowOverlay(event: MaestroOverlayEvent)

/** Notifies the client app that the currently-displayed overlay should be dismissed. */
fun shouldHideOverlay()

/** Notifies the client app of user impressions for analytics tracking. */
fun trackImpression(analytics: Map<String, String>)

/** Notifies the client app of user actions for analytics tracking. */
fun trackAction(analytics: Map<String, String>)

/** Notifies the client app that the (Fantasy) login card was clicked. */
fun onLoginClicked()

/** Notifies the client app that the panel [panel] was selected. */
fun onPanelSelected(panel: MaestroPanelType)
}

MaestroEventInterface


/**
* The API used to let the client app notify the SDK of certain events
* and thus control UI functionalities.
*/
interface MaestroEventInterface {

/** Notifies the SDK that the key play clip at [index] started playing. */
fun didStartPlayingClip(index: Int)

/** Notifies the SDK that the key play clip at [index] stopped playing. */
fun didStopPlayingClip(index: Int)

/** Notifies the SDK that the user tried to play the clip but it failed to play back.*/
fun clipDidFailToPlay(index: Int)

/** Notifies the SDK of the playback [progress] (0 to 1) of the currently-played key play clip. */
fun didUpdatePlaybackProgressOfClip(progress: Float)

/** Notifies the SDK that the MaestroPanel was displayed.*/
fun didShowPanel(maestroPanelType: MaestroPanelType)

/** Notifies the SDK that MaestroPanel was hidden. */
fun didHidePanel()

/** Notifies the SDK that the key play with index [index] needs to gain focus. */
fun onKeyPlayFocusChanged(index: Int)
}