package com.suno.android.common_ui.components.timebox import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import com.suno.android.common_ui.components.waveform.DpPerSecond import kotlin.time.Duration /** * A state holder for the TimeBox component that manages the time-based viewport state. * * The TimeBoxState maintains two key pieces of state: * 1. `resolution`: Controls how many pixels represent one second of time (DpPerSecond) * 2. `startTimeOffset`: The starting time offset of the viewport * * This state is used by TimeBox to determine what time range is visible and how to * position time-based elements within the viewport. * * @property initialResolution The initial zoom level/resolution of the time view * @property initialStartTimeOffset The initial time offset of the viewport */ class TimeBoxState( initialResolution: DpPerSecond, initialStartTimeOffset: Duration = Duration.ZERO, ) { internal val resolutionState = mutableStateOf(initialResolution) val resolution get() = resolutionState.value internal val startTimeOffsetState = mutableStateOf(initialStartTimeOffset) val startTimeOffset get() = startTimeOffsetState.value } /** * Creates and remembers a [TimeBoxState] instance that persists across recompositions. * * This is the primary way to create a TimeBoxState for use in a TimeBox component. * The state will be preserved across recompositions and will only be recreated if * the resolution or startTimeOffset parameters change. * * @param resolution The initial zoom level/resolution of the time view * @param startTimeOffset The initial time offset of the viewport, defaults to Duration.ZERO * @return A remembered TimeBoxState instance */ @Composable fun rememberTimeBoxState( resolution: DpPerSecond, startTimeOffset: Duration = Duration.ZERO, ): TimeBoxState = remember { TimeBoxState( initialResolution = resolution, initialStartTimeOffset = startTimeOffset, ) } /** * Creates and remembers a [TimeBoxState] instance that updates its values when the * provided resolution or startTimeOffset parameters change. * * Unlike [rememberTimeBoxState], this function will update the state's values * whenever the input parameters change, making it suitable for cases where the * time box needs to be controlled externally. * * @param resolution The current zoom level/resolution of the time view * @param startTimeOffset The current time offset of the viewport, defaults to Duration.ZERO * @return A remembered TimeBoxState instance that updates with parameter changes */ @Composable fun rememberTimeBoxStateOf( resolution: DpPerSecond, startTimeOffset: Duration = Duration.ZERO, ): TimeBoxState = remember { TimeBoxState( initialResolution = resolution, initialStartTimeOffset = startTimeOffset, ) }.apply { resolutionState.value = resolution startTimeOffsetState.value = startTimeOffset }