refactor to a shared composable to eliminate waveform code duplication

This commit is contained in:
davotoula
2026-01-11 10:33:05 +01:00
parent d8093f64b1
commit 70c638ad90
@@ -110,6 +110,32 @@ fun VoiceHeader(
?.let { WaveformData(it) } ?.let { WaveformData(it) }
} }
RenderAudioWithWaveform(
mediaUrl = media,
title = noteEvent.subject(),
mimeType = null,
waveform = waveform,
note = note,
accountViewModel = accountViewModel,
nav = nav,
)
}
/**
* Shared composable for rendering audio with waveform visualization.
* Used by both VoiceHeader (for BaseVoiceEvent) and RenderAudioFromIMeta (for other events with audio IMeta).
*/
@Composable
fun RenderAudioWithWaveform(
mediaUrl: String,
title: String?,
mimeType: String?,
waveform: WaveformData?,
note: Note,
accountViewModel: AccountViewModel,
nav: INav,
) {
val noteEvent = note.event ?: return
val callbackUri = remember(note) { note.toNostrUri() } val callbackUri = remember(note) { note.toNostrUri() }
Column(modifier = MaxWidthPaddingTop5dp, horizontalAlignment = Alignment.CenterHorizontally) { Column(modifier = MaxWidthPaddingTop5dp, horizontalAlignment = Alignment.CenterHorizontally) {
@@ -117,14 +143,14 @@ fun VoiceHeader(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
GetMediaItem( GetMediaItem(
videoUri = media, videoUri = mediaUrl,
title = noteEvent.subject(), title = title,
artworkUri = null, artworkUri = null,
authorName = note.author?.toBestDisplayName(), authorName = note.author?.toBestDisplayName(),
callbackUri = callbackUri, callbackUri = callbackUri,
mimeType = null, mimeType = mimeType,
aspectRatio = null, aspectRatio = null,
proxyPort = accountViewModel.httpClientBuilder.proxyPortForVideo(media), proxyPort = accountViewModel.httpClientBuilder.proxyPortForVideo(mediaUrl),
keepPlaying = false, keepPlaying = false,
waveformData = waveform, waveformData = waveform,
) { mediaItem -> ) { mediaItem ->
@@ -171,7 +197,7 @@ fun RenderVoicePlayer(
factory = { context: Context -> factory = { context: Context ->
PlayerView(context).apply { PlayerView(context).apply {
player = controllerState.controller player = controllerState.controller
// if we alrady know the size of the frame, this forces the player to stay in the size // if we already know the size of the frame, this forces the player to stay in the size
layoutParams = layoutParams =
FrameLayout.LayoutParams( FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT,
@@ -307,43 +333,13 @@ fun RenderAudioFromIMeta(
audioMeta.waveform?.let { WaveformData(it) } audioMeta.waveform?.let { WaveformData(it) }
} }
val callbackUri = remember(note) { note.toNostrUri() } RenderAudioWithWaveform(
mediaUrl = audioMeta.url,
Column(modifier = MaxWidthPaddingTop5dp, horizontalAlignment = Alignment.CenterHorizontally) { title = null,
Row( mimeType = audioMeta.mimeType,
verticalAlignment = Alignment.CenterVertically, waveform = waveform,
) { note = note,
GetMediaItem( accountViewModel = accountViewModel,
videoUri = audioMeta.url, nav = nav,
title = null, )
artworkUri = null,
authorName = note.author?.toBestDisplayName(),
callbackUri = callbackUri,
mimeType = audioMeta.mimeType,
aspectRatio = null,
proxyPort = accountViewModel.httpClientBuilder.proxyPortForVideo(audioMeta.url),
keepPlaying = false,
waveformData = waveform,
) { mediaItem ->
GetVideoController(
mediaItem = mediaItem,
muted = false,
) { controller ->
RenderVoicePlayer(
mediaItem = mediaItem,
controllerState = controller,
waveform = waveform,
borderModifier = MaterialTheme.colorScheme.imageModifier,
accountViewModel = accountViewModel,
)
}
}
}
if (noteEvent.hasHashtags()) {
Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
DisplayUncitedHashtags(noteEvent, callbackUri, accountViewModel, nav)
}
}
}
} }