diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MyAsyncImage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MyAsyncImage.kt index d362caff41..6a866187e9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MyAsyncImage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/MyAsyncImage.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size6dp import com.vitorpamplona.amethyst.commons.ui.theme.Size75dp import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.model.MediaAspectRatioCache +import com.vitorpamplona.amethyst.ui.note.platform.GifVideoView @Composable fun MyAsyncImage( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/CopyNoteText.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/CopyNoteText.kt index d3b727c4c0..ef974d4c6b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/CopyNoteText.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/CopyNoteText.kt @@ -32,13 +32,13 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.copy_text import com.vitorpamplona.amethyst.commons.resources.copy_text_original import com.vitorpamplona.amethyst.commons.resources.copy_text_translated +import com.vitorpamplona.amethyst.commons.ui.components.LocalTranslationPlatform import com.vitorpamplona.amethyst.commons.ui.components.M3ActionDialog import com.vitorpamplona.amethyst.commons.ui.components.M3ActionRow import com.vitorpamplona.amethyst.commons.ui.components.M3ActionSection import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.ui.components.cachedTranslation import com.vitorpamplona.amethyst.ui.note.types.displayedNoteText import kotlinx.coroutines.launch @@ -80,6 +80,7 @@ fun copyNoteTextAction( onDismiss: () -> Unit, ): (note: Note, versionShown: Note) -> Unit { val clipboardManager = LocalClipboard.current + val translator = LocalTranslationPlatform.current val scope = rememberCoroutineScope() val choice = remember { mutableStateOf(null) } @@ -113,7 +114,7 @@ fun copyNoteTextAction( onDismiss() } else { val original = displayedNoteText(note, decrypted) - val translated = cachedTranslation(original, accountViewModel) + val translated = translator.cachedTranslation(original, accountViewModel) if (translated == null) { copy(original) } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index c0354ab756..e40268f832 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -145,6 +145,25 @@ import com.vitorpamplona.amethyst.ui.note.elements.DisplayReward import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton import com.vitorpamplona.amethyst.ui.note.elements.Reward import com.vitorpamplona.amethyst.ui.note.elements.ShowForkInformation +import com.vitorpamplona.amethyst.ui.note.platform.ReactionsRow +import com.vitorpamplona.amethyst.ui.note.platform.RenderAudioHeader +import com.vitorpamplona.amethyst.ui.note.platform.RenderAudioTrack +import com.vitorpamplona.amethyst.ui.note.platform.RenderChessGame +import com.vitorpamplona.amethyst.ui.note.platform.RenderGitIssueEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderGitPatchEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderGitPullRequestEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderGitPullRequestUpdateEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderGitRepositoryEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderLiveChessChallenge +import com.vitorpamplona.amethyst.ui.note.platform.RenderLiveChessGameEnd +import com.vitorpamplona.amethyst.ui.note.platform.RenderMeetingRoomEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderMeetingSpaceEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderMusicTrack +import com.vitorpamplona.amethyst.ui.note.platform.RenderNamedNappletEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderNamedSiteEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderRootNappletEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderRootSiteEvent +import com.vitorpamplona.amethyst.ui.note.platform.RenderVoiceTrack import com.vitorpamplona.amethyst.ui.note.types.BadgeDisplay import com.vitorpamplona.amethyst.ui.note.types.DisplayBlockedRelayList import com.vitorpamplona.amethyst.ui.note.types.DisplayBroadcastRelayList @@ -170,8 +189,6 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderAttestation import com.vitorpamplona.amethyst.ui.note.types.RenderAttestationRequest import com.vitorpamplona.amethyst.ui.note.types.RenderAttestorProficiency import com.vitorpamplona.amethyst.ui.note.types.RenderAttestorRecommendation -import com.vitorpamplona.amethyst.ui.note.types.RenderAudioHeader -import com.vitorpamplona.amethyst.ui.note.types.RenderAudioTrack import com.vitorpamplona.amethyst.ui.note.types.RenderBadgeAward import com.vitorpamplona.amethyst.ui.note.types.RenderBlossomPieceIndex import com.vitorpamplona.amethyst.ui.note.types.RenderBolt12Zap @@ -185,7 +202,6 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderChannelMessage import com.vitorpamplona.amethyst.ui.note.types.RenderChat import com.vitorpamplona.amethyst.ui.note.types.RenderChatMessage import com.vitorpamplona.amethyst.ui.note.types.RenderChatMessageEncryptedFile -import com.vitorpamplona.amethyst.ui.note.types.RenderChessGame import com.vitorpamplona.amethyst.ui.note.types.RenderCitation import com.vitorpamplona.amethyst.ui.note.types.RenderClassifieds import com.vitorpamplona.amethyst.ui.note.types.RenderCommunity @@ -199,26 +215,14 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderFhirResource import com.vitorpamplona.amethyst.ui.note.types.RenderFundraiser import com.vitorpamplona.amethyst.ui.note.types.RenderGeocache import com.vitorpamplona.amethyst.ui.note.types.RenderGeocacheFoundLog -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.RenderGoal import com.vitorpamplona.amethyst.ui.note.types.RenderHighlight import com.vitorpamplona.amethyst.ui.note.types.RenderInteractiveStory import com.vitorpamplona.amethyst.ui.note.types.RenderLearningResource import com.vitorpamplona.amethyst.ui.note.types.RenderLiveActivityChatMessage import com.vitorpamplona.amethyst.ui.note.types.RenderLiveActivityEvent -import com.vitorpamplona.amethyst.ui.note.types.RenderLiveChessChallenge -import com.vitorpamplona.amethyst.ui.note.types.RenderLiveChessGameEnd import com.vitorpamplona.amethyst.ui.note.types.RenderLongFormContent -import com.vitorpamplona.amethyst.ui.note.types.RenderMeetingRoomEvent -import com.vitorpamplona.amethyst.ui.note.types.RenderMeetingSpaceEvent import com.vitorpamplona.amethyst.ui.note.types.RenderMusicPlaylist -import com.vitorpamplona.amethyst.ui.note.types.RenderMusicTrack -import com.vitorpamplona.amethyst.ui.note.types.RenderNamedNappletEvent -import com.vitorpamplona.amethyst.ui.note.types.RenderNamedSiteEvent import com.vitorpamplona.amethyst.ui.note.types.RenderNipContent import com.vitorpamplona.amethyst.ui.note.types.RenderNutzap import com.vitorpamplona.amethyst.ui.note.types.RenderOnchainZap @@ -245,8 +249,6 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderRelayReview import com.vitorpamplona.amethyst.ui.note.types.RenderReport import com.vitorpamplona.amethyst.ui.note.types.RenderRoadEventConfirmation import com.vitorpamplona.amethyst.ui.note.types.RenderRoadEventReport -import com.vitorpamplona.amethyst.ui.note.types.RenderRootNappletEvent -import com.vitorpamplona.amethyst.ui.note.types.RenderRootSiteEvent import com.vitorpamplona.amethyst.ui.note.types.RenderSnoAvatar import com.vitorpamplona.amethyst.ui.note.types.RenderSnoObject import com.vitorpamplona.amethyst.ui.note.types.RenderSnoShard @@ -260,7 +262,6 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderTorrent import com.vitorpamplona.amethyst.ui.note.types.RenderTorrentComment import com.vitorpamplona.amethyst.ui.note.types.RenderVideoCollaboration import com.vitorpamplona.amethyst.ui.note.types.RenderVideoCurationSet -import com.vitorpamplona.amethyst.ui.note.types.RenderVoiceTrack import com.vitorpamplona.amethyst.ui.note.types.RenderWikiContent import com.vitorpamplona.amethyst.ui.note.types.RenderWikiMergeAcceptance import com.vitorpamplona.amethyst.ui.note.types.RenderWikiMergeRequest diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index a08968b31c..a74905f35e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -109,7 +109,6 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.Popup import androidx.compose.ui.window.PopupProperties import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -2061,55 +2060,6 @@ private fun ActionableReactionButton( } } -@Composable -fun RenderReaction(reactionType: String) { - if (reactionType.startsWith(":")) { - val noStartColon = reactionType.removePrefix(":") - val url = noStartColon.substringAfter(":") - - InLineIconRenderer( - persistentListOf( - CustomEmoji.ImageUrlType(url), - ), - style = SpanStyle(color = MaterialTheme.colorScheme.onBackground), - maxLines = 1, - fontSize = 22.sp, - ) - } else { - when (reactionType) { - "+" -> { - LikedIcon(modifier = Size28Modifier) - } - - "-" -> { - Text( - text = "\uD83D\uDC4E", - color = MaterialTheme.colorScheme.onBackground, - maxLines = 1, - fontSize = 22.sp, - ) - } - - else -> { - if (EmojiCoder.isCoded(reactionType)) { - AnimatedBorderTextCornerRadius( - reactionType, - color = MaterialTheme.colorScheme.onBackground, - fontSize = 20.sp, - ) - } else { - Text( - reactionType, - color = MaterialTheme.colorScheme.onBackground, - maxLines = 1, - fontSize = 22.sp, - ) - } - } - } - } -} - @Composable fun ZapAmountChoicePopup( baseNote: Note, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RenderReaction.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RenderReaction.kt new file mode 100644 index 0000000000..efd456cc9d --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RenderReaction.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * 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.ui.note + +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.unit.sp +import com.vitorpamplona.amethyst.commons.emojicoder.EmojiCoder +import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius +import com.vitorpamplona.amethyst.commons.ui.note.LikedIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer +import com.vitorpamplona.amethyst.commons.ui.theme.Size28Modifier +import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun RenderReaction(reactionType: String) { + if (reactionType.startsWith(":")) { + val noStartColon = reactionType.removePrefix(":") + val url = noStartColon.substringAfter(":") + + InLineIconRenderer( + persistentListOf( + CustomEmoji.ImageUrlType(url), + ), + style = SpanStyle(color = MaterialTheme.colorScheme.onBackground), + maxLines = 1, + fontSize = 22.sp, + ) + } else { + when (reactionType) { + "+" -> { + LikedIcon(modifier = Size28Modifier) + } + + "-" -> { + Text( + text = "\uD83D\uDC4E", + color = MaterialTheme.colorScheme.onBackground, + maxLines = 1, + fontSize = 22.sp, + ) + } + + else -> { + if (EmojiCoder.isCoded(reactionType)) { + AnimatedBorderTextCornerRadius( + reactionType, + color = MaterialTheme.colorScheme.onBackground, + fontSize = 20.sp, + ) + } else { + Text( + reactionType, + color = MaterialTheme.colorScheme.onBackground, + maxLines = 1, + fontSize = 22.sp, + ) + } + } + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt index 9f1cd964d2..7439980de7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt @@ -29,7 +29,7 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName +import com.vitorpamplona.amethyst.ui.note.platform.LoadCityName /** * Compact pill showing the geohash a note is scoped to, resolved to a city diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt index f86ec600ad..c4a29b0df5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DropDownMenu.kt @@ -45,9 +45,9 @@ import com.vitorpamplona.amethyst.commons.ui.note.VerticalDotsIcon 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.amethyst.ui.note.QuickActionAlertDialog import com.vitorpamplona.amethyst.ui.note.deletionRequestBody +import com.vitorpamplona.amethyst.ui.note.platform.EditPostView import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.screen.loggedIn.report.ReportNoteDialog import com.vitorpamplona.quartz.nip01Core.tags.aTag.isTaggedAddressableNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayExternalId.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayExternalId.kt index 5affac5616..64d3261100 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayExternalId.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayExternalId.kt @@ -52,7 +52,7 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.ui.components.rememberUrlPreviewState +import com.vitorpamplona.amethyst.ui.note.platform.rememberUrlPreviewState import com.vitorpamplona.quartz.nip73ExternalIds.ExternalId import com.vitorpamplona.quartz.nip73ExternalIds.location.GeohashId import com.vitorpamplona.quartz.nip73ExternalIds.topics.HashtagId diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayGeoHashExternalId.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayGeoHashExternalId.kt index 79ae65091e..49308219ab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayGeoHashExternalId.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayGeoHashExternalId.kt @@ -46,7 +46,7 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName +import com.vitorpamplona.amethyst.ui.note.platform.LoadCityName import com.vitorpamplona.quartz.nip73ExternalIds.location.GeohashId @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/AndroidNotePlatform.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/AndroidNotePlatform.kt index 9664a765ae..9e54e4b016 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/AndroidNotePlatform.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/AndroidNotePlatform.kt @@ -33,6 +33,7 @@ import com.vitorpamplona.amethyst.commons.audio.WaveformData import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.note.types.EditState @@ -45,6 +46,7 @@ import com.vitorpamplona.amethyst.ui.components.GifVideoView as AppGifVideoView import com.vitorpamplona.amethyst.ui.components.LoadUrlPreview as AppLoadUrlPreview import com.vitorpamplona.amethyst.ui.components.ZoomableContentView as AppZoomableContentView import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog as AppZoomableImageDialog +import com.vitorpamplona.amethyst.ui.components.rememberUrlPreviewState as AppRememberUrlPreviewState import com.vitorpamplona.amethyst.ui.note.LikeReaction as AppLikeReaction import com.vitorpamplona.amethyst.ui.note.ReactionsRow as AppReactionsRow import com.vitorpamplona.amethyst.ui.note.ZapReaction as AppZapReaction @@ -52,6 +54,7 @@ import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName as AppL import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap as AppLocationPreviewMap import com.vitorpamplona.amethyst.ui.note.types.PodcastEpisodeAudioPlayer as AppPodcastEpisodeAudioPlayer import com.vitorpamplona.amethyst.ui.note.types.RenderAudioFromIMeta as AppRenderAudioFromIMeta +import com.vitorpamplona.amethyst.ui.note.types.RenderAudioHeader as AppRenderAudioHeader import com.vitorpamplona.amethyst.ui.note.types.RenderAudioTrack as AppRenderAudioTrack import com.vitorpamplona.amethyst.ui.note.types.RenderAudioWithWaveform as AppRenderAudioWithWaveform import com.vitorpamplona.amethyst.ui.note.types.RenderChessGame as AppRenderChessGame @@ -74,6 +77,20 @@ import com.vitorpamplona.amethyst.ui.note.types.RenderVoiceTrack as AppRenderVoi /** Android's [NotePlatform]: the app's own media, map, audio, chess, git, napplet and zap composables. */ object AndroidNotePlatform : NotePlatform { + @Composable + override fun rememberUrlPreviewState( + url: String, + accountViewModel: AccountViewModel, + ): UrlPreviewState = AppRememberUrlPreviewState(url, accountViewModel) + + @Composable + override fun RenderAudioHeader( + note: Note, + contentScale: ContentScale, + accountViewModel: AccountViewModel, + nav: INav, + ) = AppRenderAudioHeader(note, contentScale, accountViewModel, nav) + @Composable override fun ZoomableContentView( content: BaseMediaContent, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatform.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatform.kt index e9202147f7..eaa984fed2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatform.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatform.kt @@ -35,6 +35,7 @@ import com.vitorpamplona.amethyst.commons.audio.WaveformData import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.note.types.EditState @@ -111,6 +112,13 @@ interface NotePlatform { nav: INav?, ) {} + /** The OpenGraph preview of [url], starting from the platform's cache. */ + @Composable + fun rememberUrlPreviewState( + url: String, + accountViewModel: AccountViewModel, + ): UrlPreviewState = UrlPreviewState.Loading + // Places @Composable @@ -133,6 +141,14 @@ interface NotePlatform { // Audio + @Composable + fun RenderAudioHeader( + note: Note, + contentScale: ContentScale, + accountViewModel: AccountViewModel, + nav: INav, + ) {} + @Composable fun RenderAudioTrack( note: Note, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatformCalls.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatformCalls.kt index 5d0b6b65ec..4f260d7e95 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatformCalls.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/platform/NotePlatformCalls.kt @@ -34,6 +34,7 @@ import com.vitorpamplona.amethyst.commons.audio.WaveformData import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.Font14SP import com.vitorpamplona.amethyst.commons.ui.theme.Size14Modifier @@ -536,3 +537,17 @@ fun EditPostView( accountViewModel = accountViewModel, nav = nav, ) + +@Composable +fun rememberUrlPreviewState( + url: String, + accountViewModel: AccountViewModel, +): UrlPreviewState = LocalNotePlatform.current.rememberUrlPreviewState(url, accountViewModel) + +@Composable +fun RenderAudioHeader( + note: Note, + contentScale: ContentScale, + accountViewModel: AccountViewModel, + nav: INav, +) = LocalNotePlatform.current.RenderAudioHeader(note, contentScale, accountViewModel, nav) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt index facefb8d7d..cff4953459 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AppDefinition.kt @@ -117,7 +117,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableImageDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.KindChip import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.kindDisplayName import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.application.SoftwareApplicationEvent diff --git a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioMetaExt.kt similarity index 55% rename from amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioMetaExt.kt index dc5bbf441f..f9afe5e367 100644 --- a/amethyst/src/fdroid/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioMetaExt.kt @@ -18,15 +18,28 @@ * 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.ui.components +package com.vitorpamplona.amethyst.ui.note.types -import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip92IMeta.imetas +import com.vitorpamplona.quartz.nipA0VoiceMessages.AudioMeta /** - * No translation service in this flavor, so no note is ever translated and the copy-text - * menus never need to offer a "Copy Translated" option. + * Extracts AudioMeta from an event's IMeta tags if it has audio content with waveform. + * Returns the first audio IMeta that has a waveform, or null if none found. */ -fun cachedTranslation( - content: String, - accountViewModel: AccountViewModel, -): String? = null +fun Event.getAudioMetaWithWaveform(): AudioMeta? { + val audioMetas = imetas().map { AudioMeta.parse(it) } + return audioMetas.firstOrNull { meta -> + meta.waveform != null && + (meta.mimeType == null || meta.mimeType?.startsWith("audio/") == true) + } +} + +/** + * Checks if the event content is primarily an audio attachment (content is just the audio URL). + */ +fun Event.isAudioOnlyContent(): Boolean { + val audioMeta = getAudioMetaWithWaveform() ?: return false + return content.trim() == audioMeta.url +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt index aab4d90572..4d16826df2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Classifieds.kt @@ -48,8 +48,8 @@ import com.vitorpamplona.amethyst.commons.ui.theme.subtleBorder import com.vitorpamplona.amethyst.commons.util.showAmount import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.AutoNonlazyGrid -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent import com.vitorpamplona.quartz.utils.parseBigDecimalOrNull import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt index 037f54a95e..0fbf32410e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/CommunityHeader.kt @@ -103,12 +103,12 @@ import com.vitorpamplona.amethyst.commons.util.equalImmutableLists import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.note.LikeReaction -import com.vitorpamplona.amethyst.ui.note.ZapReaction import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.note.externalLinkForNote +import com.vitorpamplona.amethyst.ui.note.platform.LikeReaction +import com.vitorpamplona.amethyst.ui.note.platform.ZapReaction import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent import com.vitorpamplona.quartz.nip72ModCommunities.definition.tags.ModeratorTag diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt index 63f3590fc5..ffb54d3d42 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileHeader.kt @@ -33,7 +33,7 @@ import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.ui.components.FileAttachmentCard import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.SensitivityWarning -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip94FileMetadata.FileMetadataEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt index 06c3192b90..4e2b8c845e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FileStorage.kt @@ -35,7 +35,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.LoadNote import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.SensitivityWarning -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.experimental.nip95.header.FileStorageHeaderEvent import com.vitorpamplona.quartz.nip31Alts.alt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Geocache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Geocache.kt index bdc0fcad3f..8755c94273 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Geocache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Geocache.kt @@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.GeocacheFoundLogCard import com.vitorpamplona.amethyst.commons.ui.note.LoadAddressableNote 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.amethyst.ui.note.platform.LocationPreviewMap import com.vitorpamplona.quartz.nip01Core.tags.geohash.toGeoHash import com.vitorpamplona.quartz.nipCCGeocaching.foundLog.GeocacheFoundLogEvent import com.vitorpamplona.quartz.nipCCGeocaching.listing.GeocacheListingEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Library.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Library.kt index 95bd943a9d..38d2ec7514 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Library.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Library.kt @@ -80,8 +80,8 @@ import com.vitorpamplona.amethyst.commons.util.countToHumanReadableBytes import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.experimental.library.BlossomPieceIndexEvent import com.vitorpamplona.quartz.experimental.library.BookshelfDirectoryEvent import com.vitorpamplona.quartz.experimental.library.LearningResourceEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt index 6376c105b5..edfa6a5e86 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt @@ -72,11 +72,11 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.equalImmutableLists import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.commons.viewmodels.mockAccountViewModel -import com.vitorpamplona.amethyst.service.playback.composable.VideoView import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.note.DisplayAuthorBanner import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground +import com.vitorpamplona.amethyst.ui.note.platform.VideoView import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ParticipantTag diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt index d9afde972d..b620b70f68 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PictureDisplay.kt @@ -47,9 +47,9 @@ import com.vitorpamplona.amethyst.ui.components.BlurhashBackdrop import com.vitorpamplona.amethyst.ui.components.BlurhashGridBackdrop import com.vitorpamplona.amethyst.ui.components.ContentWarningGate import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.components.collectContentWarningReasons import com.vitorpamplona.amethyst.ui.components.mediaSizingModifier +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.nip36SensitiveContent.isSensitiveOrNSFW import com.vitorpamplona.quartz.nip68Picture.PictureEvent import kotlinx.collections.immutable.toImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastEpisode.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastEpisode.kt index 3b899ff377..bbe3641a31 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastEpisode.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastEpisode.kt @@ -64,6 +64,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size5dp import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer +import com.vitorpamplona.amethyst.ui.note.platform.PodcastEpisodeAudioPlayer import com.vitorpamplona.quartz.podcasts.PodcastEpisode // Bottom-rounded border on the audio player so it visually butts up against the cover's diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RoadEvent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RoadEvent.kt index 975a11cc4c..015ec9bfa6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RoadEvent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RoadEvent.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.ui.note.RoadEventConfirmationCard import com.vitorpamplona.amethyst.commons.ui.note.RoadEventReportCard -import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap +import com.vitorpamplona.amethyst.ui.note.platform.LocationPreviewMap import com.vitorpamplona.quartz.experimental.roadstr.confirmation.RoadEventConfirmationEvent import com.vitorpamplona.quartz.experimental.roadstr.report.RoadEventReportEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt index 0cfe726665..78ec7ceea1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/SoftwareApp.kt @@ -92,9 +92,9 @@ import com.vitorpamplona.amethyst.commons.util.DecimalPatternFormatter import com.vitorpamplona.amethyst.commons.util.prettyMime import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.model.MediaAspectRatioCache -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView -import com.vitorpamplona.amethyst.ui.note.ReactionsRow import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton +import com.vitorpamplona.amethyst.ui.note.platform.ReactionsRow +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.application.SoftwareApplicationEvent import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.asset.SoftwareAssetEvent import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.release.isNip82SoftwareRelease diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt index aa8063474a..9145ac34de 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.note.ReplyNoteComposition import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.note.nip22Comments.DisplayCommentScope +import com.vitorpamplona.amethyst.ui.note.platform.RenderAudioFromIMeta import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.PreloadThreadForReply import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags import com.vitorpamplona.quartz.nip01Core.tags.people.hasAnyTaggedUser diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt index 895fbc53d8..8a8347e606 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TextModification.kt @@ -61,10 +61,10 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.imageModifier import com.vitorpamplona.amethyst.commons.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.ui.actions.EditPostView import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.note.NoteBody import com.vitorpamplona.amethyst.ui.note.observeEdits +import com.vitorpamplona.amethyst.ui.note.platform.EditPostView import com.vitorpamplona.quartz.experimental.edits.TextNoteModificationEvent import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt index 48c13314dd..703ae5df89 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Video.kt @@ -58,10 +58,10 @@ import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags import com.vitorpamplona.quartz.nip31Alts.alt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VoiceTrack.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VoiceTrack.kt index b55995e9b1..31de26f722 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VoiceTrack.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/VoiceTrack.kt @@ -79,11 +79,8 @@ import com.vitorpamplona.amethyst.ui.components.ShareMediaAction import com.vitorpamplona.amethyst.ui.components.getActivity import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.saveMediaToGallery -import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags import com.vitorpamplona.quartz.nip14Subject.subject -import com.vitorpamplona.quartz.nip92IMeta.imetas -import com.vitorpamplona.quartz.nipA0VoiceMessages.AudioMeta import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent @Composable @@ -321,26 +318,6 @@ fun PlayPauseButton(controllerState: MediaControllerState) { } } -/** - * Extracts AudioMeta from an event's IMeta tags if it has audio content with waveform. - * Returns the first audio IMeta that has a waveform, or null if none found. - */ -fun Event.getAudioMetaWithWaveform(): AudioMeta? { - val audioMetas = imetas().map { AudioMeta.parse(it) } - return audioMetas.firstOrNull { meta -> - meta.waveform != null && - (meta.mimeType == null || meta.mimeType?.startsWith("audio/") == true) - } -} - -/** - * Checks if the event content is primarily an audio attachment (content is just the audio URL). - */ -fun Event.isAudioOnlyContent(): Boolean { - val audioMeta = getAudioMetaWithWaveform() ?: return false - return content.trim() == audioMeta.url -} - /** * Renders audio with waveform for any event type that has audio IMeta attachment. * This allows KIND 1 (TextNoteEvent) and KIND 1111 (CommentEvent) with voice diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatClip.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatClip.kt index 08b267c218..b5e2a7cd3d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatClip.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatClip.kt @@ -46,8 +46,8 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel -import com.vitorpamplona.amethyst.service.playback.composable.VideoView import com.vitorpamplona.amethyst.ui.note.CrossfadeToDisplayComment +import com.vitorpamplona.amethyst.ui.note.platform.VideoView import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderEncryptedFile.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderEncryptedFile.kt index 72da6ac804..40e243b612 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderEncryptedFile.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderEncryptedFile.kt @@ -41,8 +41,8 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView -import com.vitorpamplona.amethyst.ui.note.types.RenderAudioWithWaveform +import com.vitorpamplona.amethyst.ui.note.platform.RenderAudioWithWaveform +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.utils.ciphers.AESGCM diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/ShortPublicChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/ShortPublicChatChannelHeader.kt index 4e6e5f623e..8c8f19f03a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/ShortPublicChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/ShortPublicChatChannelHeader.kt @@ -53,8 +53,8 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel -import com.vitorpamplona.amethyst.ui.note.LikeReaction -import com.vitorpamplona.amethyst.ui.note.ZapReaction +import com.vitorpamplona.amethyst.ui.note.platform.LikeReaction +import com.vitorpamplona.amethyst.ui.note.platform.ZapReaction @Composable fun ShortPublicChatChannelHeader( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/ShowVideoStreaming.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/ShowVideoStreaming.kt index aaa001c830..02eee9710a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/ShowVideoStreaming.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/ShowVideoStreaming.kt @@ -34,7 +34,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StreamingHeaderModifier import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannelInfo import com.vitorpamplona.amethyst.ui.components.SensitivityWarning -import com.vitorpamplona.amethyst.ui.components.ZoomableContentView +import com.vitorpamplona.amethyst.ui.note.platform.ZoomableContentView @Composable fun ShowVideoStreaming( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/ShortLiveActivityChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/ShortLiveActivityChannelHeader.kt index 38bead47c6..b6257e88c6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/ShortLiveActivityChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/ShortLiveActivityChannelHeader.kt @@ -50,8 +50,8 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel -import com.vitorpamplona.amethyst.ui.note.LikeReaction -import com.vitorpamplona.amethyst.ui.note.ZapReaction +import com.vitorpamplona.amethyst.ui.note.platform.LikeReaction +import com.vitorpamplona.amethyst.ui.note.platform.ZapReaction import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt index b1f912902a..9b2f8ce4c2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt @@ -58,10 +58,10 @@ import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel import com.vitorpamplona.amethyst.commons.viewmodels.mockAccountViewModel import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.note.GalleryUnloaded -import com.vitorpamplona.amethyst.ui.note.LikeReaction -import com.vitorpamplona.amethyst.ui.note.ZapReaction import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageBanner import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageBannerBackground +import com.vitorpamplona.amethyst.ui.note.platform.LikeReaction +import com.vitorpamplona.amethyst.ui.note.platform.ZapReaction import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip51Lists.starterPack.StarterPackEvent import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTrailerListItem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTrailerListItem.kt index eed71d64c1..e7739b8adc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTrailerListItem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTrailerListItem.kt @@ -48,7 +48,7 @@ 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.amethyst.ui.note.platform.PodcastEpisodeAudioPlayer import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent import com.vitorpamplona.quartz.podcasts.PodcastAudio diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt index 05b8719165..d4fea19cf7 100644 --- a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/CachedTranslation.kt @@ -28,9 +28,9 @@ import com.vitorpamplona.amethyst.service.lang.TranslationsCache * when no translation occurred (same language, undetected source, blocklisted) or none is * cached. Cache-only on purpose: this backs the "Copy Translated" option of the copy-text * menus, which only applies to text the user is looking at — and rendering it through - * [TranslatableRichTextViewer] is what populated the cache. + * [MlKitTranslationPlatform] is what populated the cache. */ -fun cachedTranslation( +internal fun cachedMlKitTranslation( content: String, accountViewModel: AccountViewModel, ): String? { diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/MlKitTranslationPlatform.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/MlKitTranslationPlatform.kt index 6060d89314..16801a66e0 100644 --- a/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/MlKitTranslationPlatform.kt +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/ui/components/MlKitTranslationPlatform.kt @@ -59,6 +59,11 @@ object MlKitTranslationPlatform : TranslationPlatform { content: String, accountViewModel: AccountViewModel, ): String = rememberMlKitTranslation(content, accountViewModel) + + override fun cachedTranslation( + content: String, + accountViewModel: AccountViewModel, + ): String? = cachedMlKitTranslation(content, accountViewModel) } val FlavorTranslationPlatform: TranslationPlatform = MlKitTranslationPlatform diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/TranslationPlatform.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/TranslationPlatform.kt index 4f8ccedfe1..6b8ebfb71b 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/TranslationPlatform.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/TranslationPlatform.kt @@ -53,6 +53,16 @@ interface TranslationPlatform { accountViewModel: AccountViewModel, ): String + /** + * The already-computed translation of [content] under the current settings, or null when + * none occurred or none is cached. Cache-only: it backs "Copy Translated", which applies + * to text on screen, and rendering that text through [Translatable] filled the cache. + */ + fun cachedTranslation( + content: String, + accountViewModel: AccountViewModel, + ): String? = null + /** No translator: the content is always its own translation. */ object None : TranslationPlatform { @Composable