refactor: reach the media player only through NotePlatform slots

Screens and feed composables called the app's player and media
renderers directly, around the NotePlatform slots that already exist
for them. Twenty-three screens reached media3 that way, mostly through
EditPostView.

- The chat action sheet and bookmark options open the EditPostView slot;
  EditPostView and the composer previews use the VideoView and
  LoadUrlPreview slots.
- The thread view, pictures, shorts, file-metadata and video cards, Cordn,
  Marmot media, group-DM preview, profile header and banner, URL screen,
  geocache and relay-group screens, podcast list and chat text notes call
  the ZoomableContentView, ZoomableImageDialog, rememberUrlPreviewState,
  LocationPreviewMap, PodcastEpisodeAudioPlayer, RenderAudio*, RenderGit*,
  RenderMusicTrack, Render*SiteEvent and RenderVoiceTrack slots.
- New FullscreenVideoView slot for the Blossom blob viewer, which reached
  into the internal VideoViewInner.
- LocationPreviewMap's slot takes the modifier and an optional zoom the
  map callers pass.
- syntheticWaveformFor (pure) moves to commons.audio.

Only the platform side (AndroidNotePlatform, the renderers behind the
slots, the zoom dialog, AppModules, MainActivity) imports playback now,
and no screen reaches it. The media3 engine stays in the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S7FuNBSKiyVecARSoE4B9P
This commit is contained in:
Claude
2026-09-29 22:39:46 +00:00
parent d87ed81242
commit 0bdada5e41
28 changed files with 100 additions and 52 deletions
@@ -89,6 +89,8 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar
import com.vitorpamplona.amethyst.commons.ui.note.NoteCompose
import com.vitorpamplona.amethyst.commons.ui.note.creators.invoice.AddLnInvoiceButton
import com.vitorpamplona.amethyst.commons.ui.note.creators.userSuggestions.ShowUserSuggestionList
import com.vitorpamplona.amethyst.commons.ui.note.platform.LoadUrlPreview
import com.vitorpamplona.amethyst.commons.ui.note.platform.VideoView
import com.vitorpamplona.amethyst.commons.ui.note.types.ReplyRenderType
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.text.MentionPreservingInputTransformation
@@ -102,8 +104,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText
import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier
import com.vitorpamplona.amethyst.commons.ui.theme.subtleBorder
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.service.playback.composable.VideoView
import com.vitorpamplona.amethyst.ui.components.LoadUrlPreview
import com.vitorpamplona.amethyst.ui.note.creators.invoice.InvoiceRequest
import com.vitorpamplona.amethyst.ui.note.creators.uploads.ImageVideoDescription
import kotlinx.coroutines.delay
@@ -131,13 +131,13 @@ import com.vitorpamplona.amethyst.commons.resources.retry
import com.vitorpamplona.amethyst.commons.ui.components.util.setText
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton
import com.vitorpamplona.amethyst.commons.ui.note.platform.FullscreenVideoView
import com.vitorpamplona.amethyst.commons.ui.platform.AppBottomBar
import com.vitorpamplona.amethyst.commons.ui.pluralStringRes
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.theme.allGoodColor
import com.vitorpamplona.amethyst.commons.ui.theme.grayText
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.service.playback.composable.VideoViewInner
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip56Reports.ReportType
import kotlinx.coroutines.launch
@@ -535,15 +535,13 @@ private fun BlossomBlobViewer(
if (url != null && isVideo) {
val controllerVisible = remember { mutableStateOf(true) }
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
VideoViewInner(
FullscreenVideoView(
videoUri = url,
mimeType = row.type,
contentScale = ContentScale.Fit,
borderModifier = Modifier.fillMaxWidth(),
automaticallyStartPlayback = true,
controllerVisible = controllerVisible,
isFullscreen = true,
accountViewModel = accountViewModel,
modifier = Modifier.fillMaxWidth(),
)
}
} else if (url != null) {
@@ -47,8 +47,8 @@ import org.osmdroid.views.CustomZoomButtonsController
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.Marker
/** Default close-up zoom for a single pinned location (street-level). */
private const val DEFAULT_ZOOM = 16.0
/** Default close-up zoom for a single pinned location (street-level), when the caller picks none. */
const val DEFAULT_MAP_ZOOM = 16.0
/**
* Night-mode filter for the (always-light) MAPNIK tiles so the map follows the
@@ -145,7 +145,7 @@ fun LocationPreviewMap(
latitude: Double,
longitude: Double,
modifier: Modifier = Modifier,
zoom: Double = DEFAULT_ZOOM,
zoom: Double = DEFAULT_MAP_ZOOM,
aspectRatio: Float = 1f,
pinColor: Color? = null,
pinEmoji: String? = null,
@@ -50,10 +50,10 @@ import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState
import com.vitorpamplona.amethyst.commons.ui.components.WaitAndDisplay
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.NoteCompose
import com.vitorpamplona.amethyst.commons.ui.note.platform.VideoView
import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
import com.vitorpamplona.amethyst.service.playback.composable.VideoView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.urlPreview
@Composable
@@ -79,7 +79,6 @@ fun PreviewUrl(
myUrlPreview,
mimeType = null,
roundedCorner = false,
gallery = false,
contentScale = ContentScale.FillHeight,
accountViewModel = accountViewModel,
)
@@ -133,7 +132,6 @@ fun PreviewUrlFillWidth(
myUrlPreview,
mimeType = null,
roundedCorner = false,
gallery = false,
contentScale = ContentScale.FillWidth,
accountViewModel = accountViewModel,
)
@@ -233,7 +231,6 @@ private fun MyLoadUrlPreviewDirect(
state.previewInfo.url,
mimeType = state.previewInfo.mimeType,
roundedCorner = false,
gallery = false,
contentScale = ContentScale.Crop,
accountViewModel = accountViewModel,
)
@@ -301,7 +298,6 @@ private fun MyLoadUrlPreviewDirectFillWidth(
state.previewInfo.url,
mimeType = state.previewInfo.mimeType,
roundedCorner = false,
gallery = false,
contentScale = ContentScale.FillWidth,
accountViewModel = accountViewModel,
)
@@ -41,6 +41,8 @@ import com.vitorpamplona.amethyst.commons.ui.note.platform.NotePlatform
import com.vitorpamplona.amethyst.commons.ui.note.types.EditState
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
import com.vitorpamplona.amethyst.service.playback.composable.VideoViewInner
import com.vitorpamplona.amethyst.ui.note.creators.location.DEFAULT_MAP_ZOOM
import com.vitorpamplona.amethyst.ui.screen.loggedIn.urlPreview
import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag
import com.vitorpamplona.quartz.podcasts.PodcastAudio
@@ -206,9 +208,13 @@ object AndroidNotePlatform : NotePlatform {
pinColor: Color?,
pinEmoji: String?,
pinAlpha: Float,
modifier: Modifier,
zoom: Double?,
) = AppLocationPreviewMap(
latitude = latitude,
longitude = longitude,
modifier = modifier,
zoom = zoom ?: DEFAULT_MAP_ZOOM,
aspectRatio = aspectRatio,
pinColor = pinColor,
pinEmoji = pinEmoji,
@@ -596,6 +602,25 @@ object AndroidNotePlatform : NotePlatform {
callbacks: ZapButtonCallbacks,
) = AppReusableZapButton(baseNote, accountViewModel, nav, config, callbacks)
@Composable
override fun FullscreenVideoView(
videoUri: String,
mimeType: String?,
contentScale: ContentScale,
modifier: Modifier,
controllerVisible: MutableState<Boolean>,
accountViewModel: AccountViewModel,
) = VideoViewInner(
videoUri = videoUri,
mimeType = mimeType,
contentScale = contentScale,
borderModifier = modifier,
automaticallyStartPlayback = true,
controllerVisible = controllerVisible,
isFullscreen = true,
accountViewModel = accountViewModel,
)
@Composable
override fun EditPostView(
onClose: () -> Unit,
@@ -52,6 +52,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.commons.audio.syntheticWaveformFor
import com.vitorpamplona.amethyst.commons.icons.symbols.Icon
import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols
import com.vitorpamplona.amethyst.commons.model.Note
@@ -81,7 +82,6 @@ import com.vitorpamplona.amethyst.service.playback.composable.LoadThumbAndThenVi
import com.vitorpamplona.amethyst.service.playback.composable.PauseControllerWhenInBackground
import com.vitorpamplona.amethyst.service.playback.composable.VideoView
import com.vitorpamplona.amethyst.service.playback.composable.mediaitem.GetMediaItem
import com.vitorpamplona.amethyst.service.playback.composable.wavefront.syntheticWaveformFor
import com.vitorpamplona.quartz.experimental.music.track.MusicTrackEvent
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
@@ -30,6 +30,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.vitorpamplona.amethyst.commons.audio.WaveformData
import com.vitorpamplona.amethyst.commons.audio.syntheticWaveformFor
import com.vitorpamplona.amethyst.commons.model.Note
import com.vitorpamplona.amethyst.commons.ui.note.PodcastSoundbites
import com.vitorpamplona.amethyst.commons.ui.note.types.PodcastChaptersView
@@ -38,7 +39,6 @@ import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.service.playback.composable.GetVideoController
import com.vitorpamplona.amethyst.service.playback.composable.PauseControllerWhenInBackground
import com.vitorpamplona.amethyst.service.playback.composable.mediaitem.GetMediaItem
import com.vitorpamplona.amethyst.service.playback.composable.wavefront.syntheticWaveformFor
import com.vitorpamplona.quartz.podcasts.PodcastAudio
import com.vitorpamplona.quartz.podcasts.PodcastEpisode
@@ -37,8 +37,8 @@ import com.vitorpamplona.amethyst.commons.ui.components.BlurhashBackdrop
import com.vitorpamplona.amethyst.commons.ui.components.ContentWarningGate
import com.vitorpamplona.amethyst.commons.ui.components.collectContentWarningReasons
import com.vitorpamplona.amethyst.commons.ui.components.mediaSizingModifier
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip31Alts.alt
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
@@ -67,12 +67,12 @@ import com.vitorpamplona.amethyst.commons.ui.note.copyNoteTextAction
import com.vitorpamplona.amethyst.commons.ui.note.elements.DropDownParams
import com.vitorpamplona.amethyst.commons.ui.note.elements.observeBookmarksFollowsAndAccount
import com.vitorpamplona.amethyst.commons.ui.note.externalLinkForNote
import com.vitorpamplona.amethyst.commons.ui.note.platform.EditPostView
import com.vitorpamplona.amethyst.commons.ui.note.types.EditState
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.report.ReportNoteDialog
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.theme.Size24Modifier
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.actions.EditPostView
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip23LongContent.LongFormContentEvent
import kotlinx.coroutines.Dispatchers
@@ -112,6 +112,7 @@ import com.vitorpamplona.amethyst.commons.ui.loadStringRes
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.NonClickableUserPictures
import com.vitorpamplona.amethyst.commons.ui.note.UserPicture
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.ui.pluralStringRes
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.chats.feed.types.observeUserNameByHex
import com.vitorpamplona.amethyst.commons.ui.stringRes
@@ -122,7 +123,6 @@ import com.vitorpamplona.amethyst.model.cordn.CordnMediaService
import com.vitorpamplona.amethyst.service.uploads.MetadataStripper
import com.vitorpamplona.amethyst.ui.actions.uploads.RecordingResult
import com.vitorpamplona.amethyst.ui.actions.uploads.VoiceMessageRecorder
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.note.types.RenderAudioWaveformPlayer
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.ChatFileUploadDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.ChatFileUploadState
@@ -92,6 +92,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.elements.NoteActionHandlers
import com.vitorpamplona.amethyst.commons.ui.note.elements.ShareOptionsBottomSheet
import com.vitorpamplona.amethyst.commons.ui.note.elements.noteActionSections
import com.vitorpamplona.amethyst.commons.ui.note.elements.observeBookmarksFollowsAndAccount
import com.vitorpamplona.amethyst.commons.ui.note.platform.EditPostView
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.report.ReportNoteDialog
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.wallet.OnchainZapSendDialog
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.wallet.navigateToReloadMint
@@ -103,7 +104,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText
import com.vitorpamplona.amethyst.commons.ui.theme.reactionBox
import com.vitorpamplona.amethyst.commons.ui.theme.selectedReactionBoxModifier
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.actions.EditPostView
import com.vitorpamplona.amethyst.ui.note.ZapAmountChoiceGrid
import com.vitorpamplona.amethyst.ui.note.observeZapRailCapability
import com.vitorpamplona.amethyst.ui.note.payViaIntentOrManualSplit
@@ -38,10 +38,10 @@ import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlVideo
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
import com.vitorpamplona.amethyst.commons.ui.components.TranslatableRichTextViewer
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderAudioWithWaveform
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.note.types.RenderAudioWithWaveform
import com.vitorpamplona.quartz.marmot.appComponents.EncryptedMediaPolicyV2
import com.vitorpamplona.quartz.marmot.appComponents.EncryptedMediaReferenceV2
import com.vitorpamplona.quartz.marmot.appComponents.EncryptedMediaV2
@@ -38,10 +38,10 @@ import com.vitorpamplona.amethyst.commons.ui.components.SensitivityWarning
import com.vitorpamplona.amethyst.commons.ui.components.TranslatableRichTextViewer
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.LoadDecryptedContentOrNull
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderAudioFromIMeta
import com.vitorpamplona.amethyst.commons.ui.note.types.getAudioMetaWithWaveform
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.note.types.RenderAudioFromIMeta
@Composable
fun RenderRegularTextNote(
@@ -108,6 +108,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.creators.userSuggestions.ShowU
import com.vitorpamplona.amethyst.commons.ui.note.creators.zapraiser.AddZapraiserButton
import com.vitorpamplona.amethyst.commons.ui.note.creators.zapraiser.ZapRaiserRequest
import com.vitorpamplona.amethyst.commons.ui.note.creators.zapsplits.ForwardZapToButton
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.text.MentionPreservingInputTransformation
import com.vitorpamplona.amethyst.commons.ui.text.onUiThread
@@ -124,7 +125,6 @@ import com.vitorpamplona.amethyst.ui.actions.UrlUserTagOutputTransformation
import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton
import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton
import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.navigation.navs.Nav
import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList
import com.vitorpamplona.amethyst.ui.note.creators.expiration.ExpirationDatePicker
@@ -109,12 +109,12 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar
import com.vitorpamplona.amethyst.commons.ui.note.platform.LoadCityName
import com.vitorpamplona.amethyst.commons.ui.note.platform.LocationPreviewMap
import com.vitorpamplona.amethyst.commons.ui.platform.GeohashLocationPickerDialog
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.chats.publicChannels.relayGroup.LoadRelayGroupChannel
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupCardWarmupSubscription
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHash
import com.vitorpamplona.quartz.nip29RelayGroups.GroupId
@@ -104,11 +104,11 @@ import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.geocacheEmoji
import com.vitorpamplona.amethyst.commons.ui.note.geocacheLabelRes
import com.vitorpamplona.amethyst.commons.ui.note.platform.LocationPreviewMap
import com.vitorpamplona.amethyst.commons.ui.platform.GeohashLocationPickerDialog
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.qrcode.QrCodeDrawer
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap
import com.vitorpamplona.quartz.nip01Core.tags.geohash.toGeoHash
import com.vitorpamplona.quartz.nipCCGeocaching.listing.GeocacheGeohash
import com.vitorpamplona.quartz.nipCCGeocaching.listing.tags.CacheSize
@@ -98,13 +98,13 @@ import com.vitorpamplona.amethyst.commons.ui.note.GeocacheSpoilerHint
import com.vitorpamplona.amethyst.commons.ui.note.forListing
import com.vitorpamplona.amethyst.commons.ui.note.geocacheEmoji
import com.vitorpamplona.amethyst.commons.ui.note.geocachePoint
import com.vitorpamplona.amethyst.commons.ui.note.platform.LocationPreviewMap
import com.vitorpamplona.amethyst.commons.ui.note.rememberGeocachePalette
import com.vitorpamplona.amethyst.commons.ui.note.specSummary
import com.vitorpamplona.amethyst.commons.ui.note.types.distanceToCache
import com.vitorpamplona.amethyst.commons.ui.screen.loggedIn.geocaches.datasource.GeocachesFilterAssemblerSubscription
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nipCCGeocaching.listing.GeocacheListingEvent
import com.vitorpamplona.quartz.nipCCGeocaching.listing.tags.TypeModifier
@@ -50,8 +50,8 @@ import com.vitorpamplona.amethyst.commons.ui.components.collectContentWarningRea
import com.vitorpamplona.amethyst.commons.ui.components.mediaSizingModifier
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.platform.ReactionsRow
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.UserCardHeader
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
import com.vitorpamplona.quartz.nip68Picture.PictureEvent
@@ -44,6 +44,7 @@ import com.vitorpamplona.amethyst.commons.resources.podcast_season
import com.vitorpamplona.amethyst.commons.resources.podcast_season_episode
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.navigation.routes.routeFor
import com.vitorpamplona.amethyst.commons.ui.note.platform.PodcastEpisodeAudioPlayer
import com.vitorpamplona.amethyst.commons.ui.note.platform.ReactionsRow
import com.vitorpamplona.amethyst.commons.ui.note.rememberTimeAgoLabels
import com.vitorpamplona.amethyst.commons.ui.note.timeAgoWith
@@ -51,7 +52,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.theme.Size5dp
import com.vitorpamplona.amethyst.commons.ui.theme.grayText
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.note.types.PodcastEpisodeAudioPlayer
import com.vitorpamplona.quartz.podcasts.PodcastEpisode
private val PLAYER_SHAPE = Modifier.clip(RoundedCornerShape(12.dp))
@@ -46,10 +46,10 @@ import com.vitorpamplona.amethyst.commons.resources.profile_banner
import com.vitorpamplona.amethyst.commons.resources.profile_image
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
import com.vitorpamplona.amethyst.commons.ui.components.util.setText
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableImageDialog
import com.vitorpamplona.amethyst.commons.ui.painterRes
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog
import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class)
@@ -64,13 +64,13 @@ import com.vitorpamplona.amethyst.commons.ui.actions.uploads.GallerySelectSingle
import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.ClickableUserPicture
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableImageDialog
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.theme.Size100dp
import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp
import com.vitorpamplona.amethyst.commons.ui.theme.userProfileBorderModifier
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.commons.viewmodels.UserExternalIdentitiesViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog
import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.apps.UserAppRecommendationsFeedViewModel
import kotlinx.coroutines.launch
@@ -52,8 +52,8 @@ import com.vitorpamplona.amethyst.commons.ui.components.collectContentWarningRea
import com.vitorpamplona.amethyst.commons.ui.components.mediaSizingModifier
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.platform.ReactionsRow
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.UserCardHeader
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip31Alts.alt
@@ -144,6 +144,18 @@ import com.vitorpamplona.amethyst.commons.ui.note.elements.TimeAgoStyle
import com.vitorpamplona.amethyst.commons.ui.note.nip22Comments.DisplayCommentScope
import com.vitorpamplona.amethyst.commons.ui.note.observeEdits
import com.vitorpamplona.amethyst.commons.ui.note.platform.ReactionsRow
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderAudioHeader
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderAudioTrack
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderGitIssueEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderGitPatchEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderGitPullRequestEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderGitPullRequestUpdateEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderGitRepositoryEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderMusicTrack
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderNamedSiteEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderRootSiteEvent
import com.vitorpamplona.amethyst.commons.ui.note.platform.RenderVoiceTrack
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.ui.note.types.BadgeDisplay
import com.vitorpamplona.amethyst.commons.ui.note.types.DisplayBlockedRelayList
import com.vitorpamplona.amethyst.commons.ui.note.types.DisplayBroadcastRelayList
@@ -261,18 +273,6 @@ import com.vitorpamplona.amethyst.commons.util.showAmount
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.commons.viewmodels.mockAccountViewModel
import com.vitorpamplona.amethyst.commons.viewmodels.thread.LevelFeedViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.amethyst.ui.note.types.AudioHeader
import com.vitorpamplona.amethyst.ui.note.types.AudioTrackHeader
import com.vitorpamplona.amethyst.ui.note.types.RenderGitIssueEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderGitPatchEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderGitPullRequestEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderGitPullRequestUpdateEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderGitRepositoryEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderMusicTrack
import com.vitorpamplona.amethyst.ui.note.types.RenderNamedSiteEvent
import com.vitorpamplona.amethyst.ui.note.types.RenderRootSiteEvent
import com.vitorpamplona.amethyst.ui.note.types.VoiceHeader
import com.vitorpamplona.quartz.cyberspace.CyberspaceBagEvent
import com.vitorpamplona.quartz.cyberspace.deck0003Sno.SnoAvatarEvent
import com.vitorpamplona.quartz.cyberspace.deck0003Sno.SnoObjectEvent
@@ -894,7 +894,7 @@ private fun FullBleedNoteCompose(
} else if (noteEvent is WorkoutRecordEvent) {
WorkoutDisplay(baseNote, backgroundColor, canPreview = true, quotesLeft = 3, accountViewModel = accountViewModel, nav = nav)
} else if (noteEvent is BaseVoiceEvent) {
VoiceHeader(noteEvent, baseNote, accountViewModel, nav)
RenderVoiceTrack(baseNote, accountViewModel, nav)
} else if (noteEvent is FileMetadataEvent) {
FileMetadataDisplay(baseNote, roundedCorner = true, ContentScale.FillWidth, accountViewModel = accountViewModel)
} else if (noteEvent is FileStorageHeaderEvent) {
@@ -906,9 +906,9 @@ private fun FullBleedNoteCompose(
} else if (noteEvent is ContactListEvent) {
DisplayContactList(baseNote, accountViewModel, nav)
} else if (noteEvent is AudioTrackEvent) {
AudioTrackHeader(noteEvent, baseNote, ContentScale.FillWidth, accountViewModel, nav)
RenderAudioTrack(baseNote, ContentScale.FillWidth, accountViewModel, nav)
} else if (noteEvent is AudioHeaderEvent) {
AudioHeader(noteEvent, baseNote, ContentScale.FillWidth, accountViewModel, nav)
RenderAudioHeader(baseNote, ContentScale.FillWidth, accountViewModel, nav)
} else if (noteEvent is MusicTrackEvent) {
RenderMusicTrack(baseNote, makeItShort = false, canPreview = true, backgroundColor, accountViewModel, nav)
} else if (noteEvent is MusicPlaylistEvent) {
@@ -38,11 +38,11 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarP
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton
import com.vitorpamplona.amethyst.commons.ui.note.nip22Comments.LocalCurrentExternalScope
import com.vitorpamplona.amethyst.commons.ui.note.platform.rememberUrlPreviewState
import com.vitorpamplona.amethyst.commons.ui.screen.RefresheableFeedView
import com.vitorpamplona.amethyst.commons.ui.stringRes
import com.vitorpamplona.amethyst.commons.ui.theme.MaxWidthWithHorzPadding
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.rememberUrlPreviewState
import com.vitorpamplona.amethyst.ui.screen.loggedIn.url.dal.UrlFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.url.datasource.UrlFilterAssemblerSubscription
import com.vitorpamplona.quartz.nip73ExternalIds.urls.UrlId
@@ -46,10 +46,10 @@ import com.vitorpamplona.amethyst.commons.ui.components.collectContentWarningRea
import com.vitorpamplona.amethyst.commons.ui.components.mediaSizingModifier
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.commons.ui.note.platform.ReactionsRow
import com.vitorpamplona.amethyst.commons.ui.note.platform.ZoomableContentView
import com.vitorpamplona.amethyst.commons.ui.note.types.FileMetadataAttachmentCard
import com.vitorpamplona.amethyst.commons.ui.note.types.toMediaContent
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW
import com.vitorpamplona.quartz.nip94FileMetadata.FileMetadataEvent
@@ -18,9 +18,8 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.amethyst.service.playback.composable.wavefront
package com.vitorpamplona.amethyst.commons.audio
import com.vitorpamplona.amethyst.commons.audio.WaveformData
import kotlin.math.PI
import kotlin.math.sin
import kotlin.random.Random
@@ -106,6 +106,20 @@ interface NotePlatform {
accountViewModel: AccountViewModel,
) {}
/**
* A video filling a full-screen viewer, playing at once. [controllerVisible] shows and hides
* its playback controls, so the viewer can toggle them with its own chrome.
*/
@Composable
fun FullscreenVideoView(
videoUri: String,
mimeType: String?,
contentScale: ContentScale,
modifier: Modifier,
controllerVisible: MutableState<Boolean>,
accountViewModel: AccountViewModel,
) {}
/** The link card for [url]: OpenGraph preview, inline media, or a plain link. */
@Composable
fun UrlPreview(
@@ -142,6 +156,8 @@ interface NotePlatform {
pinColor: Color?,
pinEmoji: String?,
pinAlpha: Float,
modifier: Modifier,
zoom: Double?,
) {}
/** Resolves [geohashStr] to a place name for [content], showing [onLoading] meanwhile. */
@@ -107,6 +107,16 @@ fun GifVideoView(
thumbhash = thumbhash,
)
@Composable
fun FullscreenVideoView(
videoUri: String,
mimeType: String?,
contentScale: ContentScale,
controllerVisible: MutableState<Boolean>,
accountViewModel: AccountViewModel,
modifier: Modifier = Modifier,
) = LocalNotePlatform.current.FullscreenVideoView(videoUri, mimeType, contentScale, modifier, controllerVisible, accountViewModel)
@Composable
fun VideoView(
videoUri: String,
@@ -151,6 +161,8 @@ fun LoadUrlPreview(
fun LocationPreviewMap(
latitude: Double,
longitude: Double,
modifier: Modifier = Modifier,
zoom: Double? = null,
aspectRatio: Float = 1f,
pinColor: Color? = null,
pinEmoji: String? = null,
@@ -162,6 +174,8 @@ fun LocationPreviewMap(
pinColor = pinColor,
pinEmoji = pinEmoji,
pinAlpha = pinAlpha,
modifier = modifier,
zoom = zoom,
)
@Composable