From 0a5aed7ec5f819f9cbe1c07345f1dd85ca7a6954 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 23 Sep 2026 22:59:42 +0000 Subject: [PATCH 1/9] refactor: share the user avatar image, score tags and metadata observers The avatar is the second most common dependency of the app's composables (after AccountViewModel). This moves its rendering and the observers under it into commonsUI, leaving the app with the settings/account reads. - Observers: the app's observeUserInfo, observeUserAboutMe, observeUserBanner and observeUserPicture were copies of the commonsUI relayClient/user ones, and its UserFinderFilterAssemblerSubscription (user, Account, dataSource) a copy of the shared subscription. They now delegate, keeping their signatures so no call site changes. The shared observeUserPicture gains the app's `subscribe` flag. observeUserName stays app-side: it applies the account's contact-card petname. (The shared subscription remembers per user *and* account, so an account switch no longer reuses the previous account's query state.) - ScoreTag / ScoreTagRegular / Small / Smallest move to ui/note. - RobohashAsyncImage, RobohashFallbackAsyncImage and GifProfilePicture move to commonsUI jvmAndroid ui/components (they tag requests with the jvmAndroid-only LocalBlossomCacheRedirectInterceptor header). The one Android API, starting/stopping an animated avatar's Animatable drawable, becomes AnimatedImageAutoPlay: an expect in jvmAndroid with the Android actual and a desktop no-op. The Coil request uses LocalPlatformContext instead of LocalContext. - isAnimatedMediaUrl, a pure URL check, moves to commons richtext. - UserPictureImage(userHex, picture, name, size, modifier, loadProfilePicture, loadRobohash, autoPlayGif) in commonsUI jvmAndroid ui/note is the display half of InnerUserPicture, which keeps reading the three settings. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../consent/ConnectedAccountRow.kt | 2 +- .../consent/SignerConsentActivity.kt | 2 +- .../napplet/NappletConsentActivity.kt | 2 +- .../compose/RelayAuthPromptHost.kt | 2 +- .../UserFinderFilterAssemblerSubscription.kt | 12 +- .../reqCommand/user/UserObservers.kt | 96 ++------------ .../ui/components/ConcordInviteCard.kt | 1 + .../amethyst/ui/components/MyAsyncImage.kt | 9 +- .../amethyst/ui/components/RelayGroupCard.kt | 1 + .../bottombars/GroupBottomBarEntries.kt | 2 +- .../drawer/AccountSwitchBottomSheet.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 2 +- .../topbars/UserDrawerSearchTopBar.kt | 2 +- .../amethyst/ui/note/MultiSetCompose.kt | 3 +- .../amethyst/ui/note/NoteCompose.kt | 2 +- .../amethyst/ui/note/RelayListRow.kt | 2 +- .../amethyst/ui/note/UserProfilePicture.kt | 118 ++--------------- .../amethyst/ui/note/types/Badge.kt | 2 +- .../amethyst/ui/note/types/CommunityHeader.kt | 2 +- .../amethyst/ui/note/types/PodcastPeople.kt | 2 +- .../ui/note/types/RelayGroupMessage.kt | 2 +- .../ProfileAppRecommendationsScreen.kt | 2 +- .../backups/BackupConflictEventViews.kt | 2 +- .../backups/BackupConflictListViews.kt | 2 +- .../badges/profile/ProfileBadgesScreen.kt | 2 +- .../chats/geohashChat/GeohashChatScreen.kt | 2 +- .../marmotGroup/MarmotGroupIconEditor.kt | 2 +- .../concord/ConcordHomeScreen.kt | 2 +- .../concord/ConcordMetadataForm.kt | 2 +- .../header/ShortEphemeralChatChannelHeader.kt | 2 +- .../header/LongPublicChatChannelHeader.kt | 2 +- .../header/ShortPublicChatChannelHeader.kt | 2 +- .../relayGroup/RelayGroupChannelListScreen.kt | 2 +- .../relayGroup/RelayGroupDiscoveryScreen.kt | 2 +- .../relayGroup/RelayGroupParentPicker.kt | 2 +- .../send/ChannelFileUploadDialog.kt | 2 +- .../chats/rooms/ChatroomHeaderCompose.kt | 2 +- .../profile/header/badges/DisplayBadges.kt | 4 +- .../ui/screen/loggedIn/qrcode/ShowQRScreen.kt | 2 +- .../relayauth/RelayAuthSettingsScreen.kt | 2 +- .../ActiveSubscriptionsScreen.kt | 2 +- .../commons/richtext/AnimatedMediaUrl.kt | 30 +++++ .../AnimatedImageAutoPlay.android.kt | 43 +++++++ .../relayClient/user/UserMetadataObservers.kt | 7 +- .../amethyst/commons/ui/note/ScoreTag.kt | 119 ++++++++++++++++++ .../ui/components/RobohashAsyncImage.kt | 43 +++---- .../commons/ui/note/UserPictureImage.kt | 73 +++++++++++ .../components/AnimatedImageAutoPlay.jvm.kt | 32 +++++ 48 files changed, 379 insertions(+), 278 deletions(-) create mode 100644 commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt create mode 100644 commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/ScoreTag.kt rename {amethyst/src/main/java/com/vitorpamplona/amethyst => commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons}/ui/components/RobohashAsyncImage.kt (88%) create mode 100644 commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt create mode 100644 commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/ConnectedAccountRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/ConnectedAccountRow.kt index c4e20fe1cb..58950306c6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/ConnectedAccountRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/ConnectedAccountRow.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage /** * The account a signer request acts as — avatar + display name — so it's clear WHICH logged-in diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/SignerConsentActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/SignerConsentActivity.kt index 2f627041d9..7d610c2ffd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/SignerConsentActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/connectedApps/consent/SignerConsentActivity.kt @@ -95,11 +95,11 @@ import com.vitorpamplona.amethyst.commons.resources.nip46_signer_batch_select_no import com.vitorpamplona.amethyst.commons.resources.nip46_signer_batch_signing_as import com.vitorpamplona.amethyst.commons.resources.nip46_signer_batch_title import com.vitorpamplona.amethyst.commons.resources.nip46_signer_messages_with +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.call.CallSessionBridge -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.theme.AmethystTheme import com.vitorpamplona.quartz.nip01Core.core.Event diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletConsentActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletConsentActivity.kt index 96ddf7fb70..49e9bb54c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletConsentActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/napplet/NappletConsentActivity.kt @@ -70,8 +70,8 @@ import com.vitorpamplona.amethyst.commons.resources.napplet_consent_deny_always import com.vitorpamplona.amethyst.commons.resources.napplet_consent_hide_event import com.vitorpamplona.amethyst.commons.resources.napplet_consent_not_now import com.vitorpamplona.amethyst.commons.resources.napplet_consent_show_event +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.theme.AmethystTheme /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/authCommand/compose/RelayAuthPromptHost.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/authCommand/compose/RelayAuthPromptHost.kt index 81d8ae1207..4a09f6706a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/authCommand/compose/RelayAuthPromptHost.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/authCommand/compose/RelayAuthPromptHost.kt @@ -97,13 +97,13 @@ import com.vitorpamplona.amethyst.commons.resources.relay_auth_why_read_venue import com.vitorpamplona.amethyst.commons.resources.relay_auth_why_send_dm import com.vitorpamplona.amethyst.commons.resources.relay_auth_why_thread import com.vitorpamplona.amethyst.commons.resources.relay_auth_why_thread_with +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.RelayIconFilter import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Address diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt index 9d67b5d442..2774e6f8c0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderQueryState import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider +import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssemblerSubscription as SharedUserFinderSubscription @SuppressLint("StateFlowValueCalledInComposition") @Composable @@ -48,16 +49,7 @@ fun UserFinderFilterAssemblerSubscription( user: User, forAccount: Account, dataSource: UserFinderFilterAssembler, -) { - // different screens get different states - // even if they are tracking the same tag. - val state = - remember(user) { - UserFinderQueryState(user, forAccount) - } - - LifecycleAwareKeyDataSourceSubscription(state, dataSource) -} +) = SharedUserFinderSubscription(user, forAccount, dataSource) /** * Watches all the users that are cited in the parent post. diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt index b314ab7cd0..691179b7e7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserObservers.kt @@ -47,10 +47,13 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.sample +import com.vitorpamplona.amethyst.commons.relayClient.user.observeUserAboutMe as sharedObserveUserAboutMe +import com.vitorpamplona.amethyst.commons.relayClient.user.observeUserBanner as sharedObserveUserBanner +import com.vitorpamplona.amethyst.commons.relayClient.user.observeUserInfo as sharedObserveUserInfo +import com.vitorpamplona.amethyst.commons.relayClient.user.observeUserPicture as sharedObserveUserPicture @OptIn(ExperimentalCoroutinesApi::class) @Composable @@ -86,113 +89,30 @@ fun observeUserNickname( return flow.collectAsStateWithLifecycle(remember(user) { contactCards.cachedNickname(user) }) } -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeUserAboutMe( user: User, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in the metadata of this user. - UserFinderFilterAssemblerSubscription(user, accountViewModel) +): State = sharedObserveUserAboutMe(user, accountViewModel.dataSources().userFinder, accountViewModel.account) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(user) { - user.metadata().flow.map { - it?.info?.about ?: "" - } - } - - return flow.collectAsStateWithLifecycle( - user - .metadataOrNull() - ?.flow - ?.value - ?.info - ?.about ?: "", - ) -} - -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeUserInfo( user: User, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in the metadata of this user. - UserFinderFilterAssemblerSubscription(user, accountViewModel) +): State = sharedObserveUserInfo(user, accountViewModel.dataSources().userFinder, accountViewModel.account) - // Subscribe in the LocalCache for changes that arrive in the device - return user.metadata().flow.collectAsStateWithLifecycle() -} - -@SuppressLint("StateFlowValueCalledInComposition") -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeUserBanner( user: User, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in the metadata of this user. - UserFinderFilterAssemblerSubscription(user, accountViewModel) +): State = sharedObserveUserBanner(user, accountViewModel.dataSources().userFinder, accountViewModel.account) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(user) { - user - .metadata() - .flow - .map { - it?.info?.banner - }.distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle( - user - .metadataOrNull() - ?.flow - ?.value - ?.info - ?.banner, - ) -} - -@SuppressLint("StateFlowValueCalledInComposition") -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeUserPicture( user: User, accountViewModel: AccountViewModel, subscribe: Boolean = true, -): State { - // Subscribe in the relay for changes in the metadata of this user. - // Callers that already hold a single shared subscription for the same user - // (e.g. an author avatar that also observes the contact-card score) can pass - // subscribe = false to avoid setting up a redundant relay subscription. - if (subscribe) { - UserFinderFilterAssemblerSubscription(user, accountViewModel) - } - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(user) { - user - .metadata() - .flow - .map { - it?.info?.picture - }.distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle( - user - .metadataOrNull() - ?.flow - ?.value - ?.info - ?.picture, - ) -} +): State = sharedObserveUserPicture(user, accountViewModel.dataSources().userFinder, accountViewModel.account, subscribe) @OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ConcordInviteCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ConcordInviteCard.kt index 8276f2016b..ab6f170785 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ConcordInviteCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ConcordInviteCard.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.concord_home_title import com.vitorpamplona.amethyst.commons.resources.concord_invite_card_join import com.vitorpamplona.amethyst.commons.resources.concord_invite_card_subtitle +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel 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 757b7e4244..6446525a49 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 @@ -37,6 +37,7 @@ import androidx.compose.ui.layout.ContentScale import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedMediaUrl import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.note.DownloadForOfflineIcon import com.vitorpamplona.amethyst.commons.ui.theme.Size40dp @@ -154,11 +155,3 @@ fun MyAsyncImage( } } } - -fun isAnimatedMediaUrl(url: String): Boolean = - url.endsWith(".gif", ignoreCase = true) || - url.contains(".gif?", ignoreCase = true) || - url.contains(".gif#", ignoreCase = true) || - url.endsWith(".avif", ignoreCase = true) || - url.contains(".avif?", ignoreCase = true) || - url.contains(".avif#", ignoreCase = true) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RelayGroupCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RelayGroupCard.kt index ef9bf4b422..7d7ac96c3a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RelayGroupCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RelayGroupCard.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_badge_invite_onl import com.vitorpamplona.amethyst.commons.resources.relay_group_badge_private import com.vitorpamplona.amethyst.commons.resources.relay_group_member_count import com.vitorpamplona.amethyst.commons.resources.relay_group_open +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt index 9add6f2fa2..428b2ac946 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/GroupBottomBarEntries.kt @@ -41,10 +41,10 @@ import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChann import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.concord_home_title +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderFilterAssemblerSubscription -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.concord.rememberConcordImageModel import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt index 02f8689296..c828e83cee 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.resources.scheduled_posts_logout_toast import com.vitorpamplona.amethyst.commons.resources.scheduled_posts_logout_toast_zero import com.vitorpamplona.amethyst.commons.resources.scheduled_posts_logout_warning import com.vitorpamplona.amethyst.commons.scheduledposts.ScheduledPostStatus +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.loadPluralStringRes import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -79,7 +80,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size55dp import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.toShortDisplay import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index efd48a5e86..77cf8b53a3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -116,6 +116,7 @@ import com.vitorpamplona.amethyst.commons.resources.share_hls_video import com.vitorpamplona.amethyst.commons.resources.show_npub_as_a_qr_code import com.vitorpamplona.amethyst.commons.resources.status_update import com.vitorpamplona.amethyst.commons.scheduledposts.ScheduledPostStatus +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -146,7 +147,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserStatuses import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.layouts.PermanentDrawerWidth import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarCatalog import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarItemDef diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt index cc1d87909b..4998b3ae15 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt @@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.your_profile_image import com.vitorpamplona.amethyst.commons.search.SearchQuery +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -45,7 +46,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.HeaderPictureModifier import com.vitorpamplona.amethyst.commons.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index 775488a32a..f3d5b37d0f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -77,10 +77,12 @@ import com.vitorpamplona.amethyst.commons.resources.nutzap import com.vitorpamplona.amethyst.commons.resources.profile_image import com.vitorpamplona.amethyst.commons.richtext.CachedRichTextParser import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.FollowingIcon import com.vitorpamplona.amethyst.commons.ui.note.LikedIcon import com.vitorpamplona.amethyst.commons.ui.note.RepostedIcon +import com.vitorpamplona.amethyst.commons.ui.note.ScoreTagSmall import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange @@ -105,7 +107,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.ui.components.CoreSecretMessage import com.vitorpamplona.amethyst.ui.components.ExpandableRichTextViewer import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.routes.authorRouteFor import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor 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 20c88f6e1c..e83291659c 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 @@ -85,6 +85,7 @@ import com.vitorpamplona.amethyst.commons.resources.private_rumor_info_title import com.vitorpamplona.amethyst.commons.resources.private_rumor_mark import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.layouts.GenericRepostLayout import com.vitorpamplona.amethyst.commons.ui.layouts.NoteComposeLayout import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -117,7 +118,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observe import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeCommunityApprovalNeedStatus import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteModifications -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeEditDraftTo import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.creators.zapsplits.DisplayZapSplits diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt index eb589ce309..c2c54ffb9d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt @@ -55,6 +55,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.expand_relay_list import com.vitorpamplona.amethyst.commons.resources.relay_info import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.LargeRelayIconModifier @@ -70,7 +71,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.relayIconModifier import com.vitorpamplona.amethyst.commons.ui.theme.ripple24dp import com.vitorpamplona.amethyst.commons.ui.theme.warningColorOnSecondSurface import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index 5cfa7ff7cd..3aa93de82f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -21,25 +21,18 @@ package com.vitorpamplona.amethyst.ui.note import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -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 androidx.compose.ui.unit.dp @@ -47,21 +40,16 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.resources.Res -import com.vitorpamplona.amethyst.commons.resources.profile_image -import com.vitorpamplona.amethyst.commons.resources.profile_image_of_user import com.vitorpamplona.amethyst.commons.resources.unknown_author +import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.FollowingIcon +import com.vitorpamplona.amethyst.commons.ui.note.ScoreTag +import com.vitorpamplona.amethyst.commons.ui.note.UserPictureImage import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.commons.ui.theme.Font10SP -import com.vitorpamplona.amethyst.commons.ui.theme.Font6SP -import com.vitorpamplona.amethyst.commons.ui.theme.Font8SP -import com.vitorpamplona.amethyst.commons.ui.theme.SmallBorder import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserContactCardsScore import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser @@ -525,84 +513,6 @@ fun ScoreTag55Preview() { } } -@Composable -fun ScoreTag( - score: Int, - size: Dp, - modifier: Modifier, -) { - if (size > 34.dp) { - ScoreTagRegular(score, modifier) - } else if (size > 23.dp) { - ScoreTagSmall(score, modifier) - } else { - ScoreTagSmallest(score, modifier) - } -} - -@Composable -fun ScoreTagRegular( - score: Int, - modifier: Modifier, -) { - Text( - text = score.toString(), - color = Color.White, - fontWeight = FontWeight.Bold, - fontSize = Font10SP, - maxLines = 1, - overflow = TextOverflow.Clip, - lineHeight = Font10SP, - modifier = - modifier - .clip(SmallBorder) - .background(Color.Black) - .padding(horizontal = 4.dp, vertical = 0.dp), - ) -} - -@Composable -fun ScoreTagSmall( - score: Int, - modifier: Modifier, -) { - Text( - text = score.toString(), - color = Color.White, - fontWeight = FontWeight.Bold, - fontSize = Font8SP, - maxLines = 1, - overflow = TextOverflow.Clip, - lineHeight = Font8SP, - modifier = - modifier - .clip(SmallBorder) - .background(Color.Black) - .padding(horizontal = 3.dp, vertical = 0.dp), - ) -} - -@Composable -fun ScoreTagSmallest( - score: Int, - modifier: Modifier, -) { - Text( - text = score.toString(), - color = Color.White, - fontWeight = FontWeight.Bold, - fontSize = Font6SP, - maxLines = 1, - overflow = TextOverflow.Clip, - lineHeight = Font6SP, - modifier = - modifier - .clip(SmallBorder) - .background(Color.Black) - .padding(horizontal = 2.dp, vertical = 0.dp), - ) -} - @Composable fun WatchProfilePicture( baseUser: User, @@ -623,22 +533,12 @@ fun InnerUserPicture( modifier: Modifier, accountViewModel: AccountViewModel, ) { - val myImageModifier = - remember { - modifier.size(size).clip(shape = CircleShape) - } - - RobohashFallbackAsyncImage( - robot = userHex, - model = userPicture, - contentDescription = - if (userName != null) { - stringRes(id = Res.string.profile_image_of_user, userName) - } else { - stringRes(id = Res.string.profile_image) - }, - modifier = myImageModifier, - contentScale = ContentScale.Crop, + UserPictureImage( + userHex = userHex, + userPicture = userPicture, + userName = userName, + size = size, + modifier = modifier, loadProfilePicture = accountViewModel.settings.showProfilePictures(), loadRobohash = accountViewModel.settings.isNotPerformanceMode(), autoPlayGif = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt index 4522c97552..2ea85eed91 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt @@ -74,12 +74,12 @@ import com.vitorpamplona.amethyst.commons.resources.badge_awardees_label import com.vitorpamplona.amethyst.commons.resources.badge_untitled import com.vitorpamplona.amethyst.commons.resources.reject_badge import com.vitorpamplona.amethyst.commons.resources.unaccept_badge +import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size30dp import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel 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 8a5eb85fe9..8a95513673 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 @@ -76,6 +76,7 @@ import com.vitorpamplona.amethyst.commons.resources.preview_card_image_for import com.vitorpamplona.amethyst.commons.resources.profile_image import com.vitorpamplona.amethyst.commons.resources.quick_action_share import com.vitorpamplona.amethyst.commons.resources.quick_action_share_browser_link +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder @@ -93,7 +94,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.components.RichTextViewer -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt index 5b25f5ecc1..9bd69eb2ae 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt @@ -44,11 +44,11 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.podcast_hosts_and_guests +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav 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.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt index 67ff0aff42..aa62be4e9a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt @@ -48,11 +48,11 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.nip29RelayGroups.ui.RelayNameChip import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.buzz.workspace.buzzParticipants diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt index a56295a56c..9d462ebcf1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt @@ -67,6 +67,7 @@ import com.vitorpamplona.amethyst.commons.resources.profile_app_recommendations_ import com.vitorpamplona.amethyst.commons.resources.profile_app_recommendations_search import com.vitorpamplona.amethyst.commons.resources.profile_app_recommendations_search_empty import com.vitorpamplona.amethyst.commons.resources.select_list_to_filter +import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -77,7 +78,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.navigation.topbars.FeedFilterSpinner import com.vitorpamplona.amethyst.ui.note.types.ByAuthorChip diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt index d68ba9f721..5667f0e30e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt @@ -69,6 +69,7 @@ import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflic import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.toShortDisplay @@ -76,7 +77,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observe import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.UserPicture diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt index e1beb6c625..c8feeaa482 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt @@ -61,12 +61,12 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.toShortDisplay import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.LoadPublicChatChannel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt index 5b09074883..0d3cbdf7fb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt @@ -57,12 +57,12 @@ import com.vitorpamplona.amethyst.commons.resources.badge_untitled import com.vitorpamplona.amethyst.commons.resources.profile_badges_description import com.vitorpamplona.amethyst.commons.resources.profile_badges_empty import com.vitorpamplona.amethyst.commons.resources.profile_badges_title +import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt index ce9df281b9..fb7b9de13f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt @@ -64,12 +64,12 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.geohashChat.GeohashChatChannel import com.vitorpamplona.amethyst.commons.search.SearchSeed +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.topbars.SearchTopBarAction diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupIconEditor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupIconEditor.kt index f0fabf7766..faa029d834 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupIconEditor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupIconEditor.kt @@ -44,9 +44,9 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_add_photo import com.vitorpamplona.amethyst.commons.resources.marmot_change_photo import com.vitorpamplona.amethyst.commons.resources.marmot_group_icon import com.vitorpamplona.amethyst.commons.resources.marmot_remove_photo +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.HexKey diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt index 8df0607a89..a4300dae56 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt @@ -67,13 +67,13 @@ import com.vitorpamplona.amethyst.commons.resources.concord_home_empty import com.vitorpamplona.amethyst.commons.resources.concord_home_title import com.vitorpamplona.amethyst.commons.resources.concord_member_count import com.vitorpamplona.amethyst.commons.resources.concord_show_all_channels +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.timeAgo diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt index eec6288437..6dafebd7ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt @@ -74,12 +74,12 @@ import com.vitorpamplona.amethyst.commons.resources.concord_create_title import com.vitorpamplona.amethyst.commons.resources.concord_edit_banner_hint import com.vitorpamplona.amethyst.commons.resources.failed_to_upload_media_no_details import com.vitorpamplona.amethyst.commons.resources.remove +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.MediumRelayIconModifier import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/ShortEphemeralChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/ShortEphemeralChatChannelHeader.kt index 9fc763710b..da2bce20a3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/ShortEphemeralChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/ShortEphemeralChatChannelHeader.kt @@ -40,6 +40,7 @@ import com.vitorpamplona.amethyst.commons.chats.ui.LeaveChannelButton import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.HeaderPictureModifier @@ -47,7 +48,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingChannel -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt index ae56c76d54..a5757f0ed1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt @@ -50,6 +50,7 @@ import com.vitorpamplona.amethyst.commons.resources.channel_image import com.vitorpamplona.amethyst.commons.resources.created_at import com.vitorpamplona.amethyst.commons.resources.groups_no_descriptor import com.vitorpamplona.amethyst.commons.resources.owner +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DoubleHorzSpacer @@ -60,7 +61,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observe import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingChannel import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.LoadNote -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay 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 317783b3a6..531c6c4399 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 @@ -41,6 +41,7 @@ import com.vitorpamplona.amethyst.commons.chats.ui.JoinChannelButton import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.HeaderPictureModifier @@ -50,7 +51,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingChannel import com.vitorpamplona.amethyst.ui.components.LoadNote -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.LikeReaction import com.vitorpamplona.amethyst.ui.note.ZapReaction import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt index 43ccd79d8d..8093f081eb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt @@ -94,6 +94,7 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_section_forums import com.vitorpamplona.amethyst.commons.resources.relay_tor_clearnet_action import com.vitorpamplona.amethyst.commons.resources.relay_tor_clearnet_body import com.vitorpamplona.amethyst.commons.resources.relay_tor_clearnet_title +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.pluralStringRes @@ -103,7 +104,6 @@ import com.vitorpamplona.amethyst.commons.util.sortedBySnapshot import com.vitorpamplona.amethyst.model.nip11RelayInfo.isRelaySignedRelayGroup import com.vitorpamplona.amethyst.model.nip11RelayInfo.looksLikeNonNip29Relay import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.UserPicture diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt index e6e0a4a720..e55e17f57c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt @@ -69,6 +69,7 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_member_count import com.vitorpamplona.amethyst.commons.resources.relay_group_message_count_short_capped import com.vitorpamplona.amethyst.commons.resources.relay_group_relay_group_count import com.vitorpamplona.amethyst.commons.resources.select_list_to_filter +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel @@ -83,7 +84,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.warningColor import com.vitorpamplona.amethyst.model.nip11RelayInfo.WarmNip11 import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupParentPicker.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupParentPicker.kt index c0823de922..627c5face7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupParentPicker.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupParentPicker.kt @@ -75,12 +75,12 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_parent_pick_titl import com.vitorpamplona.amethyst.commons.resources.relay_group_parent_search import com.vitorpamplona.amethyst.commons.resources.relay_group_parent_top_level_option import com.vitorpamplona.amethyst.commons.resources.relay_group_section_structure +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.util.sortedBySnapshot import com.vitorpamplona.amethyst.model.nip11RelayInfo.isRelaySignedRelayGroup import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupCardWarmupSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relayGroup.datasource.RelayGroupsOnRelaySubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelFileUploadDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelFileUploadDialog.kt index 96e70b3588..ec0e05f483 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelFileUploadDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/send/ChannelFileUploadDialog.kt @@ -38,11 +38,11 @@ import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChann import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.HeaderPictureModifier import com.vitorpamplona.amethyst.commons.ui.theme.Size34dp -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.ChatFileUploadDialog diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt index 9772cc57ff..43bc9c72c8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt @@ -95,6 +95,7 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_server_label import com.vitorpamplona.amethyst.commons.resources.remove_from_messages import com.vitorpamplona.amethyst.commons.resources.unmute_notifications import com.vitorpamplona.amethyst.commons.resources.unpin_conversation +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -113,7 +114,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observe import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteHasEvent import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderByParentFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.layouts.ChatHeaderLayout import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.BlankNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt index 40a1adaf7a..aea887d665 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt @@ -70,12 +70,12 @@ import com.vitorpamplona.amethyst.commons.resources.badge_award_image_for import com.vitorpamplona.amethyst.commons.resources.badge_untitled import com.vitorpamplona.amethyst.commons.resources.profile_badges_header import com.vitorpamplona.amethyst.commons.resources.profile_badges_title +import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImage -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt index c733ea070f..4321485aa8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.commons.model.nip05DnsIdentifiers.Nip05State import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image import com.vitorpamplona.amethyst.commons.resources.scan_qr +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton @@ -64,7 +65,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.largeProfilePictureModifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.ObserveAndDisplayNIP05 import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relayauth/RelayAuthSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relayauth/RelayAuthSettingsScreen.kt index b867cb022e..83deb6a5f8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relayauth/RelayAuthSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relayauth/RelayAuthSettingsScreen.kt @@ -109,6 +109,7 @@ import com.vitorpamplona.amethyst.commons.resources.relay_auth_session_undo_bloc import com.vitorpamplona.amethyst.commons.resources.relay_auth_settings_title import com.vitorpamplona.amethyst.commons.resources.relay_auth_undo import com.vitorpamplona.amethyst.commons.resources.relay_info +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -116,7 +117,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.MediumRelayIconModifier import com.vitorpamplona.amethyst.commons.ui.theme.RelayIconFilter import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.service.relayClient.authCommand.compose.relayAuthPurposeLabelRes -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.timeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsDivider diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/subscriptions/ActiveSubscriptionsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/subscriptions/ActiveSubscriptionsScreen.kt index f513a35aed..42fcf0d8e5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/subscriptions/ActiveSubscriptionsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/subscriptions/ActiveSubscriptionsScreen.kt @@ -87,6 +87,7 @@ import com.vitorpamplona.amethyst.commons.resources.active_subs_title import com.vitorpamplona.amethyst.commons.resources.active_subs_unattributed import com.vitorpamplona.amethyst.commons.resources.active_subs_untagged import com.vitorpamplona.amethyst.commons.resources.marmot_group_fallback_name +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.theme.RelayIconFilter @@ -94,7 +95,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.allGoodColor import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.ui.theme.warningColor import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.pluralStringRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt new file mode 100644 index 0000000000..8f3a251674 --- /dev/null +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt @@ -0,0 +1,30 @@ +/* + * 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.commons.richtext + +/** True for GIF/AVIF urls, which may animate and so bypass still-image pipelines like the avatar thumbnail cache. */ +fun isAnimatedMediaUrl(url: String): Boolean = + url.endsWith(".gif", ignoreCase = true) || + url.contains(".gif?", ignoreCase = true) || + url.contains(".gif#", ignoreCase = true) || + url.endsWith(".avif", ignoreCase = true) || + url.contains(".avif?", ignoreCase = true) || + url.contains(".avif#", ignoreCase = true) diff --git a/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt new file mode 100644 index 0000000000..f93981c56b --- /dev/null +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt @@ -0,0 +1,43 @@ +/* + * 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.commons.ui.components + +import android.graphics.drawable.Animatable +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.platform.LocalContext +import coil3.Image +import coil3.asDrawable + +@Composable +internal actual fun AnimatedImageAutoPlay( + image: Image?, + autoPlay: Boolean, +) { + val resources = LocalContext.current.resources + val drawable = image?.asDrawable(resources) + + LaunchedEffect(drawable, autoPlay) { + if (drawable is Animatable) { + if (autoPlay) drawable.start() else drawable.stop() + } + } +} diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/user/UserMetadataObservers.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/user/UserMetadataObservers.kt index c1d20a41d9..f2dd189808 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/user/UserMetadataObservers.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/user/UserMetadataObservers.kt @@ -62,8 +62,13 @@ fun observeUserPicture( user: User, userFinder: UserFinderFilterAssembler, account: UserFinderAccount, + // Callers that already hold a subscription for the same user (e.g. an author avatar that + // also observes the contact-card score) pass false to skip a redundant relay subscription. + subscribe: Boolean = true, ): State { - UserFinderFilterAssemblerSubscription(user, account, userFinder) + if (subscribe) { + UserFinderFilterAssemblerSubscription(user, account, userFinder) + } val flow = remember(user) { diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/ScoreTag.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/ScoreTag.kt new file mode 100644 index 0000000000..bb69d45d37 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/ScoreTag.kt @@ -0,0 +1,119 @@ +/* + * 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.commons.ui.note + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.commons.ui.theme.Font10SP +import com.vitorpamplona.amethyst.commons.ui.theme.Font6SP +import com.vitorpamplona.amethyst.commons.ui.theme.Font8SP +import com.vitorpamplona.amethyst.commons.ui.theme.SmallBorder + +/** + * Trust-score chip drawn over the bottom of an avatar, sized to the avatar: regular above 34dp, + * small above 23dp, smallest below. + */ +@Composable +fun ScoreTag( + score: Int, + size: Dp, + modifier: Modifier, +) { + if (size > 34.dp) { + ScoreTagRegular(score, modifier) + } else if (size > 23.dp) { + ScoreTagSmall(score, modifier) + } else { + ScoreTagSmallest(score, modifier) + } +} + +@Composable +fun ScoreTagRegular( + score: Int, + modifier: Modifier, +) { + Text( + text = score.toString(), + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = Font10SP, + maxLines = 1, + overflow = TextOverflow.Clip, + lineHeight = Font10SP, + modifier = + modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 4.dp, vertical = 0.dp), + ) +} + +@Composable +fun ScoreTagSmall( + score: Int, + modifier: Modifier, +) { + Text( + text = score.toString(), + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = Font8SP, + maxLines = 1, + overflow = TextOverflow.Clip, + lineHeight = Font8SP, + modifier = + modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 3.dp, vertical = 0.dp), + ) +} + +@Composable +fun ScoreTagSmallest( + score: Int, + modifier: Modifier, +) { + Text( + text = score.toString(), + color = Color.White, + fontWeight = FontWeight.Bold, + fontSize = Font6SP, + maxLines = 1, + overflow = TextOverflow.Clip, + lineHeight = Font6SP, + modifier = + modifier + .clip(SmallBorder) + .background(Color.Black) + .padding(horizontal = 2.dp, vertical = 0.dp), + ) +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt similarity index 88% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt rename to commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt index dcfce38a90..c1725fb28b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RobohashAsyncImage.kt +++ b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt @@ -18,15 +18,13 @@ * 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.commons.ui.components -import android.graphics.drawable.Animatable import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -38,9 +36,8 @@ import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import coil3.asDrawable import coil3.compose.AsyncImagePainter +import coil3.compose.LocalPlatformContext import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent import coil3.network.NetworkHeaders @@ -48,12 +45,22 @@ import coil3.network.httpHeaders import coil3.request.ImageRequest import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.icons.symbols.rememberMaterialSymbolPainter +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedMediaUrl import com.vitorpamplona.amethyst.commons.robohash.CachedRobohash import com.vitorpamplona.amethyst.commons.service.http.LocalBlossomCacheRedirectInterceptor -import com.vitorpamplona.amethyst.commons.ui.components.ProfilePictureUrl -import com.vitorpamplona.amethyst.commons.ui.components.forwardingPainter import com.vitorpamplona.amethyst.commons.ui.theme.isLight import com.vitorpamplona.amethyst.commons.ui.theme.onBackgroundColorFilter +import coil3.Image as CoilImage + +/** + * Plays or pauses an animated avatar (GIF/AVIF) once Coil has decoded it. Android drives the + * decoded `Animatable` drawable; desktop has no such drawable, so it is a no-op there. + */ +@Composable +internal expect fun AnimatedImageAutoPlay( + image: CoilImage?, + autoPlay: Boolean, +) @Composable fun RobohashAsyncImage( @@ -115,7 +122,6 @@ fun RobohashFallbackAsyncImage( ) } - val resources = LocalContext.current.resources SubcomposeAsyncImage( // The thumbnail-cache fetcher behind ProfilePictureUrl delegates to Coil's http-only // NetworkFetcher, so a LOCAL model (e.g. a decrypted Concord community icon cached at @@ -136,14 +142,7 @@ fun RobohashFallbackAsyncImage( filterQuality = filterQuality, ) { val state by painter.state.collectAsState() - val successState = state as? AsyncImagePainter.State.Success - val drawable = successState?.result?.image?.asDrawable(resources) - - LaunchedEffect(drawable, autoPlayGif) { - if (drawable is Animatable) { - if (autoPlayGif) drawable.start() else drawable.stop() - } - } + AnimatedImageAutoPlay((state as? AsyncImagePainter.State.Success)?.result?.image, autoPlayGif) when (state) { is AsyncImagePainter.State.Success -> SubcomposeAsyncImageContent() @@ -194,7 +193,6 @@ fun GifProfilePicture( loadRobohash: Boolean, autoPlay: Boolean, ) { - val resources = LocalContext.current.resources val fallbackPainter = if (loadRobohash) { rememberVectorPainter(image = CachedRobohash.get(userHex, MaterialTheme.colorScheme.isLight)) @@ -205,7 +203,7 @@ fun GifProfilePicture( ) } - val context = LocalContext.current + val context = LocalPlatformContext.current // Animated avatars skip ProfilePictureFetcher (its thumbnail cache would flatten them), so // they carry the profile-picture marker themselves for the local Blossom cache bridge. val model = @@ -229,14 +227,7 @@ fun GifProfilePicture( modifier = Modifier.fillMaxSize(), ) { val state by painter.state.collectAsState() - val successState = state as? AsyncImagePainter.State.Success - val drawable = successState?.result?.image?.asDrawable(resources) - - LaunchedEffect(drawable, autoPlay) { - if (drawable is Animatable) { - if (autoPlay) drawable.start() else drawable.stop() - } - } + AnimatedImageAutoPlay((state as? AsyncImagePainter.State.Success)?.result?.image, autoPlay) when (state) { is AsyncImagePainter.State.Success -> { diff --git a/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt new file mode 100644 index 0000000000..b3234d1f08 --- /dev/null +++ b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt @@ -0,0 +1,73 @@ +/* + * 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.commons.ui.note + +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.Dp +import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.profile_image +import com.vitorpamplona.amethyst.commons.resources.profile_image_of_user +import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.stringRes + +/** + * A user's round avatar: their picture when [loadProfilePicture] allows it, otherwise (or while + * loading / on error) their robohash, or a plain face icon when [loadRobohash] is off. + * Animated pictures play only when [autoPlayGif]. + */ +@Composable +fun UserPictureImage( + userHex: String, + userPicture: String?, + userName: String?, + size: Dp, + modifier: Modifier, + loadProfilePicture: Boolean, + loadRobohash: Boolean, + autoPlayGif: Boolean, +) { + val myImageModifier = + remember { + modifier.size(size).clip(shape = CircleShape) + } + + RobohashFallbackAsyncImage( + robot = userHex, + model = userPicture, + contentDescription = + if (userName != null) { + stringRes(id = Res.string.profile_image_of_user, userName) + } else { + stringRes(id = Res.string.profile_image) + }, + modifier = myImageModifier, + contentScale = ContentScale.Crop, + loadProfilePicture = loadProfilePicture, + loadRobohash = loadRobohash, + autoPlayGif = autoPlayGif, + ) +} diff --git a/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt new file mode 100644 index 0000000000..3edd5be51c --- /dev/null +++ b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt @@ -0,0 +1,32 @@ +/* + * 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.commons.ui.components + +import androidx.compose.runtime.Composable +import coil3.Image + +@Composable +internal actual fun AnimatedImageAutoPlay( + image: Image?, + autoPlay: Boolean, +) { + // Desktop decodes animated avatars without a controllable drawable; nothing to toggle. +} From ef845067a48d26da69584b98a3323a53ccbd3b21 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 00:21:14 +0000 Subject: [PATCH 2/9] fix: address the avatar audit and fold UserPictureImage into UserAvatar - UserAvatar is now the one shared avatar. It keeps the remember(size, modifier) keys and hands drawing to an AvatarImage expect: jvmAndroid uses RobohashFallbackAsyncImage (GIF/AVIF playback included), iOS a plain AsyncImage. UserPictureImage is gone; InnerUserPicture calls UserAvatar. - The ProfilePictureUrl thumbnail-cache wrapping and the local-Blossom request marker are now gated on LocalProfilePictureCache, which the Android AmethystTheme provides. Desktop has neither the fetcher nor the interceptor, so it loads plain URLs and never leaks the marker header. The unused per-call useThumbnailCache flag is removed. - AnimatedImageAutoPlay remembers the drawable, so a bitmap is no longer rewrapped and the effect no longer restarts on every recomposition. The desktop no-op and the expect document that autoPlay has no effect there. - One animated-URL check: isAnimatedGifUrl / isAvifUrl / isAnimatedMediaUrl in commons richtext, used by ZoomableContentView and the desktop GIF paths. - Drop the app's forwarding 3-arg UserFinderFilterAssemblerSubscription. - commonsUI/ARCHITECTURE.md lists the avatar engine and its actuals. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../UserFinderFilterAssemblerSubscription.kt | 11 +- .../ui/components/ZoomableContentView.kt | 8 +- .../amethyst/ui/note/UserProfilePicture.kt | 15 ++- .../vitorpamplona/amethyst/ui/theme/Theme.kt | 3 + .../commons/richtext/AnimatedMediaUrl.kt | 14 ++- commonsUI/ARCHITECTURE.md | 8 +- .../AnimatedImageAutoPlay.android.kt | 5 +- .../commons/ui/components/UserAvatar.kt | 102 +++++++----------- .../commons/ui/components/AvatarImage.ios.kt | 80 ++++++++++++++ .../AvatarImage.jvmAndroid.kt} | 40 ++----- .../ui/components/RobohashAsyncImage.kt | 40 ++++--- .../components/AnimatedImageAutoPlay.jvm.kt | 3 +- .../ui/chats/composer/GifPickerPanel.kt | 2 +- .../desktop/ui/media/AnimatedGifImage.kt | 7 -- .../desktop/ui/media/PictureDisplay.kt | 1 + .../desktop/ui/media/ZoomableImage.kt | 1 + .../amethyst/desktop/ui/note/NoteCard.kt | 2 +- .../desktop/ui/note/WoTBadgedAvatar.kt | 2 - 18 files changed, 189 insertions(+), 155 deletions(-) create mode 100644 commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.ios.kt rename commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/{note/UserPictureImage.kt => components/AvatarImage.jvmAndroid.kt} (54%) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt index 2774e6f8c0..3002e75f48 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt @@ -26,9 +26,7 @@ import androidx.compose.runtime.remember import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.LifecycleAwareKeyDataSourceSubscription -import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssembler import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderQueryState -import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssemblerSubscription as SharedUserFinderSubscription @@ -38,19 +36,12 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssem fun UserFinderFilterAssemblerSubscription( user: User, accountViewModel: AccountViewModel, -) = UserFinderFilterAssemblerSubscription( +) = SharedUserFinderSubscription( user, accountViewModel.account, accountViewModel.dataSources().userFinder, ) -@Composable -fun UserFinderFilterAssemblerSubscription( - user: User, - forAccount: Account, - dataSource: UserFinderFilterAssembler, -) = SharedUserFinderSubscription(user, forAccount, dataSource) - /** * Watches all the users that are cited in the parent post. * So that we load their relay lists and find posts diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 36fc70c585..d7af8ef884 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -104,6 +104,7 @@ import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlPdf import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.RichTextParser +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedMediaUrl import com.vitorpamplona.amethyst.commons.service.image.placeholderModel import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.components.M3ActionDialog @@ -749,12 +750,7 @@ fun BaseMediaContent.isAnimatedMedia(): Boolean = if (this is MediaUrlContent) { mimeType == "image/gif" || mimeType == "image/avif" || - url.endsWith(".gif", ignoreCase = true) || - url.contains(".gif?", ignoreCase = true) || - url.contains(".gif#", ignoreCase = true) || - url.endsWith(".avif", ignoreCase = true) || - url.contains(".avif?", ignoreCase = true) || - url.contains(".avif#", ignoreCase = true) + isAnimatedMediaUrl(url) } else if (this is MediaPreloadedContent) { mimeType == "image/gif" || mimeType == "image/avif" || diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index 3aa93de82f..165d78d292 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -40,12 +40,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.resources.Res +import com.vitorpamplona.amethyst.commons.resources.profile_image +import com.vitorpamplona.amethyst.commons.resources.profile_image_of_user import com.vitorpamplona.amethyst.commons.resources.unknown_author import com.vitorpamplona.amethyst.commons.ui.components.RobohashAsyncImage +import com.vitorpamplona.amethyst.commons.ui.components.UserAvatar import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.FollowingIcon import com.vitorpamplona.amethyst.commons.ui.note.ScoreTag -import com.vitorpamplona.amethyst.commons.ui.note.UserPictureImage import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserContactCardsScore @@ -533,12 +535,17 @@ fun InnerUserPicture( modifier: Modifier, accountViewModel: AccountViewModel, ) { - UserPictureImage( + UserAvatar( userHex = userHex, - userPicture = userPicture, - userName = userName, + pictureUrl = userPicture, size = size, modifier = modifier, + contentDescription = + if (userName != null) { + stringRes(id = Res.string.profile_image_of_user, userName) + } else { + stringRes(id = Res.string.profile_image) + }, loadProfilePicture = accountViewModel.settings.showProfilePictures(), loadRobohash = accountViewModel.settings.isNotPerformanceMode(), autoPlayGif = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 13a092c162..7fbbf5fed1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -44,6 +44,7 @@ import com.patrykandpatrick.vico.compose.common.VicoTheme import com.patrykandpatrick.vico.compose.common.VicoTheme.CandlestickCartesianLayerColors import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.icons.symbols.ProvideAppIcons +import com.vitorpamplona.amethyst.commons.ui.components.LocalProfilePictureCache import com.vitorpamplona.amethyst.commons.ui.theme.AccentBlueDark import com.vitorpamplona.amethyst.commons.ui.theme.AccentBlueLight import com.vitorpamplona.amethyst.commons.ui.theme.AccentGreenDark @@ -189,6 +190,8 @@ fun AmethystTheme( ProvideAppIcons { CompositionLocalProvider( LocalDensity provides scaledDensity, + // ImageLoaderSetup registers the avatar thumbnail cache and the local Blossom bridge. + LocalProfilePictureCache provides true, LocalTextStyle provides LocalTextStyle.current.merge(TextStyle(fontFamily = resolvedFontFamily)), content = content, ) diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt index 8f3a251674..7bdde9baf2 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt @@ -20,11 +20,17 @@ */ package com.vitorpamplona.amethyst.commons.richtext -/** True for GIF/AVIF urls, which may animate and so bypass still-image pipelines like the avatar thumbnail cache. */ -fun isAnimatedMediaUrl(url: String): Boolean = +/** True for GIF urls (path ends in `.gif`, optionally followed by a query or fragment). */ +fun isAnimatedGifUrl(url: String): Boolean = url.endsWith(".gif", ignoreCase = true) || url.contains(".gif?", ignoreCase = true) || - url.contains(".gif#", ignoreCase = true) || - url.endsWith(".avif", ignoreCase = true) || + url.contains(".gif#", ignoreCase = true) + +/** True for AVIF urls (path ends in `.avif`, optionally followed by a query or fragment). */ +fun isAvifUrl(url: String): Boolean = + url.endsWith(".avif", ignoreCase = true) || url.contains(".avif?", ignoreCase = true) || url.contains(".avif#", ignoreCase = true) + +/** True for GIF/AVIF urls, which may animate and so bypass still-image pipelines like the avatar thumbnail cache. */ +fun isAnimatedMediaUrl(url: String): Boolean = isAnimatedGifUrl(url) || isAvifUrl(url) diff --git a/commonsUI/ARCHITECTURE.md b/commonsUI/ARCHITECTURE.md index 2830e8a38f..b693e06a2b 100644 --- a/commonsUI/ARCHITECTURE.md +++ b/commonsUI/ARCHITECTURE.md @@ -46,11 +46,11 @@ is specific to the UI module. | Source set | For | |---------------|-----| | `commonMain` | Composables, icons, theme, Coil fetchers, `composeResources`. Gated by `verifyKmpPurity` like `commons`. | -| `jvmAndroid` | Markdown renderer (`ui/markdown`), Coil-OkHttp + Blossom read-auth fetcher, the `viewModel()` helper. | -| `jvmMain` | Desktop Coil bridge (`CoilImageBridge.jvm.kt`), `compose.desktop.currentOs`. `dependsOn(jvmAndroid)` + `skikoMain`. | -| `androidMain` | Android Coil bridge. `dependsOn(jvmAndroid)`. | +| `jvmAndroid` | Markdown renderer (`ui/markdown`), Coil-OkHttp + Blossom read-auth fetcher, the `viewModel()` helper, and the avatar/image engine (`ui/components/RobohashAsyncImage.kt`: `RobohashFallbackAsyncImage`, `GifProfilePicture`) behind the `UserAvatar` `AvatarImage` actual. For a user avatar call the commonMain `UserAvatar`; don't add another avatar composable. | +| `jvmMain` | Desktop Coil bridge (`CoilImageBridge.jvm.kt`), a no-op `AnimatedImageAutoPlay` (Coil decodes only the first frame), `compose.desktop.currentOs`. `dependsOn(jvmAndroid)` + `skikoMain`. | +| `androidMain` | Android Coil bridge, the `AnimatedImageAutoPlay` actual that starts/stops GIF/AVIF drawables. `dependsOn(jvmAndroid)`. | | `skikoMain` | `org.jetbrains.skia` pixel helpers shared by desktop JVM + iOS (`SkiaBitmapConverter`). | -| `iosMain` | iOS Coil bridge. Compile-only spike today. | +| `iosMain` | iOS Coil bridge, a plain `AsyncImage` `AvatarImage` actual. Compile-only spike today. | ## Tooling that points here diff --git a/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt index f93981c56b..4205e6d09a 100644 --- a/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.commons.ui.components import android.graphics.drawable.Animatable import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import coil3.Image import coil3.asDrawable @@ -33,7 +34,9 @@ internal actual fun AnimatedImageAutoPlay( autoPlay: Boolean, ) { val resources = LocalContext.current.resources - val drawable = image?.asDrawable(resources) + // asDrawable wraps a bitmap in a new BitmapDrawable on every call; remembering it keeps the + // effect below from restarting on each recomposition. + val drawable = remember(image, resources) { image?.asDrawable(resources) } LaunchedEffect(drawable, autoPlay) { if (drawable is Animatable) { diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/UserAvatar.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/UserAvatar.kt index 9a559ebde8..1e294c544f 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/UserAvatar.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/UserAvatar.kt @@ -20,28 +20,16 @@ */ package com.vitorpamplona.amethyst.commons.ui.components -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment +import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.DefaultAlpha -import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.vector.rememberVectorPainter -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.Dp -import coil3.compose.AsyncImage -import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols -import com.vitorpamplona.amethyst.commons.icons.symbols.rememberMaterialSymbolPainter -import com.vitorpamplona.amethyst.commons.robohash.CachedRobohash -import com.vitorpamplona.amethyst.commons.ui.theme.isLight /** * Wrapper class for profile picture URLs that signals Coil to use the thumbnail @@ -54,7 +42,16 @@ data class ProfilePictureUrl( ) /** - * Shared avatar component that displays a user's profile picture with Robohash fallback. + * True when the host's Coil pipeline registers a `Fetcher.Factory` (the + * avatar thumbnail cache) and the local Blossom cache bridge that strips the profile-picture + * request marker. Avatars then load http(s) pictures through that cache. Hosts without them + * (desktop, iOS) keep the default `false`, so avatars load the plain URL. + */ +val LocalProfilePictureCache = staticCompositionLocalOf { false } + +/** + * The shared user avatar: the profile picture clipped to a circle, with a Robohash (or a generic + * face icon) while it loads, when it fails, or when pictures are turned off. * * @param userHex The user's public key hex (used for Robohash generation) * @param pictureUrl Optional URL to the user's profile picture @@ -63,7 +60,8 @@ data class ProfilePictureUrl( * @param contentDescription Accessibility description * @param loadProfilePicture Whether to load the profile picture (false = show robohash only) * @param loadRobohash Whether to generate robohash (false = show generic icon) - * @param useThumbnailCache Whether to use the thumbnail disk cache for faster repeated loads + * @param autoPlayGif Whether animated (GIF/AVIF) pictures play. Only Android can animate them; + * desktop shows their first frame either way. * @param badge Optional overlay drawn on top of the avatar (bottom-right by * convention). Used by Desktop for the WoT trust-score chip; Android call * sites leave it null. When null the avatar renders as before (no extra @@ -78,7 +76,7 @@ fun UserAvatar( contentDescription: String? = null, loadProfilePicture: Boolean = true, loadRobohash: Boolean = true, - useThumbnailCache: Boolean = false, + autoPlayGif: Boolean = true, badge: @Composable (BoxScope.() -> Unit)? = null, ) { if (badge != null) { @@ -91,7 +89,7 @@ fun UserAvatar( contentDescription = contentDescription, loadProfilePicture = loadProfilePicture, loadRobohash = loadRobohash, - useThumbnailCache = useThumbnailCache, + autoPlayGif = autoPlayGif, badge = null, ) badge() @@ -106,53 +104,25 @@ fun UserAvatar( .clip(shape = CircleShape) } - val imageModel: Any? = - if (pictureUrl != null && useThumbnailCache) { - ProfilePictureUrl(pictureUrl) - } else { - pictureUrl - } - - if (imageModel != null && loadProfilePicture) { - // Show profile picture with robohash/icon as fallback - val fallbackPainter = - if (loadRobohash) { - rememberVectorPainter( - image = CachedRobohash.get(userHex, MaterialTheme.colorScheme.isLight), - ) - } else { - rememberMaterialSymbolPainter(MaterialSymbols.Face) - } - - AsyncImage( - model = imageModel, - contentDescription = contentDescription, - modifier = avatarModifier, - placeholder = fallbackPainter, - fallback = fallbackPainter, - error = fallbackPainter, - alignment = Alignment.Center, - contentScale = ContentScale.Crop, - alpha = DefaultAlpha, - colorFilter = null, - filterQuality = DrawScope.DefaultFilterQuality, - ) - } else if (loadRobohash) { - // Show robohash only - Image( - imageVector = CachedRobohash.get(userHex, MaterialTheme.colorScheme.isLight), - contentDescription = contentDescription, - modifier = avatarModifier, - contentScale = ContentScale.Crop, - ) - } else { - // Show generic icon - Image( - painter = rememberMaterialSymbolPainter(MaterialSymbols.Face), - contentDescription = contentDescription, - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground), - modifier = avatarModifier, - contentScale = ContentScale.Crop, - ) - } + AvatarImage( + userHex = userHex, + pictureUrl = pictureUrl, + contentDescription = contentDescription, + modifier = avatarModifier, + loadProfilePicture = loadProfilePicture, + loadRobohash = loadRobohash, + autoPlayGif = autoPlayGif, + ) } + +/** Draws the avatar picture into an already sized and clipped [modifier]. */ +@Composable +internal expect fun AvatarImage( + userHex: String, + pictureUrl: String?, + contentDescription: String?, + modifier: Modifier, + loadProfilePicture: Boolean, + loadRobohash: Boolean, + autoPlayGif: Boolean, +) diff --git a/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.ios.kt b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.ios.kt new file mode 100644 index 0000000000..b57daac73a --- /dev/null +++ b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.ios.kt @@ -0,0 +1,80 @@ +/* + * 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.commons.ui.components + +import androidx.compose.foundation.Image +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.layout.ContentScale +import coil3.compose.AsyncImage +import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.icons.symbols.rememberMaterialSymbolPainter +import com.vitorpamplona.amethyst.commons.robohash.CachedRobohash +import com.vitorpamplona.amethyst.commons.ui.theme.isLight +import com.vitorpamplona.amethyst.commons.ui.theme.onBackgroundColorFilter + +// iOS has no animated-avatar pipeline yet, so autoPlayGif is unused. +@Composable +internal actual fun AvatarImage( + userHex: String, + pictureUrl: String?, + contentDescription: String?, + modifier: Modifier, + loadProfilePicture: Boolean, + loadRobohash: Boolean, + autoPlayGif: Boolean, +) { + if (pictureUrl != null && loadProfilePicture) { + val fallbackPainter = + if (loadRobohash) { + rememberVectorPainter(image = CachedRobohash.get(userHex, MaterialTheme.colorScheme.isLight)) + } else { + rememberMaterialSymbolPainter(MaterialSymbols.Face) + } + + AsyncImage( + model = pictureUrl, + contentDescription = contentDescription, + modifier = modifier, + placeholder = fallbackPainter, + fallback = fallbackPainter, + error = fallbackPainter, + contentScale = ContentScale.Crop, + ) + } else if (loadRobohash) { + Image( + imageVector = CachedRobohash.get(userHex, MaterialTheme.colorScheme.isLight), + contentDescription = contentDescription, + modifier = modifier, + contentScale = ContentScale.Crop, + ) + } else { + Image( + painter = rememberMaterialSymbolPainter(MaterialSymbols.Face), + contentDescription = contentDescription, + colorFilter = MaterialTheme.colorScheme.onBackgroundColorFilter, + modifier = modifier, + contentScale = ContentScale.Crop, + ) + } +} diff --git a/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt similarity index 54% rename from commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt rename to commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt index b3234d1f08..bd9f3ae050 100644 --- a/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserPictureImage.kt +++ b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt @@ -18,53 +18,27 @@ * 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.commons.ui.note +package com.vitorpamplona.amethyst.commons.ui.components -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.Dp -import com.vitorpamplona.amethyst.commons.resources.Res -import com.vitorpamplona.amethyst.commons.resources.profile_image -import com.vitorpamplona.amethyst.commons.resources.profile_image_of_user -import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage -import com.vitorpamplona.amethyst.commons.ui.stringRes -/** - * A user's round avatar: their picture when [loadProfilePicture] allows it, otherwise (or while - * loading / on error) their robohash, or a plain face icon when [loadRobohash] is off. - * Animated pictures play only when [autoPlayGif]. - */ @Composable -fun UserPictureImage( +internal actual fun AvatarImage( userHex: String, - userPicture: String?, - userName: String?, - size: Dp, + pictureUrl: String?, + contentDescription: String?, modifier: Modifier, loadProfilePicture: Boolean, loadRobohash: Boolean, autoPlayGif: Boolean, ) { - val myImageModifier = - remember { - modifier.size(size).clip(shape = CircleShape) - } - RobohashFallbackAsyncImage( robot = userHex, - model = userPicture, - contentDescription = - if (userName != null) { - stringRes(id = Res.string.profile_image_of_user, userName) - } else { - stringRes(id = Res.string.profile_image) - }, - modifier = myImageModifier, + model = pictureUrl, + contentDescription = contentDescription, + modifier = modifier, contentScale = ContentScale.Crop, loadProfilePicture = loadProfilePicture, loadRobohash = loadRobohash, diff --git a/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt index c1725fb28b..ff55834b65 100644 --- a/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt +++ b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/RobohashAsyncImage.kt @@ -54,7 +54,8 @@ import coil3.Image as CoilImage /** * Plays or pauses an animated avatar (GIF/AVIF) once Coil has decoded it. Android drives the - * decoded `Animatable` drawable; desktop has no such drawable, so it is a no-op there. + * decoded `Animatable` drawable; desktop decodes only the first frame, so there [autoPlay] has + * no effect. */ @Composable internal expect fun AnimatedImageAutoPlay( @@ -100,6 +101,7 @@ fun RobohashFallbackAsyncImage( loadRobohash: Boolean, autoPlayGif: Boolean = true, ) { + val useThumbnailCache = LocalProfilePictureCache.current if (model != null && loadProfilePicture && isAnimatedMediaUrl(model)) { GifProfilePicture( userHex = robot, @@ -123,12 +125,13 @@ fun RobohashFallbackAsyncImage( } SubcomposeAsyncImage( - // The thumbnail-cache fetcher behind ProfilePictureUrl delegates to Coil's http-only + // ProfilePictureUrl only loads where the host registered its thumbnail-cache fetcher + // (see LocalProfilePictureCache). That fetcher delegates to Coil's http-only // NetworkFetcher, so a LOCAL model (e.g. a decrypted Concord community icon cached at // file://) would fail there. Route only remote http(s) pictures through the thumbnail // cache; hand local/content URIs to Coil's native fetchers, which load them directly. model = - if (model.startsWith("http://", ignoreCase = true) || model.startsWith("https://", ignoreCase = true)) { + if (useThumbnailCache && (model.startsWith("http://", ignoreCase = true) || model.startsWith("https://", ignoreCase = true))) { ProfilePictureUrl(model) } else { model @@ -204,19 +207,26 @@ fun GifProfilePicture( } val context = LocalPlatformContext.current + val markForLocalBlossom = LocalProfilePictureCache.current // Animated avatars skip ProfilePictureFetcher (its thumbnail cache would flatten them), so - // they carry the profile-picture marker themselves for the local Blossom cache bridge. - val model = - remember(userPicture) { - ImageRequest - .Builder(context) - .data(userPicture) - .httpHeaders( - NetworkHeaders - .Builder() - .set(LocalBlossomCacheRedirectInterceptor.MEDIA_HEADER, LocalBlossomCacheRedirectInterceptor.PROFILE_PICTURE) - .build(), - ).build() + // they carry the profile-picture marker themselves for the local Blossom cache bridge. Only + // hosts that install that bridge (LocalProfilePictureCache) strip the marker before the + // request leaves; anywhere else it would reach the image server, so it is not added. + val model: Any = + remember(userPicture, markForLocalBlossom) { + if (markForLocalBlossom) { + ImageRequest + .Builder(context) + .data(userPicture) + .httpHeaders( + NetworkHeaders + .Builder() + .set(LocalBlossomCacheRedirectInterceptor.MEDIA_HEADER, LocalBlossomCacheRedirectInterceptor.PROFILE_PICTURE) + .build(), + ).build() + } else { + userPicture + } } Box(modifier = modifier) { diff --git a/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt index 3edd5be51c..27474a2773 100644 --- a/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt +++ b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt @@ -28,5 +28,6 @@ internal actual fun AnimatedImageAutoPlay( image: Image?, autoPlay: Boolean, ) { - // Desktop decodes animated avatars without a controllable drawable; nothing to toggle. + // Coil on desktop decodes only the first frame of a GIF/AVIF, so there is no animation to + // start or stop and autoPlay has no effect here. } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/composer/GifPickerPanel.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/composer/GifPickerPanel.kt index 66fff8317f..4d9a099214 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/composer/GifPickerPanel.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/composer/GifPickerPanel.kt @@ -49,10 +49,10 @@ import androidx.compose.ui.input.pointer.PointerIcon import androidx.compose.ui.input.pointer.pointerHoverIcon import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedGifUrl import com.vitorpamplona.amethyst.desktop.DesktopPreferences import com.vitorpamplona.amethyst.desktop.ui.deck.LocalRelayManager import com.vitorpamplona.amethyst.desktop.ui.media.AnimatedGifImage -import com.vitorpamplona.amethyst.desktop.ui.media.isAnimatedGifUrl import kotlinx.coroutines.delay /** diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/AnimatedGifImage.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/AnimatedGifImage.kt index 88f1abe5c2..b2013610dc 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/AnimatedGifImage.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/AnimatedGifImage.kt @@ -51,13 +51,6 @@ private const val MIN_FRAME_DURATION_MS = 20 private val gifHttpClient get() = DesktopHttpClient.currentClient() -fun isAnimatedGifUrl(url: String): Boolean { - val lower = url.lowercase() - return lower.endsWith(".gif") || - lower.contains(".gif?") || - lower.contains(".gif#") -} - private class GifFrames( val frames: List, val durations: List, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/PictureDisplay.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/PictureDisplay.kt index 59eb0475b6..a2eb2160c9 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/PictureDisplay.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/PictureDisplay.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedGifUrl import com.vitorpamplona.quartz.nip68Picture.PictureEvent /** diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/ZoomableImage.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/ZoomableImage.kt index e26094d955..b77677c697 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/ZoomableImage.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/media/ZoomableImage.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.input.pointer.PointerEventType import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.ContentScale import coil3.compose.AsyncImage +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedGifUrl @OptIn(ExperimentalComposeUiApi::class) @Composable diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/NoteCard.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/NoteCard.kt index 7c575eb267..35eb2de57b 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/NoteCard.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/NoteCard.kt @@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderFilterAssem import com.vitorpamplona.amethyst.commons.richtext.CachedRichTextParser import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.richtext.UrlParser +import com.vitorpamplona.amethyst.commons.richtext.isAnimatedGifUrl import com.vitorpamplona.amethyst.commons.ui.note.ReplyToLabel import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache import com.vitorpamplona.amethyst.desktop.ui.components.ToggleableTimeAgoText @@ -69,7 +70,6 @@ import com.vitorpamplona.amethyst.desktop.ui.media.AnimatedGifImage import com.vitorpamplona.amethyst.desktop.ui.media.AudioPlayer import com.vitorpamplona.amethyst.desktop.ui.media.DesktopVideoPlayer import com.vitorpamplona.amethyst.desktop.ui.media.LocalWindowState -import com.vitorpamplona.amethyst.desktop.ui.media.isAnimatedGifUrl import com.vitorpamplona.amethyst.desktop.ui.rememberDisplayData import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser import com.vitorpamplona.quartz.nip19Bech32.entities.NEvent diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/WoTBadgedAvatar.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/WoTBadgedAvatar.kt index 9e91f361b1..40953b745c 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/WoTBadgedAvatar.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/WoTBadgedAvatar.kt @@ -54,7 +54,6 @@ fun WoTBadgedAvatar( contentDescription: String? = null, loadProfilePicture: Boolean = true, loadRobohash: Boolean = true, - useThumbnailCache: Boolean = false, ) { val service = LocalWoTService.current val ready = LocalWoTReady.current @@ -75,7 +74,6 @@ fun WoTBadgedAvatar( contentDescription = contentDescription, loadProfilePicture = loadProfilePicture, loadRobohash = loadRobohash, - useThumbnailCache = useThumbnailCache, badge = if (score > 0) { { From 7f4f3cab3b0784d7b8aa2741e701e66836bf9683 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 01:32:12 +0000 Subject: [PATCH 3/9] fix: read backup-conflict labels through LocalResources Android lint's LocalContextGetResourceValueCall fails the build on rememberPresentation: context.getString is not configuration-aware. LocalResources.current invalidates on configuration changes, so the remembered labels follow a locale change. main fails the same lint. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../screen/loggedIn/backups/BackupConflictPresentation.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictPresentation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictPresentation.kt index 6c7772ba36..58195a5d31 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictPresentation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictPresentation.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.backups import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalResources import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType import com.vitorpamplona.quartz.concord.cord02Community.ConcordCommunityListDiff @@ -242,8 +242,8 @@ private fun arrow( */ @Composable fun rememberPresentation(diff: EventDiff): DiffPresentation { - val context = LocalContext.current - return remember(diff, context) { presentationOf(diff) { context.getString(it) } } + val resources = LocalResources.current + return remember(diff, resources) { presentationOf(diff) { resources.getString(it) } } } /** Turns each event's own diff into typed, labelled groups. [str] resolves the labels. */ From 78efe8901f3fb0ed1e76dbeaeec11355611a5137 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 02:17:29 +0000 Subject: [PATCH 4/9] refactor: share the per-note event observers The observeNote* family (note, event, reactions, zaps, reposts, replies, OTS, references, modifications, community approval) moves to commonsUI relayClient/event. Each takes the UserFinderAccount and the EventFinderFilterAssembler, defaulting to LocalUserFinderAccount and LocalEventFinder, so a shared composable needs only the note. The app's EventObservers keep their signatures and delegate with the account and data source from AccountViewModel, so call sites are unchanged and Activity roots without the locals keep working. isMinichatReply (pure quartz) moves to commons model/chats, and its test to commonTest with kotlin.test. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../vitorpamplona/amethyst/model/Account.kt | 2 +- .../reqCommand/event/EventObservers.kt | 401 ++------------ .../chats/minichat/MinichatFeedViewModel.kt | 2 +- .../publicChannels/dal/ChannelFeedFilter.kt | 2 +- .../relayGroup/RelayGroupUnread.kt | 2 +- .../loggedIn/redirect/LoadRedirectScreen.kt | 2 +- .../commons/model}/chats/MinichatReply.kt | 2 +- .../commons/model}/chats/MinichatReplyTest.kt | 8 +- .../relayClient/event/EventObservers.kt | 516 ++++++++++++++++++ 9 files changed, 570 insertions(+), 367 deletions(-) rename {amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model}/chats/MinichatReply.kt (98%) rename {amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn => commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/model}/chats/MinichatReplyTest.kt (96%) create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/event/EventObservers.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 3ba243658a..85b79bd3c9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -2048,7 +2048,7 @@ class Account( // blessed status. 40002 survives only as a read-compat tail from the // 10002 -> 40001 -> 40002 migration, so we were the last active writer of a kind // their clients no longer thread on. Reading 40002 stays supported (see - // [com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply]). + // [com.vitorpamplona.amethyst.commons.model.chats.isMinichatReply]). // // Attached media rides as URLs appended to the content. val root = rootEvent.tags.buzzThreadRoot() ?: rootEvent.tags.buzzThreadReply() ?: rootEvent.id diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/EventObservers.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/EventObservers.kt index cde6322ad4..33e77422c6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/EventObservers.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/event/EventObservers.kt @@ -22,465 +22,152 @@ package com.vitorpamplona.amethyst.service.relayClient.reqCommand.event import androidx.compose.runtime.Composable import androidx.compose.runtime.State -import androidx.compose.runtime.produceState -import androidx.compose.runtime.remember -import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.NoteState import com.vitorpamplona.amethyst.commons.model.User -import com.vitorpamplona.amethyst.commons.model.textNoteModifications import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent -import com.vitorpamplona.quartz.nip18Reposts.RepostEvent -import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent -import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent -import com.vitorpamplona.quartz.nip72ModCommunities.isForCommunity -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.flow.sample +import com.vitorpamplona.amethyst.commons.relayClient.event.observeCommunityApprovalNeedStatus as sharedObserveCommunityApprovalNeedStatus +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNote as sharedObserveNote +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteAndMap as sharedObserveNoteAndMap +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteEvent as sharedObserveNoteEvent +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteEventAndMap as sharedObserveNoteEventAndMap +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteEventAndMapNotNull as sharedObserveNoteEventAndMapNotNull +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteHasEvent as sharedObserveNoteHasEvent +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteMinichatReplyCount as sharedObserveNoteMinichatReplyCount +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteModifications as sharedObserveNoteModifications +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteOts as sharedObserveNoteOts +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReactionCount as sharedObserveNoteReactionCount +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReactions as sharedObserveNoteReactions +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReferences as sharedObserveNoteReferences +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReplies as sharedObserveNoteReplies +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReplyCount as sharedObserveNoteReplyCount +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteRepostCount as sharedObserveNoteRepostCount +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteReposts as sharedObserveNoteReposts +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteRepostsBy as sharedObserveNoteRepostsBy +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteZaps as sharedObserveNoteZaps + +/* + * Android overloads of the shared per-note observers in commons `relayClient/event`: they take the + * account and event-finder data source from [AccountViewModel] instead of the composition locals, + * so they also work under Activity roots that don't provide those locals. + */ @Composable fun observeNote( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNote(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().metadata.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -/** - * [observeNote] without the relay half: watches LocalCache and asks no relay for the note. - * - * For a NIP-17 rumor, which has no fetchable id — putting one in a REQ would tell relays the - * private event's identity, the leak [com.vitorpamplona.amethyst.commons.model.Note.isPrivateRumor] - * guards everywhere else. Nothing is lost by not asking: a rumor only ever reaches the cache by - * unwrapping the envelope that carried it, and the always-on gift-wrap tail re-fetches a week of - * those on every cold start, so this flow fires on its own once the envelope lands. - */ -@Composable -fun observeNoteLocally(note: Note): State { - val flow = remember(note) { note.flow().metadata.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -@OptIn(ExperimentalCoroutinesApi::class) @Composable inline fun observeNoteEvent( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteEvent(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .metadata.stateFlow - .mapLatest { it.note.event as? T? } - } - - return flow.collectAsStateWithLifecycle(note.event as? T?) -} - -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeNoteAndMap( note: Note, accountViewModel: AccountViewModel, map: (Note) -> T, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteAndMap(note, accountViewModel.account, accountViewModel.dataSources().eventFinder, map) - val flow = - remember(note) { - note - .flow() - .metadata.stateFlow - .mapLatest { map(it.note) } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - // Subscribe in the LocalCache for changes that arrive in the device - return flow.collectAsStateWithLifecycle(map(note)) -} - -@OptIn(ExperimentalCoroutinesApi::class) -@Suppress("UNCHECKED_CAST") @Composable fun observeNoteEventAndMapNotNull( note: Note, accountViewModel: AccountViewModel, map: (T) -> U, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteEventAndMapNotNull(note, accountViewModel.account, accountViewModel.dataSources().eventFinder, map) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .metadata.stateFlow - .mapLatest { (it.note.event as? T)?.let { map(it) } } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - // Subscribe in the LocalCache for changes that arrive in the device - return flow.collectAsStateWithLifecycle((note.event as? T)?.let { map(it) }) -} - -@OptIn(ExperimentalCoroutinesApi::class) -@Suppress("UNCHECKED_CAST") @Composable fun observeNoteEventAndMap( note: Note, accountViewModel: AccountViewModel, map: (T?) -> U, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteEventAndMap(note, accountViewModel.account, accountViewModel.dataSources().eventFinder, map) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .metadata.stateFlow - .mapLatest { map(it.note.event as? T) } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - // Subscribe in the LocalCache for changes that arrive in the device - return flow.collectAsStateWithLifecycle(map(note.event as? T)) -} - -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeNoteHasEvent( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .metadata.stateFlow - .mapLatest { it.note.event != null } - .distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle(note.event != null) -} +): State = sharedObserveNoteHasEvent(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteReplies( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteReplies(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().replies.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable fun observeNoteReplyCount( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteReplyCount(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .replies.stateFlow - .sample(200) - .mapLatest { it.note.replies.size } - .distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle(note.replies.size) -} - -/** - * Count of a chat message's **minichat** replies — its kind-1111 [CommentEvent] - * children only (inline quote-replies are ordinary kind-9/42 messages and are not - * counted here). Drives the "N replies" chip that opens the minichat. - * - * Mounting this registers the message with [EventFinderFilterAssemblerSubscription], which - * batches the visible messages' ids into shared REQs for their replies (kind-1111 among - * them) — so for public chats (NIP-28/NIP-29) the thread replies load, and the chip appears, - * just by rendering the rows. Concord's kind-1111 replies instead arrive over the channel - * plane, so that REQ finds nothing there and is a harmless no-op. - */ -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable fun observeNoteMinichatReplyCount( note: Note, accountViewModel: AccountViewModel, -): State { - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - val flow = - remember(note) { - note - .flow() - .replies.stateFlow - .sample(200) - .mapLatest { it.note.replies.count { reply -> isMinichatReply(reply.event) } } - .distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle(note.replies.count { isMinichatReply(it.event) }) -} +): State = sharedObserveNoteMinichatReplyCount(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteReactions( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteReactions(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().reactions.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable fun observeNoteReactionCount( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .reactions.stateFlow - .sample(200) - .mapLatest { it.note.countReactions() } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - // Subscribe in the LocalCache for changes that arrive in the device - return flow.collectAsStateWithLifecycle(note.countReactions()) -} +): State = sharedObserveNoteReactionCount(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteZaps( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().zaps.stateFlow } - return flow.collectAsStateWithLifecycle() -} +): State = sharedObserveNoteZaps(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteReposts( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteReposts(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().boosts.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -@OptIn(ExperimentalCoroutinesApi::class) @Composable fun observeNoteRepostsBy( note: Note, user: User, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteRepostsBy(note, user, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .boosts.stateFlow - .mapLatest { it.note.isBoostedBy(user) } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - return flow.collectAsStateWithLifecycle(note.isBoostedBy(user)) -} - -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable fun observeNoteRepostCount( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note) { - note - .flow() - .boosts.stateFlow - .sample(200) - .mapLatest { note.boosts.size } - .distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle(note.boosts.size) -} +): State = sharedObserveNoteRepostCount(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteReferences( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device. - // On-chain zaps piggyback `note.flow().zaps.stateFlow` because Note.addOnchainZap - // invalidates the same `flowSet.zaps`. If that ever moves to a dedicated flow, - // add it here too — otherwise on-chain-only notes will stop pinging the chevron. - val flow = - remember(note) { - combine( - note.flow().zaps.stateFlow, - note.flow().boosts.stateFlow, - note.flow().reactions.stateFlow, - ) { zapState, _, _ -> - zapState.note.hasZapsBoostsOrReactions() - }.distinctUntilChanged() - } - - return flow.collectAsStateWithLifecycle(note.hasZapsBoostsOrReactions()) -} +): State = sharedObserveNoteReferences(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeNoteOts( note: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) +): State = sharedObserveNoteOts(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) - // Subscribe in the LocalCache for changes that arrive in the device - val flow = remember(note) { note.flow().ots.stateFlow } - return flow.collectAsStateWithLifecycle() -} - -// Resolves the actual modification list off the main thread and filters identical results, -// so the caller's LaunchedEffect only fires when the list of edits truly changes. -// `sample(500)` collapses bursts — a heavily-edited note can emit hundreds of times during -// initial relay sync, and we only need the last state per ~half second. -// Returns `null` until the first IO resolution completes — callers should treat that as -// "still loading" and not flip their UI to "no edits". -@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @Composable fun observeNoteModifications( note: Note, accountViewModel: AccountViewModel, -): State?> { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - return produceState?>(initialValue = null, note) { - note - .flow() - .edits - .stateFlow - .sample(500) - .mapLatest { note.textNoteModifications() } - .distinctUntilChanged() - .flowOn(Dispatchers.IO) - .collect { value = it } - } -} +): State?> = sharedObserveNoteModifications(note, accountViewModel.account, accountViewModel.dataSources().eventFinder) @Composable fun observeCommunityApprovalNeedStatus( note: Note, community: Note, accountViewModel: AccountViewModel, -): State { - // Subscribe in the relay for changes in this note. - EventFinderFilterAssemblerSubscription(note, accountViewModel) - - // Subscribe in the LocalCache for changes that arrive in the device - val flow = - remember(note, community) { - combine( - community.flow().metadata.stateFlow, - note.flow().boosts.stateFlow, - ) { communityMetadata, boosts -> - (communityMetadata.note.event as? CommunityDefinitionEvent)?.let { communityDefEvent -> - val moderators = communityDefEvent.moderatorKeys().toSet() - - if (note.author?.pubkeyHex in moderators) { - false - } else { - val isModerator = accountViewModel.account.userProfile().pubkeyHex in moderators - - if (isModerator) { - val wasAlreadyApproved = - note.boosts.any { - val approvalEvent = it.event - (approvalEvent is CommunityPostApprovalEvent || approvalEvent is RepostEvent || approvalEvent is GenericRepostEvent) && - approvalEvent.pubKey in moderators && - approvalEvent.isForCommunity(community.idHex) - } - !wasAlreadyApproved - } else { - false - } - } - } - }.distinctUntilChanged() - .flowOn(Dispatchers.IO) - } - - // Subscribe in the LocalCache for changes that arrive in the device - return flow.collectAsStateWithLifecycle(false) -} +): State = sharedObserveCommunityApprovalNeedStatus(note, community, accountViewModel.account, accountViewModel.dataSources().eventFinder) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatFeedViewModel.kt index 4c261853bd..4d26fdc2fd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatFeedViewModel.kt @@ -24,8 +24,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.chats.isMinichatReply import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.SharingStarted diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/dal/ChannelFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/dal/ChannelFeedFilter.kt index b2f6b23c37..f656839204 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/dal/ChannelFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/dal/ChannelFeedFilter.kt @@ -24,9 +24,9 @@ import com.vitorpamplona.amethyst.commons.feeds.AdditiveFeedFilter import com.vitorpamplona.amethyst.commons.feeds.ChangesFlowFilter import com.vitorpamplona.amethyst.commons.model.Channel import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.chats.isMinichatReply import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.dal.sortedByDefaultFeedOrder -import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply class ChannelFeedFilter( val channel: Channel, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt index 37105e8a5c..3937effabe 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupUnread.kt @@ -22,10 +22,10 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.relay import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.chats.isMinichatReply import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.dal.sortedByDefaultFeedOrder -import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.isMinichatReply import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip29RelayGroups.GroupId diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt index 5c25c80a54..a2060f9e78 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteLocally import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.looking_for_event import com.vitorpamplona.amethyst.commons.resources.looking_for_event_title @@ -44,7 +45,6 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteLocally import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.navs.Nav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReply.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReply.kt similarity index 98% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReply.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReply.kt index c6b8d8d4f9..1e97f7e0a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReply.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReply.kt @@ -18,7 +18,7 @@ * 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.screen.loggedIn.chats +package com.vitorpamplona.amethyst.commons.model.chats import com.vitorpamplona.quartz.buzz.stream.StreamMessageV2Event import com.vitorpamplona.quartz.buzz.threading.buzzThreadReply diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReplyTest.kt b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReplyTest.kt similarity index 96% rename from amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReplyTest.kt rename to commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReplyTest.kt index acb9de2a98..27e0a33c10 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/MinichatReplyTest.kt +++ b/commons/src/commonTest/kotlin/com/vitorpamplona/amethyst/commons/model/chats/MinichatReplyTest.kt @@ -18,12 +18,12 @@ * 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.screen.loggedIn.chats +package com.vitorpamplona.amethyst.commons.model.chats import com.vitorpamplona.quartz.nipC7Chats.ChatEvent -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Test +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue /** * A kind-9 chat message is a thread reply only when its `e` tag carries a NIP-10 marker. diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/event/EventObservers.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/event/EventObservers.kt new file mode 100644 index 0000000000..d105d02d99 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/event/EventObservers.kt @@ -0,0 +1,516 @@ +/* + * 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.commons.relayClient.event + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.produceState +import androidx.compose.runtime.remember +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.NoteState +import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.chats.isMinichatReply +import com.vitorpamplona.amethyst.commons.model.textNoteModifications +import com.vitorpamplona.amethyst.commons.relayClient.user.LocalUserFinderAccount +import com.vitorpamplona.amethyst.commons.relayClient.user.UserFinderAccount +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent +import com.vitorpamplona.quartz.nip18Reposts.RepostEvent +import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent +import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent +import com.vitorpamplona.quartz.nip72ModCommunities.isForCommunity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.IO +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.sample + +/* + * Per-note observers: each subscribes [note] with the relay event finder (batched with every other + * on-screen note) and exposes a LocalCache flow of the note as Compose state. + * + * [account] and [dataSource] default to the front end's [LocalUserFinderAccount] and + * [LocalEventFinder], so a shared composable needs only the note. Callers outside a composition + * that provides them (a separate Activity root) pass both explicitly. + */ + +@Composable +fun observeNote( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().metadata.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +/** + * [observeNote] without the relay half: watches LocalCache and asks no relay for the note. + * + * For a NIP-17 rumor, which has no fetchable id — putting one in a REQ would tell relays the + * private event's identity, the leak [com.vitorpamplona.amethyst.commons.model.Note.isPrivateRumor] + * guards everywhere else. Nothing is lost by not asking: a rumor only ever reaches the cache by + * unwrapping the envelope that carried it, and the always-on gift-wrap tail re-fetches a week of + * those on every cold start, so this flow fires on its own once the envelope lands. + */ +@Composable +fun observeNoteLocally(note: Note): State { + val flow = remember(note) { note.flow().metadata.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Composable +inline fun observeNoteEvent( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .metadata.stateFlow + .mapLatest { it.note.event as? T? } + } + + return flow.collectAsStateWithLifecycle(note.event as? T?) +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Composable +fun observeNoteAndMap( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, + map: (Note) -> T, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + val flow = + remember(note) { + note + .flow() + .metadata.stateFlow + .mapLatest { map(it.note) } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + // Subscribe in the LocalCache for changes that arrive in the device + return flow.collectAsStateWithLifecycle(map(note)) +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Suppress("UNCHECKED_CAST") +@Composable +fun observeNoteEventAndMapNotNull( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, + map: (T) -> U, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .metadata.stateFlow + .mapLatest { (it.note.event as? T)?.let { map(it) } } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + // Subscribe in the LocalCache for changes that arrive in the device + return flow.collectAsStateWithLifecycle((note.event as? T)?.let { map(it) }) +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Suppress("UNCHECKED_CAST") +@Composable +fun observeNoteEventAndMap( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, + map: (T?) -> U, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .metadata.stateFlow + .mapLatest { map(it.note.event as? T) } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + // Subscribe in the LocalCache for changes that arrive in the device + return flow.collectAsStateWithLifecycle(map(note.event as? T)) +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Composable +fun observeNoteHasEvent( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .metadata.stateFlow + .mapLatest { it.note.event != null } + .distinctUntilChanged() + } + + return flow.collectAsStateWithLifecycle(note.event != null) +} + +@Composable +fun observeNoteReplies( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().replies.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) +@Composable +fun observeNoteReplyCount( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .replies.stateFlow + .sample(200) + .mapLatest { it.note.replies.size } + .distinctUntilChanged() + } + + return flow.collectAsStateWithLifecycle(note.replies.size) +} + +/** + * Count of a chat message's **minichat** replies — its kind-1111 [CommentEvent] + * children only (inline quote-replies are ordinary kind-9/42 messages and are not + * counted here). Drives the "N replies" chip that opens the minichat. + * + * Mounting this registers the message with [EventFinderFilterAssemblerSubscription], which + * batches the visible messages' ids into shared REQs for their replies (kind-1111 among + * them) — so for public chats (NIP-28/NIP-29) the thread replies load, and the chip appears, + * just by rendering the rows. Concord's kind-1111 replies instead arrive over the channel + * plane, so that REQ finds nothing there and is a harmless no-op. + */ +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) +@Composable +fun observeNoteMinichatReplyCount( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + val flow = + remember(note) { + note + .flow() + .replies.stateFlow + .sample(200) + .mapLatest { it.note.replies.count { reply -> isMinichatReply(reply.event) } } + .distinctUntilChanged() + } + + return flow.collectAsStateWithLifecycle(note.replies.count { isMinichatReply(it.event) }) +} + +@Composable +fun observeNoteReactions( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().reactions.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) +@Composable +fun observeNoteReactionCount( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .reactions.stateFlow + .sample(200) + .mapLatest { it.note.countReactions() } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + // Subscribe in the LocalCache for changes that arrive in the device + return flow.collectAsStateWithLifecycle(note.countReactions()) +} + +@Composable +fun observeNoteZaps( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().zaps.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +@Composable +fun observeNoteReposts( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().boosts.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Composable +fun observeNoteRepostsBy( + note: Note, + user: User, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .boosts.stateFlow + .mapLatest { it.note.isBoostedBy(user) } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + return flow.collectAsStateWithLifecycle(note.isBoostedBy(user)) +} + +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) +@Composable +fun observeNoteRepostCount( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note) { + note + .flow() + .boosts.stateFlow + .sample(200) + .mapLatest { note.boosts.size } + .distinctUntilChanged() + } + + return flow.collectAsStateWithLifecycle(note.boosts.size) +} + +@Composable +fun observeNoteReferences( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device. + // On-chain zaps piggyback `note.flow().zaps.stateFlow` because Note.addOnchainZap + // invalidates the same `flowSet.zaps`. If that ever moves to a dedicated flow, + // add it here too — otherwise on-chain-only notes will stop pinging the chevron. + val flow = + remember(note) { + combine( + note.flow().zaps.stateFlow, + note.flow().boosts.stateFlow, + note.flow().reactions.stateFlow, + ) { zapState, _, _ -> + zapState.note.hasZapsBoostsOrReactions() + }.distinctUntilChanged() + } + + return flow.collectAsStateWithLifecycle(note.hasZapsBoostsOrReactions()) +} + +@Composable +fun observeNoteOts( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = remember(note) { note.flow().ots.stateFlow } + return flow.collectAsStateWithLifecycle() +} + +// Resolves the actual modification list off the main thread and filters identical results, +// so the caller's LaunchedEffect only fires when the list of edits truly changes. +// `sample(500)` collapses bursts — a heavily-edited note can emit hundreds of times during +// initial relay sync, and we only need the last state per ~half second. +// Returns `null` until the first IO resolution completes — callers should treat that as +// "still loading" and not flip their UI to "no edits". +@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) +@Composable +fun observeNoteModifications( + note: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State?> { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + return produceState?>(initialValue = null, note) { + note + .flow() + .edits + .stateFlow + .sample(500) + .mapLatest { note.textNoteModifications() } + .distinctUntilChanged() + .flowOn(Dispatchers.IO) + .collect { value = it } + } +} + +@Composable +fun observeCommunityApprovalNeedStatus( + note: Note, + community: Note, + account: UserFinderAccount = LocalUserFinderAccount.current, + dataSource: EventFinderFilterAssembler = LocalEventFinder.current, +): State { + // Subscribe in the relay for changes in this note. + EventFinderFilterAssemblerSubscription(note, account, dataSource) + + // Subscribe in the LocalCache for changes that arrive in the device + val flow = + remember(note, community) { + combine( + community.flow().metadata.stateFlow, + note.flow().boosts.stateFlow, + ) { communityMetadata, boosts -> + (communityMetadata.note.event as? CommunityDefinitionEvent)?.let { communityDefEvent -> + val moderators = communityDefEvent.moderatorKeys().toSet() + + if (note.author?.pubkeyHex in moderators) { + false + } else { + val isModerator = account.userFinderPubkeyHex in moderators + + if (isModerator) { + val wasAlreadyApproved = + note.boosts.any { + val approvalEvent = it.event + (approvalEvent is CommunityPostApprovalEvent || approvalEvent is RepostEvent || approvalEvent is GenericRepostEvent) && + approvalEvent.pubKey in moderators && + approvalEvent.isForCommunity(community.idHex) + } + !wasAlreadyApproved + } else { + false + } + } + } + }.distinctUntilChanged() + .flowOn(Dispatchers.IO) + } + + // Subscribe in the LocalCache for changes that arrive in the device + return flow.collectAsStateWithLifecycle(false) +} From bc44d87011425cc4aaff52f7ec687b07d7e9ff1e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 03:27:03 +0000 Subject: [PATCH 5/9] test: wait for CalendarsViewModel scopes before resetMain The calendar ViewModel tests cleared their store and then reset Main, but clearing only requests cancellation. The model's flowOn producers on Dispatchers.Default could still be finishing, and handing their completion back to the Main collector after resetMain threw "The main looper is not available" onto a background thread. runTest then failed whichever test started next with UncaughtExceptionsBeforeTest (seen on CI as Nip46ConsentInfoBuilderTest). Both tests now join the models' viewModelScope jobs before resetMain. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../calendar/CalendarsViewModelFlowTest.kt | 10 ++++++++ .../calendar/CalendarsViewModelTest.kt | 23 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt index 1a7920efdc..e504817753 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.calendar import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStore +import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.cache.LocalCache @@ -33,13 +34,16 @@ import com.vitorpamplona.quartz.nip52Calendar.calendar.CalendarEvent import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.first +import kotlinx.coroutines.job import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain +import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeoutOrNull import org.junit.After import org.junit.Assert.assertEquals @@ -137,14 +141,20 @@ class CalendarsViewModelFlowTest { ) = runBlocking { val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) val store = ViewModelStore() + var modelScope: Job? = null try { val feed = FeedContentState(CalendarAppointmentsFeedFilter(seeEverythingAccount()), scope, LocalCache) val model = ViewModelProvider(store, ViewModelProvider.NewInstanceFactory())[CalendarsViewModel::class.java] + modelScope = model.viewModelScope.coroutineContext.job model.init(pubKey, feed) block(model) } finally { store.clear() scope.cancel() + // Clearing only requests cancellation. The flowOn producers on Dispatchers.Default can + // still be finishing and hand their completion back to the Main collectors; wait for + // them here, while setMain is still in force, not after tearDown's resetMain. + withTimeout(AWAIT_MS) { modelScope?.join() } } } diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelTest.kt index 770e0add94..1358a9f67d 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelTest.kt @@ -22,13 +22,19 @@ package com.vitorpamplona.amethyst.calendar import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStore +import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.CalendarsViewMode import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.CalendarsViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.startOfWeek import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.job +import kotlinx.coroutines.joinAll +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain +import kotlinx.coroutines.withTimeout import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNull @@ -58,13 +64,24 @@ class CalendarsViewModelTest { store = ViewModelStore() } + private val scopes = mutableListOf() + @After fun tearDown() { store.clear() + // Clearing only requests cancellation: a producer the model runs on Dispatchers.Default + // (its flowOn) can still be finishing, and it hands its completion back to the Main + // collector. Waiting for the scopes keeps that inside setMain, instead of throwing onto a + // background thread after resetMain and failing whichever runTest starts next. + runBlocking { withTimeout(SCOPE_CLOSE_MS) { scopes.joinAll() } } + scopes.clear() Dispatchers.resetMain() } - private fun newModel(): CalendarsViewModel = ViewModelProvider(store, ViewModelProvider.NewInstanceFactory())[CalendarsViewModel::class.java] + private fun newModel(): CalendarsViewModel = + ViewModelProvider(store, ViewModelProvider.NewInstanceFactory())[CalendarsViewModel::class.java].also { + scopes += it.viewModelScope.coroutineContext.job + } @Test fun aFreshScreenOpensOnToday() { @@ -148,4 +165,8 @@ class CalendarsViewModelTest { assertEquals("the lenses must not share one scroll offset", 4, states.distinct().size) } + + companion object { + private const val SCOPE_CLOSE_MS = 5_000L + } } From 97136c22676ef0b6b035e9f966b67e97933a367c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 12:39:24 +0000 Subject: [PATCH 6/9] refactor: share SafeImeInsets, DisappearingScaffold, emoji text and the user name text - SafeImeInsets moves to commonsUI androidMain unchanged; its test moves to androidHostTest. rememberSafeImeInsets() is now an expect returning WindowInsets (WindowInsets.ime on desktop and iOS), and Modifier.imePaddingSafe() is shared in commonMain. 82 app files repoint their imports. - DisappearingScaffold moves to commonsUI commonMain. The account read becomes an immersiveScrolling lambda and the large-screen pin folds into allowBarHide; the app keeps a wrapper with the old signature, so its callers are unchanged. The OS status-bar hiding is an expect with an Android actual and a no-op on desktop and iOS. getActivityWindow and getDialogWindow move to commonsUI androidMain for it. - CustomEmojiChecker, CreateTextWithEmoji, the route-less CreateClickableTextWithEmoji and ClickableInLineIconRenderer move next to the shared InLineIconRenderer, which gains maxLines/overflow. The app's own InLineIconRenderer copy is deleted: it remembered its text with no keys, so a slot whose emoji list changed kept the old text. - UsernameDisplay's display half becomes commonsUI UserNameText (name with emojis, or the npub fallback, now remembered per user). The app keeps the petname and crossfade reads. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../ui/insets/ComposeImeInsetWedgeTest.kt | 4 +- .../playback/composable/RenderVideoPlayer.kt | 2 +- .../amethyst/ui/actions/EditPostView.kt | 2 +- .../amethyst/ui/actions/NewMediaView.kt | 2 +- .../ui/actions/NewUserMetadataScreen.kt | 2 +- .../bolt12Offers/Bolt12OffersScreen.kt | 2 +- .../mediaServers/AllMediaServersScreen.kt | 2 +- .../nestsServers/NestsServersScreen.kt | 2 +- .../paymentTargets/PaymentTargetsScreen.kt | 2 +- .../amethyst/ui/components/ClickableRoute.kt | 364 +----------------- .../amethyst/ui/components/RichTextViewer.kt | 2 + .../ui/components/SetDialogToEdgeToEdge.kt | 1 + .../amethyst/ui/components/WindowUtils.kt | 18 - .../ui/components/ZoomableContentDialog.kt | 2 + .../ui/components/pdf/PdfViewerDialog.kt | 2 +- .../ui/layouts/DisappearingScaffold.kt | 353 +---------------- .../ui/navigation/bottombars/KeyboardState.kt | 3 +- .../drawer/AccountSwitchBottomSheet.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 2 +- .../amethyst/ui/navigation/navs/ImeSettler.kt | 3 +- .../amethyst/ui/note/MultiSetCompose.kt | 2 +- .../ui/note/NIP05VerificationDisplay.kt | 2 +- .../amethyst/ui/note/ReactionsRow.kt | 2 +- .../amethyst/ui/note/ReplyInformation.kt | 1 + .../ui/note/UpdateReactionTypeDialog.kt | 4 +- .../amethyst/ui/note/UpdateZapAmountDialog.kt | 2 +- .../amethyst/ui/note/UsernameDisplay.kt | 61 +-- .../amethyst/ui/note/ZapCustomDialog.kt | 2 +- .../location/GeohashLocationPickerDialog.kt | 2 +- .../nip22Comments/GenericCommentPostScreen.kt | 2 +- .../amethyst/ui/note/types/AppDefinition.kt | 2 +- .../amethyst/ui/note/types/Highlight.kt | 1 + .../amethyst/ui/note/types/ProfileCard.kt | 2 +- .../backups/BackupConflictReviewScreen.kt | 2 +- .../loggedIn/badges/award/AwardBadgeScreen.kt | 2 +- .../loggedIn/badges/post/NewBadgeDialog.kt | 2 +- .../display/BookmarkGroupScreen.kt | 2 +- .../metadata/BookmarkGroupMetadataScreen.kt | 2 +- .../ArticleBookmarkListManagementScreen.kt | 2 +- .../PostBookmarkListManagementScreen.kt | 2 +- .../create/NewCalendarCollectionScreen.kt | 2 +- .../create/NewCalendarEventScreen.kt | 2 +- .../detail/CalendarEventDetailScreen.kt | 2 +- .../loggedIn/chats/feed/ChatReactionChips.kt | 2 +- .../loggedIn/chats/feed/DrawAuthorInfo.kt | 2 +- .../chats/geohashChat/GeohashChatScreen.kt | 2 +- .../chats/geohashChat/NewGeohashChatScreen.kt | 2 +- .../chats/marmotGroup/CreateGroupScreen.kt | 2 +- .../chats/marmotGroup/EditGroupInfoScreen.kt | 2 +- .../marmotGroup/MarmotGroupInfoScreen.kt | 2 +- .../loggedIn/chats/minichat/MinichatScreen.kt | 2 +- .../privateDM/header/RoomNameOnlyDisplay.kt | 2 +- .../chats/privateDM/send/NewGroupDMScreen.kt | 2 +- .../concord/ConcordChannelScreen.kt | 2 +- .../metadata/NewEphemeralChatScreen.kt | 2 +- .../header/LongPublicChatChannelHeader.kt | 2 +- .../metadata/ChannelMetadataScreen.kt | 2 +- .../relayGroup/RelayGroupMembersScreen.kt | 2 +- .../relayGroup/RelayGroupMetadataScreen.kt | 2 +- .../chats/rooms/twopane/MessagesTwoPane.kt | 2 +- .../chats/utils/ChatFileUploadDialog.kt | 2 +- .../newCommunity/NewCommunityScreen.kt | 2 +- .../nip23LongForm/LongFormPostScreen.kt | 2 +- .../nip99Classifieds/NewProductScreen.kt | 2 +- .../list/metadata/EmojiPackMetadataScreen.kt | 2 +- .../EmojiPackSelectionScreen.kt | 2 +- .../geocaches/create/NewGeocacheScreen.kt | 2 +- .../geocaches/detail/GeocacheDetailScreen.kt | 2 +- .../geocaches/hunt/GeocacheHuntScreen.kt | 2 +- .../geocaches/hunt/NewGeocacheHuntScreen.kt | 2 +- .../geocaches/log/LogGeocacheFindScreen.kt | 2 +- .../loggedIn/highlights/NewHighlightScreen.kt | 2 +- .../loggedIn/home/ShortNotePostScreen.kt | 2 +- .../loggedIn/home/nip75Goals/NewGoalScreen.kt | 2 +- .../metadata/InterestSetMetadataScreen.kt | 2 +- .../lists/display/lists/PeopleListScreen.kt | 2 +- .../lists/display/packs/FollowPackScreen.kt | 2 +- .../list/metadata/FollowPackMetadataScreen.kt | 2 +- .../list/metadata/PeopleListMetadataScreen.kt | 2 +- .../FollowListAndPackAndUserScreen.kt | 2 +- .../loggedIn/music/AddToMusicPlaylistSheet.kt | 2 +- .../loggedIn/music/NewMusicPlaylistScreen.kt | 2 +- .../loggedIn/music/NewMusicTrackScreen.kt | 2 +- .../loggedIn/nests/room/edit/EditNestSheet.kt | 2 +- .../nests/room/lobby/NestLobbyScreen.kt | 2 +- .../nests/room/screen/NestFullScreen.kt | 2 +- .../room/stage/SpeakerReactionOverlay.kt | 2 +- .../publicMessages/NewPublicMessageScreen.kt | 2 +- .../authoring/EditPodcastShowScreen.kt | 2 +- .../authoring/NewPodcastEpisodeScreen.kt | 2 +- .../authoring/NewPodcastTrailerScreen.kt | 2 +- .../profile/header/DrawAdditionalInfo.kt | 2 +- .../profile/header/UserNicknameCard.kt | 2 +- .../profile/payment/SendPaymentContent.kt | 2 +- .../qrcode/KeepScreenBrightAndAwake.kt | 2 +- .../ui/screen/loggedIn/qrcode/ShowQRScreen.kt | 4 +- .../loggedIn/relays/AllRelayListScreen.kt | 2 +- .../loggedIn/settings/HiddenWordsScreen.kt | 2 +- .../wallet/AddClinkDebitWalletScreen.kt | 2 +- .../loggedIn/wallet/AddNwcWalletScreen.kt | 2 +- .../wallet/CashuMintRecommendationsScreen.kt | 2 +- .../loggedIn/wallet/CashuMintsScreen.kt | 2 +- .../wallet/CashuWalletSettingsScreen.kt | 2 +- .../loggedIn/wallet/OnchainZapSendDialog.kt | 2 +- .../loggedIn/workouts/NewWorkoutScreen.kt | 2 +- .../ui/screen/loggedOff/login/LoginScreen.kt | 2 +- .../screen/loggedOff/signup/SignUpScreen.kt | 2 +- commonsUI/build.gradle.kts | 3 + .../commons}/ui/insets/SafeImeInsetsTest.kt | 2 +- .../ui/components/WindowUtils.android.kt | 43 +++ .../ui/insets/SafeImeInsets.android.kt | 16 +- .../ImmersiveStatusBarEffect.android.kt | 99 +++++ .../commons/ui/insets/SafeImeInsets.kt | 46 +++ .../ui/layouts/DisappearingScaffold.kt | 309 +++++++++++++++ .../amethyst/commons/ui/note/UserNameText.kt | 73 ++++ .../ui/richtext/CustomEmojiRenderer.kt | 293 ++++++++++++++ .../commons/ui/insets/SafeImeInsets.skiko.kt | 28 ++ .../layouts/ImmersiveStatusBarEffect.skiko.kt | 27 ++ 118 files changed, 1061 insertions(+), 885 deletions(-) rename {amethyst/src/test/java/com/vitorpamplona/amethyst => commonsUI/src/androidHostTest/kotlin/com/vitorpamplona/amethyst/commons}/ui/insets/SafeImeInsetsTest.kt (99%) create mode 100644 commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/WindowUtils.android.kt rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsets.kt => commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.android.kt (94%) create mode 100644 commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.android.kt create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.kt create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/DisappearingScaffold.kt create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserNameText.kt create mode 100644 commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.skiko.kt create mode 100644 commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.skiko.kt diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ui/insets/ComposeImeInsetWedgeTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ui/insets/ComposeImeInsetWedgeTest.kt index b6ef4068fd..0707b29f87 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ui/insets/ComposeImeInsetWedgeTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ui/insets/ComposeImeInsetWedgeTest.kt @@ -61,11 +61,11 @@ import org.junit.Test * [aCancelledImeAnimationMustNotWedgeTheAnimatedInset] FAILS on every version from 1.4.0 on, so it * is [Ignore]d to keep CI green. It is not a test of Amethyst code — it is the upstream repro we * attached to the bug. **Re-run it by hand after every Compose upgrade**: when it passes, the - * upstream fix has landed and [com.vitorpamplona.amethyst.ui.insets.SafeImeInsets] can be retired. + * upstream fix has landed and [com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] can be retired. * * [theAnimationTargetSurvivesTheWedge] documents the asymmetry that makes a workaround possible * and is expected to PASS — `updateImeAnimationTarget` is called outside the guard. It stays - * enabled, because it guards the premise [com.vitorpamplona.amethyst.ui.insets.SafeImeInsets] + * enabled, because it guards the premise [com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] * depends on: if a future Compose release stopped keeping `imeAnimationTarget` current, our * fallback would silently start reading a dead value too. */ diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/RenderVideoPlayer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/RenderVideoPlayer.kt index 7cab03252e..33712cfdd0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/RenderVideoPlayer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/RenderVideoPlayer.kt @@ -45,6 +45,7 @@ import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.ui.compose.ContentFrame import androidx.media3.ui.compose.SURFACE_TYPE_TEXTURE_VIEW +import com.vitorpamplona.amethyst.commons.ui.components.getDialogWindow import com.vitorpamplona.amethyst.service.playback.composable.controls.BottomGradientOverlay import com.vitorpamplona.amethyst.service.playback.composable.controls.FullscreenSwipeControlsState import com.vitorpamplona.amethyst.service.playback.composable.controls.FullscreenSwipeLevelIndicator @@ -62,7 +63,6 @@ import com.vitorpamplona.amethyst.service.playback.composable.mediaitem.LoadedMe import com.vitorpamplona.amethyst.service.playback.composable.mediaitem.isHlsMedia import com.vitorpamplona.amethyst.service.playback.composable.wavefront.AudioPlayingAnimation import com.vitorpamplona.amethyst.service.playback.composable.wavefront.rememberIsAudioTrack -import com.vitorpamplona.amethyst.ui.components.getDialogWindow import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel internal const val SKIP_SECONDS = 10 diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostView.kt index a2d42b3486..5db9dcbbd4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/EditPostView.kt @@ -78,6 +78,7 @@ import com.vitorpamplona.amethyst.commons.resources.lightning_create_and_add_inv import com.vitorpamplona.amethyst.commons.resources.lightning_invoice import com.vitorpamplona.amethyst.commons.resources.what_s_on_your_mind import com.vitorpamplona.amethyst.commons.richtext.RichTextParser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.invoice.AddLnInvoiceButton @@ -98,7 +99,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery import com.vitorpamplona.amethyst.ui.components.BechLink import com.vitorpamplona.amethyst.ui.components.LoadUrlPreview import com.vitorpamplona.amethyst.ui.components.OutlinedThinPaddingTextField -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.creators.invoice.InvoiceRequest import com.vitorpamplona.amethyst.ui.note.creators.uploads.ImageVideoDescription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt index 8398ad6d3c..1522eb0928 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt @@ -73,6 +73,7 @@ import com.vitorpamplona.amethyst.commons.resources.video_codec_h265_description import com.vitorpamplona.amethyst.commons.resources.video_codec_h265_label import com.vitorpamplona.amethyst.commons.ui.components.TextSpinner import com.vitorpamplona.amethyst.commons.ui.components.TitleExplainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.SettingSwitchItem @@ -82,7 +83,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.actions.uploads.ShowImageUploadGallery import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt index c5d1f9952d..fa67f172dd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewUserMetadataScreen.kt @@ -75,12 +75,12 @@ import com.vitorpamplona.amethyst.commons.resources.twitter import com.vitorpamplona.amethyst.commons.resources.twitter_proof_url_template import com.vitorpamplona.amethyst.commons.resources.username import com.vitorpamplona.amethyst.commons.resources.website_url +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @OptIn(ExperimentalMaterial3Api::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/bolt12Offers/Bolt12OffersScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/bolt12Offers/Bolt12OffersScreen.kt index 527b5877fb..de9f190cb8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/bolt12Offers/Bolt12OffersScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/bolt12Offers/Bolt12OffersScreen.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.commons.resources.bolt12_offers_section_explai import com.vitorpamplona.amethyst.commons.resources.delete_bolt12_offer import com.vitorpamplona.amethyst.commons.resources.invalid_bolt12_offer import com.vitorpamplona.amethyst.commons.resources.no_bolt12_offers_message +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -73,7 +74,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.grayText import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.abbreviateBolt12Offer import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/AllMediaServersScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/AllMediaServersScreen.kt index efb7ee8db5..7480a31d96 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/AllMediaServersScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/AllMediaServersScreen.kt @@ -57,12 +57,12 @@ import com.vitorpamplona.amethyst.commons.resources.local_blossom_cache_profile_ import com.vitorpamplona.amethyst.commons.resources.media_servers import com.vitorpamplona.amethyst.commons.resources.use_local_blossom_cache import com.vitorpamplona.amethyst.commons.resources.use_local_blossom_cache_caption +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton 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.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/nestsServers/NestsServersScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/nestsServers/NestsServersScreen.kt index fda47e34fd..9621ce58e5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/nestsServers/NestsServersScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/nestsServers/NestsServersScreen.kt @@ -69,6 +69,7 @@ import com.vitorpamplona.amethyst.commons.resources.nests_servers_relay_label import com.vitorpamplona.amethyst.commons.resources.nests_servers_remove import com.vitorpamplona.amethyst.commons.resources.nests_servers_title import com.vitorpamplona.amethyst.commons.resources.nests_servers_use_defaults +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -82,7 +83,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.grayText import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.mediaServers.AllMediaServersScreen -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategoryWithButton diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/paymentTargets/PaymentTargetsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/paymentTargets/PaymentTargetsScreen.kt index e86f758b85..8aacd82061 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/paymentTargets/PaymentTargetsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/paymentTargets/PaymentTargetsScreen.kt @@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.commons.resources.payment_target_type import com.vitorpamplona.amethyst.commons.resources.payment_targets import com.vitorpamplona.amethyst.commons.resources.payment_targets_explainer import com.vitorpamplona.amethyst.commons.resources.payment_targets_section_explainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -71,7 +72,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.grayText import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory import com.vitorpamplona.quartz.experimental.nipA3.PaymentTarget diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index ea6b028609..fde3038222 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -20,12 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.components -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.InlineTextContent -import androidx.compose.foundation.text.appendInlineContent -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -34,26 +28,17 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.takeOrElse import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.text.LinkAnnotation -import androidx.compose.ui.text.Placeholder -import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextLinkStyles -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.withLink import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.Note @@ -62,6 +47,9 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.concord_invite_naddr_label import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.ClickableInLineIconRenderer +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateClickableTextWithEmoji +import com.vitorpamplona.amethyst.commons.ui.richtext.CustomEmojiChecker import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.util.njumpLink import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote @@ -84,9 +72,6 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NSec import com.vitorpamplona.quartz.nip19Bech32.toNIP19 import com.vitorpamplona.quartz.nip29RelayGroups.GroupNAddrInvite import com.vitorpamplona.quartz.nip29RelayGroups.metadata.GroupMetadataEvent -import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.ImmutableMap @Composable fun ClickableRoute( @@ -406,208 +391,6 @@ fun CreateClickableText( ) } -@Composable -fun CustomEmojiChecker( - text: String, - tags: ImmutableListOfLists?, - onRegularText: @Composable (String) -> Unit, - onEmojiText: @Composable (ImmutableList) -> Unit, -) { - val mayContainEmoji by remember(text, tags) { - mutableStateOf(CustomEmoji.fastMightContainEmoji(text, tags?.lists)) - } - - if (mayContainEmoji) { - var emojiList by - remember(text, tags) { - mutableStateOf?>(null) - } - - LaunchedEffect(text, tags) { - val newEmojiList = CustomEmoji.assembleAnnotatedList(text, tags?.lists) - if (newEmojiList != null) { - emojiList = newEmojiList - } - } - - emojiList?.let { - onEmojiText(it) - } ?: run { - onRegularText(text) - } - } else { - onRegularText(text) - } -} - -@Composable -fun CustomEmojiChecker( - text: String, - emojis: ImmutableMap, - onRegularText: @Composable (String) -> Unit, - onEmojiText: @Composable (ImmutableList) -> Unit, -) { - val mayContainEmoji by remember(text, emojis) { - mutableStateOf(CustomEmoji.fastMightContainEmoji(text, emojis)) - } - - if (mayContainEmoji) { - var emojiList by - remember(text, emojis) { - mutableStateOf?>(null) - } - - LaunchedEffect(text, emojis) { - val newEmojiList = CustomEmoji.assembleAnnotatedList(text, emojis) - if (newEmojiList != null) { - emojiList = newEmojiList - } - } - - emojiList?.let { - onEmojiText(it) - } ?: run { - onRegularText(text) - } - } else { - onRegularText(text) - } -} - -@Composable -fun CreateTextWithEmoji( - text: String, - tags: ImmutableListOfLists?, - color: Color = Color.Unspecified, - textAlign: TextAlign? = null, - fontWeight: FontWeight? = null, - fontSize: TextUnit = TextUnit.Unspecified, - maxLines: Int = Int.MAX_VALUE, - overflow: TextOverflow = TextOverflow.Clip, - modifier: Modifier = Modifier, -) { - CustomEmojiChecker( - text, - tags, - onEmojiText = { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - val style = - LocalTextStyle.current - .merge( - TextStyle( - color = textColor, - textAlign = TextAlign.Unspecified, - fontWeight = fontWeight, - fontSize = fontSize, - ), - ).toSpanStyle() - - InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) - }, - onRegularText = { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - Text( - text = it, - color = textColor, - textAlign = textAlign, - fontWeight = fontWeight, - fontSize = fontSize, - maxLines = maxLines, - overflow = overflow, - modifier = modifier, - ) - }, - ) -} - -@Composable -fun CreateTextWithEmoji( - text: String, - emojis: ImmutableMap, - color: Color = Color.Unspecified, - textAlign: TextAlign? = null, - fontWeight: FontWeight? = null, - fontSize: TextUnit = TextUnit.Unspecified, - maxLines: Int = Int.MAX_VALUE, - overflow: TextOverflow = TextOverflow.Clip, - modifier: Modifier = Modifier, -) { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - - CustomEmojiChecker( - text, - emojis, - onEmojiText = { - val currentStyle = LocalTextStyle.current - val style = - remember(currentStyle) { - currentStyle - .merge( - TextStyle( - color = textColor, - textAlign = TextAlign.Unspecified, - fontWeight = fontWeight, - fontSize = fontSize, - ), - ).toSpanStyle() - } - - InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) - }, - onRegularText = { - Text( - text = it, - color = textColor, - textAlign = textAlign, - fontWeight = fontWeight, - fontSize = fontSize, - maxLines = maxLines, - overflow = overflow, - modifier = modifier, - ) - }, - ) -} - -@Composable -fun CreateClickableTextWithEmoji( - clickablePart: String, - maxLines: Int = Int.MAX_VALUE, - tags: ImmutableListOfLists?, - style: TextStyle, - onClick: () -> Unit, -) { - CustomEmojiChecker( - text = clickablePart, - tags = tags, - onRegularText = { - Text( - text = - buildAnnotatedString { - withLink( - LinkAnnotation.Clickable( - "me", - TextLinkStyles(style = style.toSpanStyle()), - ) { - onClick() - }, - ) { - append(clickablePart) - } - }, - style = style, - maxLines = maxLines, - ) - }, - onEmojiText = { - ClickableInLineIconRenderer(it, maxLines, style.toSpanStyle(), onClick = onClick) - }, - ) -} - @Composable fun CreateClickableTextWithEmoji( clickablePart: String, @@ -653,144 +436,3 @@ fun CreateClickableTextWithEmoji( }, ) } - -@Composable -fun ClickableInLineIconRenderer( - wordsInOrder: ImmutableList, - maxLines: Int = Int.MAX_VALUE, - style: SpanStyle, - suffix: String? = null, - nonClickableStype: SpanStyle? = null, - onClick: () -> Unit, -) { - val placeholderSize = - remember(style) { - if (style.fontSize == TextUnit.Unspecified) 22.sp else style.fontSize.times(1.1f) - } - - val inlineContent = - wordsInOrder - .mapIndexedNotNull { idx, value -> - if (value is CustomEmoji.ImageUrlType) { - Pair( - "inlineContent$idx", - InlineTextContent( - Placeholder( - width = placeholderSize, - height = placeholderSize, - placeholderVerticalAlign = PlaceholderVerticalAlign.Center, - ), - ) { - AsyncImage( - model = value.url, - contentDescription = null, - modifier = - Modifier - .fillMaxSize() - .padding(1.dp), - ) - }, - ) - } else { - null - } - }.associate { it.first to it.second } - - val annotatedText = - buildAnnotatedString { - wordsInOrder.forEachIndexed { idx, value -> - withLink( - LinkAnnotation.Clickable("link", TextLinkStyles(style)) { - onClick() - }, - ) { - if (value is CustomEmoji.TextType) { - append(value.text) - } else if (value is CustomEmoji.ImageUrlType) { - appendInlineContent("inlineContent$idx", "[icon]") - } - } - } - - if (suffix != null && nonClickableStype != null) { - withStyle(nonClickableStype) { - append(suffix) - } - } - } - - Text( - text = annotatedText, - inlineContent = inlineContent, - maxLines = maxLines, - ) -} - -@Composable -fun InLineIconRenderer( - wordsInOrder: ImmutableList, - style: SpanStyle, - fontSize: TextUnit = TextUnit.Unspecified, - maxLines: Int = Int.MAX_VALUE, - overflow: TextOverflow = TextOverflow.Clip, - modifier: Modifier = Modifier, -) { - val placeholderSize = - remember(fontSize) { - if (fontSize == TextUnit.Unspecified) 22.sp else fontSize.times(1.1f) - } - - val inlineContent = - wordsInOrder - .mapIndexedNotNull { idx, value -> - if (value is CustomEmoji.ImageUrlType) { - Pair( - "inlineContent$idx", - InlineTextContent( - Placeholder( - width = placeholderSize, - height = placeholderSize, - placeholderVerticalAlign = PlaceholderVerticalAlign.Center, - ), - ) { - AsyncImage( - model = value.url, - contentDescription = null, - modifier = - Modifier - .fillMaxSize() - .padding(horizontal = 0.dp), - ) - }, - ) - } else { - null - } - }.associate { it.first to it.second } - - val annotatedText = - remember { - buildAnnotatedString { - wordsInOrder.forEachIndexed { idx, value -> - withStyle( - style, - ) { - if (value is CustomEmoji.TextType) { - append(value.text) - } else if (value is CustomEmoji.ImageUrlType) { - appendInlineContent("inlineContent$idx", "[icon]") - } - } - } - } - } - - Text( - text = annotatedText, - inlineContent = inlineContent, - fontSize = fontSize, - maxLines = maxLines, - overflow = overflow, - modifier = modifier, - ) -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 62b2ea9458..3fd83f2fd5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -105,6 +105,8 @@ import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary import com.vitorpamplona.amethyst.commons.ui.components.NowhereLinkCard import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateClickableTextWithEmoji +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.richtext.HashtagIcon import com.vitorpamplona.amethyst.commons.ui.richtext.checkForHashtagWithIcon import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SetDialogToEdgeToEdge.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SetDialogToEdgeToEdge.kt index 3b2ff000bc..fadf594304 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SetDialogToEdgeToEdge.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SetDialogToEdgeToEdge.kt @@ -29,6 +29,7 @@ import androidx.compose.runtime.SideEffect import androidx.compose.ui.platform.LocalView import androidx.compose.ui.window.DialogWindowProvider import androidx.core.view.WindowCompat +import com.vitorpamplona.amethyst.commons.ui.components.getActivityWindow import com.vitorpamplona.amethyst.commons.ui.theme.isLight @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/WindowUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/WindowUtils.kt index 4bda918632..10b78d6d11 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/WindowUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/WindowUtils.kt @@ -20,31 +20,13 @@ */ package com.vitorpamplona.amethyst.ui.components -import android.app.Activity import android.content.Context import android.content.ContextWrapper -import android.view.Window import androidx.activity.ComponentActivity import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.window.DialogWindowProvider import com.vitorpamplona.amethyst.Amethyst -// Window utils -@Composable -fun getDialogWindow(): Window? = (LocalView.current.parent as? DialogWindowProvider)?.window - -@Composable -fun getActivityWindow(): Window? = LocalView.current.context.getActivityWindow() - -private tailrec fun Context.getActivityWindow(): Window? = - when (this) { - is Activity -> window - is ContextWrapper -> baseContext.getActivityWindow() - else -> null - } - tailrec fun Context.getActivity(): ComponentActivity = when (this) { is ComponentActivity -> this diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentDialog.kt index 25c2422310..c108571f73 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentDialog.kt @@ -80,6 +80,8 @@ import com.vitorpamplona.amethyst.commons.richtext.MediaUrlContent import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlPdf import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo +import com.vitorpamplona.amethyst.commons.ui.components.getActivityWindow +import com.vitorpamplona.amethyst.commons.ui.components.getDialogWindow import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.theme.imageModifier import com.vitorpamplona.amethyst.model.MediaAspectRatioCache diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfViewerDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfViewerDialog.kt index e0db66a489..e7c14e71ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfViewerDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfViewerDialog.kt @@ -62,6 +62,7 @@ import androidx.compose.ui.window.DialogProperties import androidx.core.graphics.createBitmap import coil3.disk.DiskCache import com.vitorpamplona.amethyst.commons.richtext.MediaUrlPdf +import com.vitorpamplona.amethyst.commons.ui.components.getDialogWindow import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size5dp import com.vitorpamplona.amethyst.ui.components.ImmersiveSystemBarsEffect @@ -69,7 +70,6 @@ import com.vitorpamplona.amethyst.ui.components.ViewerBackButton import com.vitorpamplona.amethyst.ui.components.ViewerControlsRow import com.vitorpamplona.amethyst.ui.components.ViewerSaveToGalleryButton import com.vitorpamplona.amethyst.ui.components.ViewerShareButton -import com.vitorpamplona.amethyst.ui.components.getDialogWindow import com.vitorpamplona.amethyst.ui.components.rememberViewerControlsVisibility import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.utils.Log diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt index 0911db8b8b..6fb63c1e08 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt @@ -20,57 +20,16 @@ */ package com.vitorpamplona.amethyst.ui.layouts -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.WindowInsetsSides -import androidx.compose.foundation.layout.navigationBars -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.only -import androidx.compose.foundation.layout.systemBars -import androidx.compose.foundation.layout.windowInsetsPadding -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.runtime.snapshotFlow -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.layout.SubcomposeLayout -import androidx.compose.ui.platform.LocalView -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.dp -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.WindowInsetsControllerCompat -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import com.vitorpamplona.amethyst.commons.ui.layouts.DisappearingBarNestedScroll -import com.vitorpamplona.amethyst.commons.ui.layouts.DisappearingBarState -import com.vitorpamplona.amethyst.commons.ui.layouts.LocalDisappearingBarState -import com.vitorpamplona.amethyst.commons.ui.layouts.LocalDisappearingScaffoldPadding -import com.vitorpamplona.amethyst.commons.ui.layouts.rememberDisappearingBarState -import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness -import com.vitorpamplona.amethyst.ui.components.getActivityWindow -import com.vitorpamplona.amethyst.ui.insets.SafeImeInsets -import com.vitorpamplona.amethyst.ui.insets.rememberSafeImeInsets import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.launch - -private enum class DisappearingSlot { Top, Bottom, Content, Fab } - -private val FabEdgePadding = 16.dp +import com.vitorpamplona.amethyst.commons.ui.layouts.DisappearingScaffold as SharedDisappearingScaffold +/** + * The app's [SharedDisappearingScaffold]: bars hide on scroll only when the user's immersive + * scrolling setting is on, and never on large screens (rail / permanent drawer), which pin the + * chrome. + */ @Composable fun DisappearingScaffold( isInvertedLayout: Boolean, @@ -81,293 +40,13 @@ fun DisappearingScaffold( isActive: () -> Boolean = { true }, allowBarHide: Boolean = true, mainContent: @Composable (padding: PaddingValues) -> Unit, -) { - val state = rememberDisappearingBarState() - - // Large screens (rail / permanent drawer) pin the chrome: bars never slide away on - // scroll, and the immersive status-bar hiding stays off. - val canHideBars = allowBarHide && !LocalScreenLayout.current.isLargeScreen - - // Hold the latest values in state so the NSC's captured lambda stays fresh across - // recompositions without rebuilding the NSC itself. - val latestIsActive by rememberUpdatedState(isActive) - val latestAllowBarHide by rememberUpdatedState(canHideBars) - val latestAccountViewModel by rememberUpdatedState(accountViewModel) - - val connection = - remember(state, isInvertedLayout) { - DisappearingBarNestedScroll( - state = state, - canScroll = { - latestAllowBarHide && - latestIsActive() && - latestAccountViewModel.settings.isImmersiveScrollingActive() - }, - reverseLayout = isInvertedLayout, - ) - } - - // Only wire the lifecycle observer + system-bar control when the scaffold actually moves its bars. - if (canHideBars) { - ResetBarsOnResume(state) - ImmersiveStatusBarEffect(state) - } - - // If the bars were scrolled away when hiding got disabled (e.g. the window grew to a - // large tier mid-scroll), nothing above can bring them back — the nested-scroll - // connection and the resume reset are gone. Snap them visible here instead of - // leaving the chrome stranded off-screen. - LaunchedEffect(canHideBars, state) { - if (!canHideBars) state.resetToVisible() - } - - // When bars are pinned, skip attaching the nested-scroll connection entirely. - // The outer Surface provides the Material container color + onBackground as - // LocalContentColor, matching M3 Scaffold's behaviour (without it, default text - // color falls back to Color.Black and is invisible on the dark theme). - // Hoisted above the branch: imePaddingSafe() inside both arms would put the call in two - // different composition groups, so toggling canHideBars (a window-size-class change) would - // dispose and rebuild it. Resolved once here, and handed to ScaffoldLayout below so the value - // this pads with is the same object the nav-bar subtraction reads. - val imeInsets = rememberSafeImeInsets() - val baseModifier = - if (canHideBars) { - Modifier.windowInsetsPadding(imeInsets).nestedScroll(connection) - } else { - Modifier.windowInsetsPadding(imeInsets) - } - val rootModifier = - baseModifier - // systemBars (not just statusBars) so a desktop window's caption bar is respected too. - .let { if (topBar == null) it.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Top)) else it } - .let { if (bottomBar == null) it.navigationBarsPadding() else it } - - Surface( - modifier = rootModifier, - color = MaterialTheme.colorScheme.background, - contentColor = MaterialTheme.colorScheme.onBackground, - ) { - ScaffoldLayout( - state = state, - topBar = topBar, - bottomBar = bottomBar, - floatingButton = floatingButton, - imeInsets = imeInsets, - mainContent = mainContent, - ) - } -} - -@Composable -private fun ScaffoldLayout( - state: DisappearingBarState, - topBar: (@Composable () -> Unit)?, - bottomBar: (@Composable () -> Unit)?, - floatingButton: (@Composable () -> Unit)?, - imeInsets: SafeImeInsets, - mainContent: @Composable (padding: PaddingValues) -> Unit, -) { - val navBarInsets = WindowInsets.navigationBars - SubcomposeLayout { constraints -> - val layoutWidth = constraints.maxWidth - val layoutHeight = constraints.maxHeight - val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0) - - val topPlaceable = - topBar?.let { bar -> - subcompose(DisappearingSlot.Top) { - Column( - modifier = - Modifier.graphicsLayer { - translationY = state.topHeightOffset - }, - ) { - bar() - HorizontalDivider(thickness = DividerThickness) - } - }.firstOrNull()?.measure(looseConstraints) - } - val topHeight = topPlaceable?.height ?: 0 - - val bottomPlaceable = - bottomBar?.let { bar -> - subcompose(DisappearingSlot.Bottom) { - Column( - modifier = - Modifier.graphicsLayer { - translationY = -state.bottomHeightOffset - }, - ) { - bar() - } - }.firstOrNull()?.measure(looseConstraints) - } - // When the bar lambda is provided but its content emits nothing (e.g. AppBottomBar - // hides itself on canPop entries, or while the keyboard is up), reserve the - // system-nav-bar inset so the FAB and content stay clear of the navigation bar instead - // of sliding under it. Subtract the IME inset: the root imePadding has already lifted the - // whole scaffold above the keyboard, and the IME inset spans the nav-bar band, so - // reserving the full nav bar on top of that would double-count and strand a gap above the - // keyboard (the `bottomBar == null` branch gets this for free via navigationBarsPadding, - // which excludes the consumed IME inset). The `bottomBar == null` case is on rootModifier. - val bottomHeight = - (bottomPlaceable?.height ?: 0).let { measured -> - if (bottomBar != null && measured == 0) { - (navBarInsets.getBottom(this) - imeInsets.getBottom(this)).coerceAtLeast(0) - } else { - measured - } - } - - // Publish the measured limits so the nested-scroll connection can clamp correctly. - state.topHeightLimit = topHeight.toFloat() - state.bottomHeightLimit = bottomHeight.toFloat() - - val contentPadding = - PaddingValues( - top = topHeight.toDp(), - bottom = bottomHeight.toDp(), - ) - - val contentPlaceable = - subcompose(DisappearingSlot.Content) { - CompositionLocalProvider( - LocalDisappearingScaffoldPadding provides contentPadding, - LocalDisappearingBarState provides state, - ) { - mainContent(contentPadding) - } - }.firstOrNull()?.measure( - Constraints.fixed(layoutWidth, layoutHeight), - ) - - val fabPlaceable = - floatingButton?.let { fab -> - subcompose(DisappearingSlot.Fab) { - FloatingButtonHolder(state = state) { fab() } - }.firstOrNull()?.measure(looseConstraints) - } - - val fabEdgePx = FabEdgePadding.roundToPx() - - layout(layoutWidth, layoutHeight) { - contentPlaceable?.place(0, 0) - topPlaceable?.place(0, 0) - bottomPlaceable?.place(0, layoutHeight - bottomHeight) - if (fabPlaceable != null) { - val x = layoutWidth - fabPlaceable.width - fabEdgePx - val yBase = layoutHeight - bottomHeight - fabPlaceable.height - fabEdgePx - fabPlaceable.place(x, yBase) - } - } - } -} - -/** - * Holds the floating button. Scales / fades it with the bottom-bar collapse fraction and - * rides along with the bar via graphicsLayer, so the layout pass is untouched while - * the bar animates. - */ -@Composable -private fun FloatingButtonHolder( - state: DisappearingBarState, - content: @Composable () -> Unit, -) { - Box( - modifier = - Modifier.graphicsLayer { - val visible = (1f - state.bottomCollapsedFraction).coerceAtLeast(0.001f) - scaleX = visible - scaleY = visible - alpha = visible - translationY = -state.bottomHeightOffset - }, - ) { - content() - } -} - -@Composable -private fun ResetBarsOnResume(state: DisappearingBarState) { - val lifecycleOwner = LocalLifecycleOwner.current - val scope = rememberCoroutineScope() - DisposableEffect(lifecycleOwner, state) { - val observer = - LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_RESUME && - (state.topHeightOffset != 0f || state.bottomHeightOffset != 0f) - ) { - scope.launch { state.resetToVisible() } - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } - } -} - -/** Fraction at which the tracked in-app bar is considered fully settled into the hidden edge. */ -private const val STATUS_BAR_HIDE_THRESHOLD = 0.999f - -/** - * Fraction the chrome must fall back below before the OS status bar reappears. Lower than - * [STATUS_BAR_HIDE_THRESHOLD] on purpose: this hysteresis gap means the finger that stops a fast - * scroll — which makes a tiny reverse reveal — does not immediately pop the status bar back. The - * user has to deliberately scroll the chrome back by ~30% before the status bar returns. - */ -private const val STATUS_BAR_SHOW_THRESHOLD = 0.7f - -/** - * Hides the OS status bar once the tracked in-app bar has settled into the hidden edge, and shows it - * the moment it starts coming back. The OS status bar is binary (cannot slide), so it is driven off - * the collapse fraction with a near-1 threshold, which means it toggles on settle rather than - * mid-drag. - * - * The status bar sits with the top in-app bar, so it tracks the top bar's collapse. The top and - * bottom bars can collapse at different rates (each clamps to its own height), so tracking the top - * fraction keeps the status bar in step with the chrome directly beneath it. On screens with no top - * bar (topHeightLimit == 0) it falls back to the bottom bar, so the status bar still hides in sync - * with the bottom navigation. - * - * Only the top status bar is touched; the bottom OS navigation bar is left alone. - * BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE lets the user swipe to peek the status bar while immersed. - * The status bar is always restored on dispose so leaving an immersive screen can never strand a - * hidden bar. - */ -@Composable -private fun ImmersiveStatusBarEffect(state: DisappearingBarState) { - val view = LocalView.current - if (view.isInEditMode) return - val window = getActivityWindow() ?: return - val controller = remember(window, view) { WindowInsetsControllerCompat(window, view) } - - LaunchedEffect(controller, state) { - controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE - var statusBarHidden = false - snapshotFlow { - if (state.topHeightLimit > 0f) state.topCollapsedFraction else state.bottomCollapsedFraction - }.distinctUntilChanged() - .collect { fraction -> - // Hysteresis: hide once fully settled, but only show again after the chrome has - // been pulled back past STATUS_BAR_SHOW_THRESHOLD. Between the two thresholds the - // status bar keeps its current state, so a stray reverse reveal can't flip it. - val shouldHide = - when { - fraction >= STATUS_BAR_HIDE_THRESHOLD -> true - fraction <= STATUS_BAR_SHOW_THRESHOLD -> false - else -> statusBarHidden - } - if (shouldHide != statusBarHidden) { - statusBarHidden = shouldHide - if (shouldHide) { - controller.hide(WindowInsetsCompat.Type.statusBars()) - } else { - controller.show(WindowInsetsCompat.Type.statusBars()) - } - } - } - } - - DisposableEffect(controller) { - onDispose { controller.show(WindowInsetsCompat.Type.statusBars()) } - } -} +) = SharedDisappearingScaffold( + isInvertedLayout = isInvertedLayout, + topBar = topBar, + bottomBar = bottomBar, + floatingButton = floatingButton, + immersiveScrolling = { accountViewModel.settings.isImmersiveScrollingActive() }, + isActive = isActive, + allowBarHide = allowBarHide && !LocalScreenLayout.current.isLargeScreen, + mainContent = mainContent, +) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt index 7fa55a8744..45789c3425 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt @@ -25,8 +25,7 @@ import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalDensity -import com.vitorpamplona.amethyst.ui.insets.SafeImeInsets -import com.vitorpamplona.amethyst.ui.insets.rememberSafeImeInsets +import com.vitorpamplona.amethyst.commons.ui.insets.rememberSafeImeInsets enum class KeyboardState { Opened, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt index c828e83cee..7c5ccb1d21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt @@ -74,12 +74,12 @@ import com.vitorpamplona.amethyst.commons.scheduledposts.ScheduledPostStatus import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.loadPluralStringRes import com.vitorpamplona.amethyst.commons.ui.pluralStringRes +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.AccountPictureModifier import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size55dp import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.note.toShortDisplay import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index 77cf8b53a3..df3a7a5014 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -119,6 +119,7 @@ import com.vitorpamplona.amethyst.commons.scheduledposts.ScheduledPostStatus import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.DoubleHorzSpacer @@ -146,7 +147,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserContactCardsFollowerCount import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserStatuses -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.layouts.PermanentDrawerWidth import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarCatalog import com.vitorpamplona.amethyst.ui.navigation.bottombars.NavBarItemDef diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt index 765537f572..fd25ab6772 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt @@ -26,9 +26,8 @@ import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import com.vitorpamplona.amethyst.commons.ui.insets.rememberSafeImeInsets import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav -import com.vitorpamplona.amethyst.ui.insets.SafeImeInsets -import com.vitorpamplona.amethyst.ui.insets.rememberSafeImeInsets import kotlinx.coroutines.flow.first import kotlinx.coroutines.withTimeoutOrNull diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index f3d5b37d0f..6a3c005742 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -84,6 +84,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.LikedIcon import com.vitorpamplona.amethyst.commons.ui.note.RepostedIcon import com.vitorpamplona.amethyst.commons.ui.note.ScoreTagSmall import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.HalfTopPadding @@ -106,7 +107,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture import com.vitorpamplona.amethyst.ui.components.CoreSecretMessage import com.vitorpamplona.amethyst.ui.components.ExpandableRichTextViewer -import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.routes.authorRouteFor import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 0bcb164f32..453da51243 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -57,6 +57,7 @@ import com.vitorpamplona.amethyst.commons.resources.nip05_failed import com.vitorpamplona.amethyst.commons.resources.nip05_verified import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Font14SP import com.vitorpamplona.amethyst.commons.ui.theme.NIP05IconSize @@ -70,7 +71,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFind import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserStatuses import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.navigation.routes.routeForUser 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 055279c4e9..c390301cd5 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 @@ -167,6 +167,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.ShareIcon import com.vitorpamplona.amethyst.commons.ui.note.VoiceReplyIcon import com.vitorpamplona.amethyst.commons.ui.note.ZapIcon import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder @@ -226,7 +227,6 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.uploads.FloatingRecordingIndicator import com.vitorpamplona.amethyst.ui.actions.uploads.MAX_VOICE_RECORD_SECONDS import com.vitorpamplona.amethyst.ui.actions.uploads.RecordAudioBox -import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt index 70eeaa776c..80b2315cf3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt @@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.and import com.vitorpamplona.amethyst.commons.resources.replying_to import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.lessImportantLink diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt index 865869f326..9166e84e62 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt @@ -76,9 +76,11 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.add import com.vitorpamplona.amethyst.commons.resources.new_reaction_symbol import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.note.LikedIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer @@ -86,8 +88,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.firstFullChar import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEventAndMapNotNull -import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.types.RenderEmojiPack import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt index 825bffda4d..51351dac5b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt @@ -110,6 +110,7 @@ import com.vitorpamplona.amethyst.commons.resources.zap_type_public_explainer import com.vitorpamplona.amethyst.commons.resources.zap_type_section_explainer import com.vitorpamplona.amethyst.commons.ui.components.TextSpinner import com.vitorpamplona.amethyst.commons.ui.components.TitleExplainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstModifier @@ -117,7 +118,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategorySpacingModifi import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.getFragmentActivity import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index fe9357bb0b..f17517e544 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -23,22 +23,19 @@ package com.vitorpamplona.amethyst.ui.note import android.content.Context import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner -import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.ui.note.PlayIcon +import com.vitorpamplona.amethyst.commons.ui.note.UserNameText import com.vitorpamplona.amethyst.commons.ui.theme.StdButtonSizeModifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote @@ -46,7 +43,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserNickname import com.vitorpamplona.amethyst.service.tts.TextToSpeechHelper import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.utils.Log @@ -113,55 +109,18 @@ fun UsernameDisplay( // the account's own nickname for this user wins over the user's metadata; // its custom emojis resolve against the contact card's tags, not the profile's val petName = nickname?.petName - val name = petName ?: it?.info?.bestName() - if (name != null) { - UserDisplay(name, if (petName != null) nickname?.tags else it?.tags, weight, fontWeight, textColor, textAlign) - } else { - NPubDisplay(baseUser, weight, fontWeight, textColor, textAlign) - } + UserNameText( + user = baseUser, + displayName = petName ?: it?.info?.bestName(), + tags = if (petName != null) nickname?.tags else it?.tags, + modifier = weight, + fontWeight = fontWeight, + textColor = textColor, + textAlign = textAlign, + ) } } -@Composable -private fun NPubDisplay( - user: User, - modifier: Modifier, - fontWeight: FontWeight = FontWeight.Bold, - textColor: Color = Color.Unspecified, - textAlign: TextAlign? = null, -) { - Text( - text = remember { user.pubkeyDisplayHex() }, - fontWeight = fontWeight, - modifier = modifier, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = textColor, - textAlign = textAlign, - ) -} - -@Composable -private fun UserDisplay( - bestDisplayName: String, - tags: ImmutableListOfLists?, - modifier: Modifier, - fontWeight: FontWeight = FontWeight.Bold, - textColor: Color = Color.Unspecified, - textAlign: TextAlign? = null, -) { - CreateTextWithEmoji( - text = bestDisplayName, - tags = tags, - fontWeight = fontWeight, - textAlign = textAlign, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = modifier, - color = textColor, - ) -} - @Composable fun DrawPlayName(name: String) { val context = LocalContext.current diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt index 8dc41e3d8b..ed1177b147 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt @@ -99,6 +99,7 @@ import com.vitorpamplona.amethyst.commons.resources.zap_type_private import com.vitorpamplona.amethyst.commons.resources.zap_type_private_explainer import com.vitorpamplona.amethyst.commons.resources.zap_type_public import com.vitorpamplona.amethyst.commons.resources.zap_type_public_explainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.note.buttons.CloseButton @@ -113,7 +114,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet.OnchainZapSendDialog import com.vitorpamplona.quartz.nip01Core.core.Event diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/GeohashLocationPickerDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/GeohashLocationPickerDialog.kt index 5b4475a912..175a05440e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/GeohashLocationPickerDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/location/GeohashLocationPickerDialog.kt @@ -95,10 +95,10 @@ import com.vitorpamplona.amethyst.commons.resources.location_picker_search_empty import com.vitorpamplona.amethyst.commons.resources.location_picker_search_hint import com.vitorpamplona.amethyst.commons.resources.location_picker_title import com.vitorpamplona.amethyst.commons.resources.location_picker_use_mine +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.location.ForwardGeolocation import com.vitorpamplona.amethyst.service.location.LocationState -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.geohashChat.label import com.vitorpamplona.quartz.experimental.bitchat.geohash.GeohashChannelLevel import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHash diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt index 5e91dae8c4..3fad5f0759 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/GenericCommentPostScreen.kt @@ -76,6 +76,7 @@ import com.vitorpamplona.amethyst.commons.resources.lightning_invoice import com.vitorpamplona.amethyst.commons.resources.post_anonymously import com.vitorpamplona.amethyst.commons.resources.what_s_on_your_mind import com.vitorpamplona.amethyst.commons.resources.zapraiser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.MarkAsSensitiveButton @@ -103,7 +104,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton import com.vitorpamplona.amethyst.ui.components.getActivity -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.NoteCompose 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 305c9d66bd..82375dddb5 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 @@ -103,11 +103,11 @@ import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.LinkIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog import com.vitorpamplona.amethyst.ui.components.util.setText diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt index 4c221f750c..cdbff32f6a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt @@ -54,6 +54,7 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.HighlightQuoteIndent import com.vitorpamplona.amethyst.commons.ui.note.HighlightQuoteSpacing import com.vitorpamplona.amethyst.commons.ui.note.HighlightedQuote +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt index 236d426d32..d8e45f3b1d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt @@ -67,6 +67,7 @@ import com.vitorpamplona.amethyst.commons.resources.profile_card_bot import com.vitorpamplona.amethyst.commons.resources.profile_card_follows_you import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ShowUserButton +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.commons.ui.theme.Size5dp @@ -77,7 +78,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.observe import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserContactCardsFollowerCount import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowing -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.ObserveDisplayNip05Status diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt index 9f3d4bdfe4..8bf321ca6c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp @@ -70,7 +71,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.toShortDisplay import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.ui.components.LoadNote -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.LoadPublicChatChannel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/award/AwardBadgeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/award/AwardBadgeScreen.kt index 88dc8b7fe7..c5dce60d0b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/award/AwardBadgeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/award/AwardBadgeScreen.kt @@ -56,11 +56,11 @@ import com.vitorpamplona.amethyst.commons.resources.award_badge_remove_recipient import com.vitorpamplona.amethyst.commons.resources.award_badge_search_label import com.vitorpamplona.amethyst.commons.resources.award_badge_search_placeholder import com.vitorpamplona.amethyst.commons.ui.components.Nip05OrPubkeyLine +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightPage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.UserSuggestionState diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/post/NewBadgeDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/post/NewBadgeDialog.kt index 06853abe3f..e3d2855357 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/post/NewBadgeDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/post/NewBadgeDialog.kt @@ -85,6 +85,7 @@ import com.vitorpamplona.amethyst.commons.resources.strip_metadata_description import com.vitorpamplona.amethyst.commons.resources.strip_metadata_label import com.vitorpamplona.amethyst.commons.ui.components.TextSpinner import com.vitorpamplona.amethyst.commons.ui.components.TitleExplainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.SettingSwitchItem import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -94,7 +95,6 @@ import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelect import com.vitorpamplona.amethyst.ui.actions.uploads.ShowImageUploadGallery import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt index c4ac467abd..15c2317fcd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.DeletedItemsBanner 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -79,7 +80,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Address import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/metadata/BookmarkGroupMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/metadata/BookmarkGroupMetadataScreen.kt index cd63962c00..e637f79fc8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/metadata/BookmarkGroupMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/metadata/BookmarkGroupMetadataScreen.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.commons.resources.follow_set_edit_list_metadat import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_be_able_to_sign_events import com.vitorpamplona.amethyst.commons.resources.optional_picture_url import com.vitorpamplona.amethyst.commons.resources.read_only_user +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe 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 @@ -61,7 +62,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstModifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt index deab17fc0e..2e1f34e970 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt @@ -42,10 +42,10 @@ import com.vitorpamplona.amethyst.commons.nip51Lists.ui.BookmarkGroupManagementI import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.article_bookmark_management_title import com.vitorpamplona.amethyst.commons.resources.bookmarks_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt index c12b8ea124..b30bb0a5f5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt @@ -42,11 +42,11 @@ import com.vitorpamplona.amethyst.commons.nip51Lists.ui.BookmarkGroupManagementI import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.bookmarks_title import com.vitorpamplona.amethyst.commons.resources.post_bookmark_management_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.components.LoadNote -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarCollectionScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarCollectionScreen.kt index 349808ffd5..c3b0524447 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarCollectionScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarCollectionScreen.kt @@ -68,10 +68,10 @@ import com.vitorpamplona.amethyst.commons.resources.calendar_untitled import com.vitorpamplona.amethyst.commons.resources.cancel import com.vitorpamplona.amethyst.commons.resources.edit_calendar_collection import com.vitorpamplona.amethyst.commons.resources.new_calendar_collection +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.formatLongDate diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarEventScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarEventScreen.kt index 172a3ed169..5a1070edaf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarEventScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/create/NewCalendarEventScreen.kt @@ -78,12 +78,12 @@ import com.vitorpamplona.amethyst.commons.resources.calendar_event_summary import com.vitorpamplona.amethyst.commons.resources.calendar_event_title import com.vitorpamplona.amethyst.commons.resources.edit_calendar_event import com.vitorpamplona.amethyst.commons.resources.new_calendar_event +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size30dp import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightChat -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt index 32da96aa1c..297bd289a8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/detail/CalendarEventDetailScreen.kt @@ -89,6 +89,7 @@ import com.vitorpamplona.amethyst.commons.resources.calendar_share_nostr_title import com.vitorpamplona.amethyst.commons.resources.calendar_untitled import com.vitorpamplona.amethyst.commons.resources.edit_calendar_event import com.vitorpamplona.amethyst.commons.resources.route_calendar_event_detail +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -96,7 +97,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size30dp import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.ReactionsRow import com.vitorpamplona.amethyst.ui.note.UsernameDisplay diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatReactionChips.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatReactionChips.kt index e9c688188c..c605fae8e3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatReactionChips.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatReactionChips.kt @@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.LikedIcon import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon import com.vitorpamplona.amethyst.commons.ui.pluralStringRes +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.Font12SP import com.vitorpamplona.amethyst.commons.ui.theme.Size14Modifier @@ -74,7 +75,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.subtleBorder import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteMinichatReplyCount import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteReactions import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteZaps -import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer import com.vitorpamplona.amethyst.ui.note.ObserveZapAmountText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/DrawAuthorInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/DrawAuthorInfo.kt index c5721a3fd4..84ebcb66d7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/DrawAuthorInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/DrawAuthorInfo.kt @@ -34,12 +34,12 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.FollowingIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp import com.vitorpamplona.amethyst.commons.ui.theme.Size5Modifier import com.vitorpamplona.amethyst.commons.ui.theme.isLight import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserNickname -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.note.InnerUserPicture import com.vitorpamplona.amethyst.ui.note.ObserveAndRenderUserCards import com.vitorpamplona.amethyst.ui.note.WatchUserFollows diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt index fb7b9de13f..3d29f92eab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt @@ -66,11 +66,11 @@ import com.vitorpamplona.amethyst.commons.model.geohashChat.GeohashChatChannel import com.vitorpamplona.amethyst.commons.search.SearchSeed import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.service.location.LocationState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.topbars.SearchTopBarAction import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/NewGeohashChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/NewGeohashChatScreen.kt index 98eb70538e..2cb3ed0a5e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/NewGeohashChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/NewGeohashChatScreen.kt @@ -63,10 +63,10 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.service.location.LocationState -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.experimental.bitchat.geohash.GeohashChannelLevel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt index 24dc7c6d32..67eb18089d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/CreateGroupScreen.kt @@ -58,12 +58,12 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_keypackage_relays_not import com.vitorpamplona.amethyst.commons.resources.marmot_keypackage_relays_not_set_title import com.vitorpamplona.amethyst.commons.resources.marmot_skip_for_now import com.vitorpamplona.amethyst.commons.resources.marmot_use_outbox_relays +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.marmotGroup.send.MarmotGroupIconChange import com.vitorpamplona.quartz.nip01Core.core.toHexKey diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt index 6e8a7a585f..ca0964fcbb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/EditGroupInfoScreen.kt @@ -56,12 +56,12 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_group_name import com.vitorpamplona.amethyst.commons.resources.marmot_group_name_placeholder import com.vitorpamplona.amethyst.commons.resources.marmot_legacy_group_no_avatar_url import com.vitorpamplona.amethyst.commons.resources.save +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ActionTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.marmotGroup.send.MarmotGroupIconChange import com.vitorpamplona.quartz.nip01Core.core.HexKey diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt index 405e8ca763..6e8108e212 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt @@ -127,6 +127,7 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_unknown_error import com.vitorpamplona.amethyst.commons.resources.marmot_user_fallback_name import com.vitorpamplona.amethyst.commons.resources.members import com.vitorpamplona.amethyst.commons.resources.remove +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes @@ -138,7 +139,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.ui.theme.ripple24dp import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.ui.components.util.setText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatScreen.kt index 694dc79861..4d2d19e7c8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/minichat/MinichatScreen.kt @@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.resources.chat_minichat_title import com.vitorpamplona.amethyst.commons.resources.chat_send_image_title import com.vitorpamplona.amethyst.commons.resources.concord_open_channel import com.vitorpamplona.amethyst.commons.resources.reply_here +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.EditFieldBorder @@ -75,7 +76,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFind import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.ChatroomMessageCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.LocalSuppressReplyToNoteId diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt index 54ccd2eece..ebf74ad944 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt @@ -30,9 +30,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt index 1b4626c92f..5b32232905 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt @@ -89,6 +89,7 @@ import com.vitorpamplona.amethyst.commons.richtext.EncryptedMediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.RichTextParser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer @@ -121,7 +122,6 @@ 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.navigation.routes.routeToMessage import com.vitorpamplona.amethyst.ui.note.BaseUserPicture diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelScreen.kt index 8a0679ee1e..e921ea0531 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelScreen.kt @@ -77,6 +77,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RelayReachMarkers import com.vitorpamplona.amethyst.commons.ui.feeds.RelayReachSentinels import com.vitorpamplona.amethyst.commons.ui.feeds.RelayReachState import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DoubleVertSpacer @@ -91,7 +92,6 @@ import com.vitorpamplona.amethyst.ui.actions.UrlUserTagOutputTransformation import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt index e7a86bb697..4dbabca232 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt @@ -47,6 +47,7 @@ import com.vitorpamplona.amethyst.commons.resources.my_awesome_group import com.vitorpamplona.amethyst.commons.resources.relay_chat import com.vitorpamplona.amethyst.commons.resources.relay_chat_explainer import com.vitorpamplona.amethyst.commons.resources.relay_chat_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar @@ -55,7 +56,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstModifier import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt index a5757f0ed1..4f29ec5f8c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/LongPublicChatChannelHeader.kt @@ -52,6 +52,7 @@ import com.vitorpamplona.amethyst.commons.resources.groups_no_descriptor import com.vitorpamplona.amethyst.commons.resources.owner import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.Size25dp @@ -59,7 +60,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.largeProfilePictureModifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingChannel -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt index 44e6fa96a2..d685c2e963 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt @@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.commons.resources.public_chat_relays_explainer import com.vitorpamplona.amethyst.commons.resources.public_chat_relays_title import com.vitorpamplona.amethyst.commons.resources.public_chat_title import com.vitorpamplona.amethyst.commons.resources.read_only_user +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar @@ -72,7 +73,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategorySpacingModifi import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.LoadPublicChatChannel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMembersScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMembersScreen.kt index 59ca38f772..c8bd0df5ca 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMembersScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMembersScreen.kt @@ -87,13 +87,13 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_remove_user import com.vitorpamplona.amethyst.commons.resources.relay_group_remove_user_confirm import com.vitorpamplona.amethyst.commons.resources.relay_group_role_admin import com.vitorpamplona.amethyst.commons.resources.relay_group_role_moderator +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightChat import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannel -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMetadataScreen.kt index 1bc031a797..ea0795cfb2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupMetadataScreen.kt @@ -103,12 +103,12 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_relay_no_nip29 import com.vitorpamplona.amethyst.commons.resources.relay_group_section_discovery import com.vitorpamplona.amethyst.commons.resources.relay_group_section_discovery_desc import com.vitorpamplona.amethyst.commons.resources.relay_group_section_permissions +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe 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.stringRes import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.creators.location.GeohashLocationPickerDialog import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/twopane/MessagesTwoPane.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/twopane/MessagesTwoPane.kt index f2c9199734..5e37b9a13f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/twopane/MessagesTwoPane.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/twopane/MessagesTwoPane.kt @@ -38,10 +38,10 @@ import com.google.accompanist.adaptive.calculateDisplayFeatures import com.vitorpamplona.amethyst.commons.chats.ui.ChannelFabColumn import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.components.getActivity -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar import com.vitorpamplona.amethyst.ui.navigation.topbars.AmethystClickableIcon import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/utils/ChatFileUploadDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/utils/ChatFileUploadDialog.kt index a87d69fba2..140818f591 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/utils/ChatFileUploadDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/utils/ChatFileUploadDialog.kt @@ -74,6 +74,7 @@ import com.vitorpamplona.amethyst.commons.resources.strip_metadata_description import com.vitorpamplona.amethyst.commons.resources.strip_metadata_label import com.vitorpamplona.amethyst.commons.ui.components.TextSpinner import com.vitorpamplona.amethyst.commons.ui.components.TitleExplainer +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TitleIconModifier @@ -84,7 +85,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size5dp import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.ShowImageUploadGallery import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsRow import kotlinx.collections.immutable.toImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/newCommunity/NewCommunityScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/newCommunity/NewCommunityScreen.kt index 8bb1fcf271..f3eadd1b43 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/newCommunity/NewCommunityScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/newCommunity/NewCommunityScreen.kt @@ -94,6 +94,7 @@ import com.vitorpamplona.amethyst.commons.resources.new_community_rules_section import com.vitorpamplona.amethyst.commons.resources.remove import com.vitorpamplona.amethyst.commons.resources.save import com.vitorpamplona.amethyst.commons.ui.components.Nip05OrPubkeyLine +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ActionTopBar import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar @@ -102,7 +103,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightPa import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelect import com.vitorpamplona.amethyst.ui.actions.uploads.ShowImageUploadGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.UserSuggestionState diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostScreen.kt index 9ed296cdb8..2545f6e935 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/LongFormPostScreen.kt @@ -100,6 +100,7 @@ import com.vitorpamplona.amethyst.commons.resources.url_slug import com.vitorpamplona.amethyst.commons.resources.url_slug_placeholder import com.vitorpamplona.amethyst.commons.resources.your_article_title import com.vitorpamplona.amethyst.commons.resources.zapraiser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.MarkAsSensitiveButton @@ -129,7 +130,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField import com.vitorpamplona.amethyst.ui.components.markdown.RenderContentAsMarkdown -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe 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 diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt index 6b4e94b60a..a3ffe17186 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/NewProductScreen.kt @@ -51,6 +51,7 @@ import com.vitorpamplona.amethyst.commons.resources.lightning_create_and_add_inv import com.vitorpamplona.amethyst.commons.resources.lightning_invoice import com.vitorpamplona.amethyst.commons.resources.new_product import com.vitorpamplona.amethyst.commons.resources.zapraiser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer @@ -75,7 +76,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia import com.vitorpamplona.amethyst.ui.actions.uploads.TakePictureButton import com.vitorpamplona.amethyst.ui.actions.uploads.TakeVideoButton -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/metadata/EmojiPackMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/metadata/EmojiPackMetadataScreen.kt index b1d20ea249..ca70ddd248 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/metadata/EmojiPackMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/metadata/EmojiPackMetadataScreen.kt @@ -71,13 +71,13 @@ import com.vitorpamplona.amethyst.commons.resources.emoji_pack_name_label import com.vitorpamplona.amethyst.commons.resources.emoji_pack_upload_image_cta import com.vitorpamplona.amethyst.commons.resources.emoji_pack_upload_image_hint import com.vitorpamplona.amethyst.commons.resources.new_emoji_pack +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe 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.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/membershipManagement/EmojiPackSelectionScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/membershipManagement/EmojiPackSelectionScreen.kt index fe42f407ee..fa5a65218e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/membershipManagement/EmojiPackSelectionScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/membershipManagement/EmojiPackSelectionScreen.kt @@ -53,13 +53,13 @@ import com.vitorpamplona.amethyst.commons.resources.emoji_pack_is_not_in_list import com.vitorpamplona.amethyst.commons.resources.emoji_pack_management_title import com.vitorpamplona.amethyst.commons.resources.my_emoji_list_title import com.vitorpamplona.amethyst.commons.resources.remove_from_emoji_list +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size40Modifier import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Address diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/create/NewGeocacheScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/create/NewGeocacheScreen.kt index e3732e1ba7..6d09488f1e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/create/NewGeocacheScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/create/NewGeocacheScreen.kt @@ -100,12 +100,12 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_owner_qr_warning import com.vitorpamplona.amethyst.commons.resources.geocache_photo_remove import com.vitorpamplona.amethyst.commons.resources.route_edit_geocache import com.vitorpamplona.amethyst.commons.resources.route_new_geocache +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.stringRes import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.creators.location.GeohashLocationPickerDialog import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/detail/GeocacheDetailScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/detail/GeocacheDetailScreen.kt index 5cdf2bd42b..ac35a14fe3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/detail/GeocacheDetailScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/detail/GeocacheDetailScreen.kt @@ -88,6 +88,7 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_needs_maintenance import com.vitorpamplona.amethyst.commons.resources.geocache_no_logs import com.vitorpamplona.amethyst.commons.resources.geocache_photos_section import com.vitorpamplona.amethyst.commons.resources.route_geocache_detail +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.GeocacheChips import com.vitorpamplona.amethyst.commons.ui.note.GeocacheDetailHero @@ -100,7 +101,6 @@ import com.vitorpamplona.amethyst.commons.ui.note.specSummary import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.creators.location.LocationPreviewMap import com.vitorpamplona.amethyst.ui.note.types.distanceToCache import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/GeocacheHuntScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/GeocacheHuntScreen.kt index c3e7b29755..d3e9da2b8f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/GeocacheHuntScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/GeocacheHuntScreen.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_hunt_start import com.vitorpamplona.amethyst.commons.resources.geocache_loading import com.vitorpamplona.amethyst.commons.resources.geocache_unnamed import com.vitorpamplona.amethyst.commons.resources.route_geocache_hunt_detail +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.GeocacheSpecLine import com.vitorpamplona.amethyst.commons.ui.note.geocacheEmoji @@ -71,7 +72,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.geocaches.datasource.GeocachesFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/NewGeocacheHuntScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/NewGeocacheHuntScreen.kt index fc064bcda9..6512bed293 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/NewGeocacheHuntScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/hunt/NewGeocacheHuntScreen.kt @@ -63,10 +63,10 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_new_publish import com.vitorpamplona.amethyst.commons.resources.geocache_unnamed import com.vitorpamplona.amethyst.commons.resources.route_edit_geocache_hunt import com.vitorpamplona.amethyst.commons.resources.route_new_geocache_hunt +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Address diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/log/LogGeocacheFindScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/log/LogGeocacheFindScreen.kt index 86f68bd6f6..9322d6ce86 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/log/LogGeocacheFindScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/log/LogGeocacheFindScreen.kt @@ -88,10 +88,10 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_log_scan_code import com.vitorpamplona.amethyst.commons.resources.geocache_log_your_log import com.vitorpamplona.amethyst.commons.resources.geocache_unnamed import com.vitorpamplona.amethyst.commons.resources.route_log_geocache_find +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.rememberGeocachePalette import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.geocaches.datasource.GeocachesFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/highlights/NewHighlightScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/highlights/NewHighlightScreen.kt index d0efa00ce6..a5d403d1d0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/highlights/NewHighlightScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/highlights/NewHighlightScreen.kt @@ -71,11 +71,11 @@ import com.vitorpamplona.amethyst.commons.resources.new_highlight_note_placehold import com.vitorpamplona.amethyst.commons.resources.new_highlight_passage_placeholder import com.vitorpamplona.amethyst.commons.resources.new_highlight_source_label import com.vitorpamplona.amethyst.commons.resources.new_highlight_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.SuggestionListDefaultHeightPage import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt index 65832e94fb..e97012e2ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostScreen.kt @@ -108,6 +108,7 @@ import com.vitorpamplona.amethyst.commons.resources.schedule_post_always_on_prom import com.vitorpamplona.amethyst.commons.resources.schedule_post_always_on_prompt_title import com.vitorpamplona.amethyst.commons.resources.what_s_on_your_mind import com.vitorpamplona.amethyst.commons.resources.zapraiser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.aihelp.AiWritingHelpPanel import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer @@ -149,7 +150,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.VoiceAnonymizationSection import com.vitorpamplona.amethyst.ui.actions.uploads.VoiceMessagePreview import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField import com.vitorpamplona.amethyst.ui.components.getActivity -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.NoteCompose diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/nip75Goals/NewGoalScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/nip75Goals/NewGoalScreen.kt index d4a00ca1e2..17492a9013 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/nip75Goals/NewGoalScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/nip75Goals/NewGoalScreen.kt @@ -59,10 +59,10 @@ import com.vitorpamplona.amethyst.commons.resources.goal_summary_placeholder import com.vitorpamplona.amethyst.commons.resources.goal_website_label import com.vitorpamplona.amethyst.commons.resources.goal_website_placeholder import com.vitorpamplona.amethyst.commons.resources.new_goal +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/metadata/InterestSetMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/metadata/InterestSetMetadataScreen.kt index fbfc567185..1a509dffbe 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/metadata/InterestSetMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/metadata/InterestSetMetadataScreen.kt @@ -46,12 +46,12 @@ import com.vitorpamplona.amethyst.commons.resources.interest_set_name_placeholde import com.vitorpamplona.amethyst.commons.resources.interest_set_rename import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_be_able_to_sign_events import com.vitorpamplona.amethyst.commons.resources.read_only_user +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe 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.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/lists/PeopleListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/lists/PeopleListScreen.kt index df4f23cc1d..074ca3547a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/lists/PeopleListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/lists/PeopleListScreen.kt @@ -87,6 +87,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -101,7 +102,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.externalLinkForNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.display.DrawUser diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/packs/FollowPackScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/packs/FollowPackScreen.kt index ba1ee995f1..cf121ecf3e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/packs/FollowPackScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/packs/FollowPackScreen.kt @@ -76,6 +76,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -89,7 +90,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.PopupUpEffect import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.externalLinkForNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.display.DrawUser diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/FollowPackMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/FollowPackMetadataScreen.kt index deccce9e43..332f2e9754 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/FollowPackMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/FollowPackMetadataScreen.kt @@ -54,6 +54,7 @@ import com.vitorpamplona.amethyst.commons.resources.follow_pack_title import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_be_able_to_sign_events import com.vitorpamplona.amethyst.commons.resources.picture_url import com.vitorpamplona.amethyst.commons.resources.read_only_user +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar @@ -64,7 +65,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstModifier import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/PeopleListMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/PeopleListMetadataScreen.kt index 3f7bc2094d..f36cbc71b9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/PeopleListMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/metadata/PeopleListMetadataScreen.kt @@ -54,6 +54,7 @@ import com.vitorpamplona.amethyst.commons.resources.people_list_explainer import com.vitorpamplona.amethyst.commons.resources.people_list_title import com.vitorpamplona.amethyst.commons.resources.picture_url import com.vitorpamplona.amethyst.commons.resources.read_only_user +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.CreatingTopBar @@ -64,7 +65,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstModifier import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.actions.uploads.SelectSingleFromGallery -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserScreen.kt index 77efd20281..ea3b3be635 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserScreen.kt @@ -38,11 +38,11 @@ import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.follow_set_man_dialog_title2 +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.HexKey diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/AddToMusicPlaylistSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/AddToMusicPlaylistSheet.kt index 74e0206b09..43da52b5bb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/AddToMusicPlaylistSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/AddToMusicPlaylistSheet.kt @@ -69,6 +69,7 @@ import com.vitorpamplona.amethyst.commons.resources.music_playlist_create_action import com.vitorpamplona.amethyst.commons.resources.music_playlist_new_title_placeholder import com.vitorpamplona.amethyst.commons.resources.music_playlist_track_count_short import com.vitorpamplona.amethyst.commons.resources.music_playlist_untitled +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton @@ -76,7 +77,6 @@ import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.commons.ui.theme.grayText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicPlaylistScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicPlaylistScreen.kt index 68499a3062..bb427ee154 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicPlaylistScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicPlaylistScreen.kt @@ -92,6 +92,7 @@ import com.vitorpamplona.amethyst.commons.resources.music_playlist_track_count import com.vitorpamplona.amethyst.commons.resources.music_playlist_unknown_track import com.vitorpamplona.amethyst.commons.resources.music_playlist_uploading_banner import com.vitorpamplona.amethyst.commons.resources.new_music_playlist +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SendingTopBar @@ -102,7 +103,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicTrackScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicTrackScreen.kt index ae2b4315bf..354b50506b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicTrackScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/NewMusicTrackScreen.kt @@ -83,6 +83,7 @@ import com.vitorpamplona.amethyst.commons.resources.music_track_title_label import com.vitorpamplona.amethyst.commons.resources.music_track_title_placeholder import com.vitorpamplona.amethyst.commons.resources.music_track_uploading_banner import com.vitorpamplona.amethyst.commons.resources.new_music_track +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SendingTopBar @@ -91,7 +92,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/edit/EditNestSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/edit/EditNestSheet.kt index 32bb031808..9db1f21bc5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/edit/EditNestSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/edit/EditNestSheet.kt @@ -65,8 +65,8 @@ import com.vitorpamplona.amethyst.commons.resources.nest_create_field_service import com.vitorpamplona.amethyst.commons.resources.nest_create_field_summary import com.vitorpamplona.amethyst.commons.resources.nest_edit_save import com.vitorpamplona.amethyst.commons.resources.nest_edit_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt index f4057e5f87..22d4c37717 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt @@ -70,12 +70,12 @@ import com.vitorpamplona.amethyst.commons.resources.nest_lobby_host_label import com.vitorpamplona.amethyst.commons.resources.nest_lobby_listeners_count import com.vitorpamplona.amethyst.commons.resources.nest_lobby_no_listeners import com.vitorpamplona.amethyst.commons.resources.nest_lobby_open_action +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt index 812e45100d..0968b8d0ea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt @@ -74,12 +74,12 @@ import com.vitorpamplona.amethyst.commons.resources.nest_tab_audience import com.vitorpamplona.amethyst.commons.resources.nest_tab_chat import com.vitorpamplona.amethyst.commons.resources.nest_tab_hands import com.vitorpamplona.amethyst.commons.resources.nests +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.viewmodels.NestUiState import com.vitorpamplona.amethyst.commons.viewmodels.NestViewModel import com.vitorpamplona.amethyst.commons.viewmodels.ParticipantGrid -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.BouncingIntentNav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.room.chat.NestChatPanel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerReactionOverlay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerReactionOverlay.kt index fb38f49d3f..4a0152ebdc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerReactionOverlay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerReactionOverlay.kt @@ -45,8 +45,8 @@ import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.vitorpamplona.amethyst.commons.ui.richtext.InLineIconRenderer import com.vitorpamplona.amethyst.commons.viewmodels.RoomReaction -import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import kotlinx.collections.immutable.persistentListOf diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt index cdfb53996d..22770a5c52 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt @@ -59,6 +59,7 @@ import com.vitorpamplona.amethyst.commons.resources.messages_new_message_to import com.vitorpamplona.amethyst.commons.resources.messages_new_message_to_caption import com.vitorpamplona.amethyst.commons.resources.public_message import com.vitorpamplona.amethyst.commons.resources.zapraiser +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.note.creators.contentWarning.ContentSensitivityExplainer @@ -89,7 +90,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/EditPodcastShowScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/EditPodcastShowScreen.kt index f6c9d9314d..dd7d2eaa9b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/EditPodcastShowScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/EditPodcastShowScreen.kt @@ -73,11 +73,11 @@ import com.vitorpamplona.amethyst.commons.resources.podcast_show_type_episodic import com.vitorpamplona.amethyst.commons.resources.podcast_show_type_label import com.vitorpamplona.amethyst.commons.resources.podcast_show_type_serial import com.vitorpamplona.amethyst.commons.resources.podcast_show_website_label +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SendingTopBar import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.CoverImagePicker import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.UploadInProgressBanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastEpisodeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastEpisodeScreen.kt index 3fd495a94e..07d1d263f8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastEpisodeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastEpisodeScreen.kt @@ -89,13 +89,13 @@ import com.vitorpamplona.amethyst.commons.resources.podcast_episode_transcript_l import com.vitorpamplona.amethyst.commons.resources.podcast_episode_video_label import com.vitorpamplona.amethyst.commons.resources.podcast_new_episode import com.vitorpamplona.amethyst.commons.resources.podcast_publishing_banner +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SendingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.GallerySelectSingle import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.CoverImagePicker import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.UploadInProgressBanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastTrailerScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastTrailerScreen.kt index fce7fc8d01..f33b87c771 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastTrailerScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/authoring/NewPodcastTrailerScreen.kt @@ -70,12 +70,12 @@ import com.vitorpamplona.amethyst.commons.resources.podcast_trailer_title_placeh import com.vitorpamplona.amethyst.commons.resources.podcast_trailer_upload_cta import com.vitorpamplona.amethyst.commons.resources.podcast_trailer_upload_hint import com.vitorpamplona.amethyst.commons.resources.podcast_trailer_url_label +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SendingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.actions.StrippingFailureDialog import com.vitorpamplona.amethyst.ui.actions.uploads.SelectedMedia -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.UploadInProgressBanner import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.UploadPlaceholder diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt index 6cef6039e6..235be10c53 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt @@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.resources.telegram import com.vitorpamplona.amethyst.commons.resources.twitter import com.vitorpamplona.amethyst.commons.resources.website import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size15Modifier import com.vitorpamplona.amethyst.commons.ui.theme.SpacedBy3dp @@ -73,7 +74,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.toShortDisplay import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.components.util.LongPressCopyText import com.vitorpamplona.amethyst.ui.note.DrawPlayName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserNicknameCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserNicknameCard.kt index 4d55566d32..e614a462df 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserNicknameCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserNicknameCard.kt @@ -44,11 +44,11 @@ import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.nip85TrustedAssertions.ui.EditNicknameDialog import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nickname_private +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserNickname -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt index 94455ed169..eb4d0d85d6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt @@ -91,13 +91,13 @@ import com.vitorpamplona.amethyst.commons.resources.send_payment_method_onchain import com.vitorpamplona.amethyst.commons.resources.send_payment_no_methods import com.vitorpamplona.amethyst.commons.resources.send_payment_receipt_section import com.vitorpamplona.amethyst.commons.resources.send_payment_try_again +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.components.util.setText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.showAmount import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/KeepScreenBrightAndAwake.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/KeepScreenBrightAndAwake.kt index c09e5029e6..0965ab4c75 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/KeepScreenBrightAndAwake.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/KeepScreenBrightAndAwake.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.platform.LocalView -import com.vitorpamplona.amethyst.ui.components.getActivityWindow +import com.vitorpamplona.amethyst.commons.ui.components.getActivityWindow /** * Pins the screen to full brightness, and awake, while a QR code is on it. diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt index 4321485aa8..d649af657e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt @@ -54,18 +54,18 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image import com.vitorpamplona.amethyst.commons.resources.scan_qr import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Font14SP import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.largeProfilePictureModifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.ObserveAndDisplayNIP05 import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/AllRelayListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/AllRelayListScreen.kt index f867533b81..51a2e0107d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/AllRelayListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/AllRelayListScreen.kt @@ -87,6 +87,7 @@ import com.vitorpamplona.amethyst.commons.resources.trusted_section_explainer 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.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.SavingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -95,7 +96,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.RowColSpacing import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategoryFirstWithHorzBorderModifier import com.vitorpamplona.amethyst.commons.ui.theme.SettingsCategorySpacingWithHorzBorderModifier import com.vitorpamplona.amethyst.commons.ui.theme.grayText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.blocked.BlockedRelayListViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.blocked.renderBlockedItems diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/HiddenWordsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/HiddenWordsScreen.kt index 433c8eafcd..81edb6d1d7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/HiddenWordsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/HiddenWordsScreen.kt @@ -70,6 +70,7 @@ import com.vitorpamplona.amethyst.commons.resources.security_hidden_words_empty import com.vitorpamplona.amethyst.commons.ui.components.AddButton import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed +import com.vitorpamplona.amethyst.commons.ui.insets.rememberSafeImeInsets import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ShowUserButton import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -77,7 +78,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.HorzPadding import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.rememberSafeImeInsets import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.dal.HiddenWordsFeedViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt index d42f164b96..7e4d6e248c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt @@ -63,11 +63,11 @@ import com.vitorpamplona.amethyst.commons.resources.wallet_name import com.vitorpamplona.amethyst.commons.resources.wallet_name_hint import com.vitorpamplona.amethyst.commons.resources.wallet_paste_ndebit import com.vitorpamplona.amethyst.commons.resources.wallet_save +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size24Modifier import com.vitorpamplona.amethyst.ui.components.util.getText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt index c5eb0f0bd2..93aa0097fd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt @@ -67,13 +67,13 @@ import com.vitorpamplona.amethyst.commons.resources.wallet_name import com.vitorpamplona.amethyst.commons.resources.wallet_name_hint import com.vitorpamplona.amethyst.commons.resources.wallet_paste_uri import com.vitorpamplona.amethyst.commons.resources.wallet_save +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.Size24Modifier import com.vitorpamplona.amethyst.ui.components.util.getText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintRecommendationsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintRecommendationsScreen.kt index 3b5b9c7c6c..a51face0dc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintRecommendationsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintRecommendationsScreen.kt @@ -75,10 +75,10 @@ import com.vitorpamplona.amethyst.commons.resources.cashu_settings_delete_confir import com.vitorpamplona.amethyst.commons.resources.cashu_settings_delete_recommendation import com.vitorpamplona.amethyst.commons.resources.cashu_settings_my_recommendations import com.vitorpamplona.amethyst.commons.resources.cashu_settings_no_recommendations +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip87Ecash.recommendation.MintRecommendationEvent import androidx.compose.material3.Icon as Material3Icon diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintsScreen.kt index d8460f1efa..a6d8910bbc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuMintsScreen.kt @@ -84,9 +84,9 @@ import com.vitorpamplona.amethyst.commons.resources.cashu_wallet_autosaves import com.vitorpamplona.amethyst.commons.resources.cashu_wallet_saving import com.vitorpamplona.amethyst.commons.resources.wallet_add_cashu_title import com.vitorpamplona.amethyst.commons.resources.wallet_edit_cashu_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt index 5e6415aad7..746f6bd39f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt @@ -96,10 +96,10 @@ import com.vitorpamplona.amethyst.commons.resources.cashu_settings_stop_nutzaps_ import com.vitorpamplona.amethyst.commons.resources.cashu_settings_stop_nutzaps_subtitle import com.vitorpamplona.amethyst.commons.resources.cashu_settings_title import com.vitorpamplona.amethyst.commons.resources.danger_zone +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainZapSendDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainZapSendDialog.kt index 2e3a3d77ac..131305e7bb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainZapSendDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainZapSendDialog.kt @@ -115,6 +115,7 @@ import com.vitorpamplona.amethyst.commons.resources.onchain_send_title import com.vitorpamplona.amethyst.commons.resources.onchain_send_to import com.vitorpamplona.amethyst.commons.resources.onchain_send_use_note_split import com.vitorpamplona.amethyst.commons.resources.send +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -122,7 +123,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.bitcoinColor import com.vitorpamplona.amethyst.model.DEFAULT_ONCHAIN_ZAP_SATS import com.vitorpamplona.amethyst.model.MIN_ONCHAIN_ZAP_SATS import com.vitorpamplona.amethyst.ui.components.namecoin.NamecoinResolutionRow -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.UserSuggestionState diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/NewWorkoutScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/NewWorkoutScreen.kt index e229c26c1c..141806845b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/NewWorkoutScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/NewWorkoutScreen.kt @@ -70,10 +70,10 @@ import com.vitorpamplona.amethyst.commons.resources.workout_minutes import com.vitorpamplona.amethyst.commons.resources.workout_notes import com.vitorpamplona.amethyst.commons.resources.workout_seconds import com.vitorpamplona.amethyst.commons.resources.workout_title +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.PostingTopBar import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.workouts.suggestion.DetectedWorkoutCarousel import com.vitorpamplona.quartz.experimental.fitness.workout.tags.DistanceTag diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/login/LoginScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/login/LoginScreen.kt index 79f0338488..a6b5937134 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/login/LoginScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/login/LoginScreen.kt @@ -79,13 +79,13 @@ import com.vitorpamplona.amethyst.commons.resources.hide_password import com.vitorpamplona.amethyst.commons.resources.ncryptsec_password import com.vitorpamplona.amethyst.commons.resources.show_password import com.vitorpamplona.amethyst.commons.resources.temporary_account +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp import com.vitorpamplona.amethyst.commons.ui.theme.Size40dp import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager import com.vitorpamplona.amethyst.ui.screen.loggedOff.TorSettingsSetup import com.vitorpamplona.amethyst.ui.screen.loggedOff.legal.TermsGate diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/signup/SignUpScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/signup/SignUpScreen.kt index b579310fd6..3987e1dfcc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/signup/SignUpScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/signup/SignUpScreen.kt @@ -59,13 +59,13 @@ import com.vitorpamplona.amethyst.commons.resources.app_logo import com.vitorpamplona.amethyst.commons.resources.how_should_we_call_you import com.vitorpamplona.amethyst.commons.resources.my_awesome_name import com.vitorpamplona.amethyst.commons.resources.welcome +import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size10dp import com.vitorpamplona.amethyst.commons.ui.theme.Size20dp import com.vitorpamplona.amethyst.commons.ui.theme.Size40dp import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager import com.vitorpamplona.amethyst.ui.screen.loggedOff.TorSettingsSetup import com.vitorpamplona.amethyst.ui.screen.loggedOff.legal.TermsGate diff --git a/commonsUI/build.gradle.kts b/commonsUI/build.gradle.kts index 0bfcd17344..453bc84252 100644 --- a/commonsUI/build.gradle.kts +++ b/commonsUI/build.gradle.kts @@ -204,6 +204,9 @@ kotlin { getByName("androidHostTest") { dependencies { implementation(libs.junit) + // SafeImeInsetsTest mocks the android.view.View its per-window cache is keyed on. + implementation(libs.mockk) + implementation(libs.kotlinx.coroutines.test) } } diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsetsTest.kt b/commonsUI/src/androidHostTest/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsetsTest.kt similarity index 99% rename from amethyst/src/test/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsetsTest.kt rename to commonsUI/src/androidHostTest/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsetsTest.kt index f98f3eb1e6..ee04d01c65 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsetsTest.kt +++ b/commonsUI/src/androidHostTest/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsetsTest.kt @@ -18,7 +18,7 @@ * 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.insets +package com.vitorpamplona.amethyst.commons.ui.insets import android.view.View import androidx.compose.foundation.layout.WindowInsets diff --git a/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/WindowUtils.android.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/WindowUtils.android.kt new file mode 100644 index 0000000000..ee03c816ac --- /dev/null +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/WindowUtils.android.kt @@ -0,0 +1,43 @@ +/* + * 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.commons.ui.components + +import android.app.Activity +import android.content.Context +import android.content.ContextWrapper +import android.view.Window +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.window.DialogWindowProvider + +// Window utils +@Composable +fun getDialogWindow(): Window? = (LocalView.current.parent as? DialogWindowProvider)?.window + +@Composable +fun getActivityWindow(): Window? = LocalView.current.context.getActivityWindow() + +private tailrec fun Context.getActivityWindow(): Window? = + when (this) { + is Activity -> window + is ContextWrapper -> baseContext.getActivityWindow() + else -> null + } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsets.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.android.kt similarity index 94% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsets.kt rename to commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.android.kt index 73c1c2c411..cafd63c557 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/insets/SafeImeInsets.kt +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.android.kt @@ -18,14 +18,13 @@ * 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.insets +package com.vitorpamplona.amethyst.commons.ui.insets import android.view.View import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.imeAnimationTarget -import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable @@ -34,7 +33,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow -import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.Density @@ -207,7 +205,7 @@ internal suspend fun watchForStrandedIme( */ @OptIn(ExperimentalLayoutApi::class) @Composable -fun rememberSafeImeInsets(): SafeImeInsets { +actual fun rememberSafeImeInsets(): WindowInsets { val view = LocalView.current val density = LocalDensity.current val animated = WindowInsets.ime @@ -221,13 +219,3 @@ fun rememberSafeImeInsets(): SafeImeInsets { return insets } - -/** - * Drop-in replacement for `Modifier.imePadding()` that survives a stranded IME inset. - * - * Prefer this everywhere in the app; `imePadding()` reads the raw animated inset and will hold a - * keyboard-sized gap open for the rest of the activity's life once Compose's insets listener wedges. - * Consumption semantics are identical — this is `windowInsetsPadding` over the same inset. - */ -@Composable -fun Modifier.imePaddingSafe(): Modifier = windowInsetsPadding(rememberSafeImeInsets()) diff --git a/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.android.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.android.kt new file mode 100644 index 0000000000..4c62b35afa --- /dev/null +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.android.kt @@ -0,0 +1,99 @@ +/* + * 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.commons.ui.layouts + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat +import com.vitorpamplona.amethyst.commons.ui.components.getActivityWindow +import kotlinx.coroutines.flow.distinctUntilChanged + +/** Fraction at which the tracked in-app bar is considered fully settled into the hidden edge. */ +private const val STATUS_BAR_HIDE_THRESHOLD = 0.999f + +/** + * Fraction the chrome must fall back below before the OS status bar reappears. Lower than + * [STATUS_BAR_HIDE_THRESHOLD] on purpose: this hysteresis gap means the finger that stops a fast + * scroll — which makes a tiny reverse reveal — does not immediately pop the status bar back. The + * user has to deliberately scroll the chrome back by ~30% before the status bar returns. + */ +private const val STATUS_BAR_SHOW_THRESHOLD = 0.7f + +/** + * Hides the OS status bar once the tracked in-app bar has settled into the hidden edge, and shows it + * the moment it starts coming back. The OS status bar is binary (cannot slide), so it is driven off + * the collapse fraction with a near-1 threshold, which means it toggles on settle rather than + * mid-drag. + * + * The status bar sits with the top in-app bar, so it tracks the top bar's collapse. The top and + * bottom bars can collapse at different rates (each clamps to its own height), so tracking the top + * fraction keeps the status bar in step with the chrome directly beneath it. On screens with no top + * bar (topHeightLimit == 0) it falls back to the bottom bar, so the status bar still hides in sync + * with the bottom navigation. + * + * Only the top status bar is touched; the bottom OS navigation bar is left alone. + * BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE lets the user swipe to peek the status bar while immersed. + * The status bar is always restored on dispose so leaving an immersive screen can never strand a + * hidden bar. + */ +@Composable +internal actual fun ImmersiveStatusBarEffect(state: DisappearingBarState) { + val view = LocalView.current + if (view.isInEditMode) return + val window = getActivityWindow() ?: return + val controller = remember(window, view) { WindowInsetsControllerCompat(window, view) } + + LaunchedEffect(controller, state) { + controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + var statusBarHidden = false + snapshotFlow { + if (state.topHeightLimit > 0f) state.topCollapsedFraction else state.bottomCollapsedFraction + }.distinctUntilChanged() + .collect { fraction -> + // Hysteresis: hide once fully settled, but only show again after the chrome has + // been pulled back past STATUS_BAR_SHOW_THRESHOLD. Between the two thresholds the + // status bar keeps its current state, so a stray reverse reveal can't flip it. + val shouldHide = + when { + fraction >= STATUS_BAR_HIDE_THRESHOLD -> true + fraction <= STATUS_BAR_SHOW_THRESHOLD -> false + else -> statusBarHidden + } + if (shouldHide != statusBarHidden) { + statusBarHidden = shouldHide + if (shouldHide) { + controller.hide(WindowInsetsCompat.Type.statusBars()) + } else { + controller.show(WindowInsetsCompat.Type.statusBars()) + } + } + } + } + + DisposableEffect(controller) { + onDispose { controller.show(WindowInsetsCompat.Type.statusBars()) } + } +} diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.kt new file mode 100644 index 0000000000..acbb55759c --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.kt @@ -0,0 +1,46 @@ +/* + * 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.commons.ui.insets + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +/** + * The IME inset to lay out against, in place of `WindowInsets.ime`. + * + * On Android this corrects a Compose insets listener that can freeze the animated IME inset for the + * rest of the activity's life (see the Android actual's `SafeImeInsets`). Desktop and iOS have no + * such defect and return `WindowInsets.ime` as is. + */ +@Composable +expect fun rememberSafeImeInsets(): WindowInsets + +/** + * Drop-in replacement for `Modifier.imePadding()` that survives a stranded IME inset. + * + * Prefer this everywhere; `imePadding()` reads the raw animated inset and, on Android, will hold a + * keyboard-sized gap open for the rest of the activity's life once Compose's insets listener wedges. + * Consumption semantics are identical — this is `windowInsetsPadding` over the same inset. + */ +@Composable +fun Modifier.imePaddingSafe(): Modifier = windowInsetsPadding(rememberSafeImeInsets()) diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/DisappearingScaffold.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/DisappearingScaffold.kt new file mode 100644 index 0000000000..972ba2c8b0 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/DisappearingScaffold.kt @@ -0,0 +1,309 @@ +/* + * 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.commons.ui.layouts + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.only +import androidx.compose.foundation.layout.systemBars +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.layout.SubcomposeLayout +import androidx.compose.ui.unit.Constraints +import androidx.compose.ui.unit.dp +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner +import com.vitorpamplona.amethyst.commons.ui.insets.rememberSafeImeInsets +import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness +import kotlinx.coroutines.launch + +private enum class DisappearingSlot { Top, Bottom, Content, Fab } + +private val FabEdgePadding = 16.dp + +/** + * A scaffold whose top and bottom bars slide away while the content scrolls and come back on the + * reverse scroll, with a floating button that rides along with the bottom bar. + * + * @param immersiveScrolling read on every scroll; false keeps the bars in place (the user's + * immersive-scrolling setting). + * @param allowBarHide false pins the bars and leaves the OS status bar alone (large screens, + * screens that must keep their chrome). + */ +@Composable +fun DisappearingScaffold( + isInvertedLayout: Boolean, + topBar: (@Composable () -> Unit)? = null, + bottomBar: (@Composable () -> Unit)? = null, + floatingButton: (@Composable () -> Unit)? = null, + immersiveScrolling: () -> Boolean = { true }, + isActive: () -> Boolean = { true }, + allowBarHide: Boolean = true, + mainContent: @Composable (padding: PaddingValues) -> Unit, +) { + val state = rememberDisappearingBarState() + + // Callers pin the chrome (e.g. large screens) through allowBarHide: bars never slide away on + // scroll, and the immersive status-bar hiding stays off. + val canHideBars = allowBarHide + + // Hold the latest values in state so the NSC's captured lambda stays fresh across + // recompositions without rebuilding the NSC itself. + val latestIsActive by rememberUpdatedState(isActive) + val latestAllowBarHide by rememberUpdatedState(canHideBars) + val latestImmersiveScrolling by rememberUpdatedState(immersiveScrolling) + + val connection = + remember(state, isInvertedLayout) { + DisappearingBarNestedScroll( + state = state, + canScroll = { + latestAllowBarHide && + latestIsActive() && + latestImmersiveScrolling() + }, + reverseLayout = isInvertedLayout, + ) + } + + // Only wire the lifecycle observer + system-bar control when the scaffold actually moves its bars. + if (canHideBars) { + ResetBarsOnResume(state) + ImmersiveStatusBarEffect(state) + } + + // If the bars were scrolled away when hiding got disabled (e.g. the window grew to a + // large tier mid-scroll), nothing above can bring them back — the nested-scroll + // connection and the resume reset are gone. Snap them visible here instead of + // leaving the chrome stranded off-screen. + LaunchedEffect(canHideBars, state) { + if (!canHideBars) state.resetToVisible() + } + + // When bars are pinned, skip attaching the nested-scroll connection entirely. + // The outer Surface provides the Material container color + onBackground as + // LocalContentColor, matching M3 Scaffold's behaviour (without it, default text + // color falls back to Color.Black and is invisible on the dark theme). + // Hoisted above the branch: imePaddingSafe() inside both arms would put the call in two + // different composition groups, so toggling canHideBars (a window-size-class change) would + // dispose and rebuild it. Resolved once here, and handed to ScaffoldLayout below so the value + // this pads with is the same object the nav-bar subtraction reads. + val imeInsets = rememberSafeImeInsets() + val baseModifier = + if (canHideBars) { + Modifier.windowInsetsPadding(imeInsets).nestedScroll(connection) + } else { + Modifier.windowInsetsPadding(imeInsets) + } + val rootModifier = + baseModifier + // systemBars (not just statusBars) so a desktop window's caption bar is respected too. + .let { if (topBar == null) it.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Top)) else it } + .let { if (bottomBar == null) it.navigationBarsPadding() else it } + + Surface( + modifier = rootModifier, + color = MaterialTheme.colorScheme.background, + contentColor = MaterialTheme.colorScheme.onBackground, + ) { + ScaffoldLayout( + state = state, + topBar = topBar, + bottomBar = bottomBar, + floatingButton = floatingButton, + imeInsets = imeInsets, + mainContent = mainContent, + ) + } +} + +@Composable +private fun ScaffoldLayout( + state: DisappearingBarState, + topBar: (@Composable () -> Unit)?, + bottomBar: (@Composable () -> Unit)?, + floatingButton: (@Composable () -> Unit)?, + imeInsets: WindowInsets, + mainContent: @Composable (padding: PaddingValues) -> Unit, +) { + val navBarInsets = WindowInsets.navigationBars + SubcomposeLayout { constraints -> + val layoutWidth = constraints.maxWidth + val layoutHeight = constraints.maxHeight + val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0) + + val topPlaceable = + topBar?.let { bar -> + subcompose(DisappearingSlot.Top) { + Column( + modifier = + Modifier.graphicsLayer { + translationY = state.topHeightOffset + }, + ) { + bar() + HorizontalDivider(thickness = DividerThickness) + } + }.firstOrNull()?.measure(looseConstraints) + } + val topHeight = topPlaceable?.height ?: 0 + + val bottomPlaceable = + bottomBar?.let { bar -> + subcompose(DisappearingSlot.Bottom) { + Column( + modifier = + Modifier.graphicsLayer { + translationY = -state.bottomHeightOffset + }, + ) { + bar() + } + }.firstOrNull()?.measure(looseConstraints) + } + // When the bar lambda is provided but its content emits nothing (e.g. AppBottomBar + // hides itself on canPop entries, or while the keyboard is up), reserve the + // system-nav-bar inset so the FAB and content stay clear of the navigation bar instead + // of sliding under it. Subtract the IME inset: the root imePadding has already lifted the + // whole scaffold above the keyboard, and the IME inset spans the nav-bar band, so + // reserving the full nav bar on top of that would double-count and strand a gap above the + // keyboard (the `bottomBar == null` branch gets this for free via navigationBarsPadding, + // which excludes the consumed IME inset). The `bottomBar == null` case is on rootModifier. + val bottomHeight = + (bottomPlaceable?.height ?: 0).let { measured -> + if (bottomBar != null && measured == 0) { + (navBarInsets.getBottom(this) - imeInsets.getBottom(this)).coerceAtLeast(0) + } else { + measured + } + } + + // Publish the measured limits so the nested-scroll connection can clamp correctly. + state.topHeightLimit = topHeight.toFloat() + state.bottomHeightLimit = bottomHeight.toFloat() + + val contentPadding = + PaddingValues( + top = topHeight.toDp(), + bottom = bottomHeight.toDp(), + ) + + val contentPlaceable = + subcompose(DisappearingSlot.Content) { + CompositionLocalProvider( + LocalDisappearingScaffoldPadding provides contentPadding, + LocalDisappearingBarState provides state, + ) { + mainContent(contentPadding) + } + }.firstOrNull()?.measure( + Constraints.fixed(layoutWidth, layoutHeight), + ) + + val fabPlaceable = + floatingButton?.let { fab -> + subcompose(DisappearingSlot.Fab) { + FloatingButtonHolder(state = state) { fab() } + }.firstOrNull()?.measure(looseConstraints) + } + + val fabEdgePx = FabEdgePadding.roundToPx() + + layout(layoutWidth, layoutHeight) { + contentPlaceable?.place(0, 0) + topPlaceable?.place(0, 0) + bottomPlaceable?.place(0, layoutHeight - bottomHeight) + if (fabPlaceable != null) { + val x = layoutWidth - fabPlaceable.width - fabEdgePx + val yBase = layoutHeight - bottomHeight - fabPlaceable.height - fabEdgePx + fabPlaceable.place(x, yBase) + } + } + } +} + +/** + * Holds the floating button. Scales / fades it with the bottom-bar collapse fraction and + * rides along with the bar via graphicsLayer, so the layout pass is untouched while + * the bar animates. + */ +@Composable +private fun FloatingButtonHolder( + state: DisappearingBarState, + content: @Composable () -> Unit, +) { + Box( + modifier = + Modifier.graphicsLayer { + val visible = (1f - state.bottomCollapsedFraction).coerceAtLeast(0.001f) + scaleX = visible + scaleY = visible + alpha = visible + translationY = -state.bottomHeightOffset + }, + ) { + content() + } +} + +@Composable +private fun ResetBarsOnResume(state: DisappearingBarState) { + val lifecycleOwner = LocalLifecycleOwner.current + val scope = rememberCoroutineScope() + DisposableEffect(lifecycleOwner, state) { + val observer = + LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_RESUME && + (state.topHeightOffset != 0f || state.bottomHeightOffset != 0f) + ) { + scope.launch { state.resetToVisible() } + } + } + lifecycleOwner.lifecycle.addObserver(observer) + onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } + } +} + +/** + * Hides the OS status bar while the in-app chrome is scrolled away, and restores it when the chrome + * returns or this leaves composition. Only Android has a status bar to hide; elsewhere a no-op. + */ +@Composable +internal expect fun ImmersiveStatusBarEffect(state: DisappearingBarState) diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserNameText.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserNameText.kt new file mode 100644 index 0000000000..c8d81847e3 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/UserNameText.kt @@ -0,0 +1,73 @@ +/* + * 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.commons.ui.note + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists +import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji + +/** + * A user's name on one line: [displayName] with its custom emojis resolved against [tags], or the + * shortened npub of [user] while no name is known. + * + * Callers pick the name (a petname, the profile's best name, ...) and the tags its emojis come from. + */ +@Composable +fun UserNameText( + user: User, + displayName: String?, + tags: ImmutableListOfLists?, + modifier: Modifier = Modifier, + fontWeight: FontWeight = FontWeight.Bold, + textColor: Color = Color.Unspecified, + textAlign: TextAlign? = null, +) { + if (displayName != null) { + CreateTextWithEmoji( + text = displayName, + tags = tags, + fontWeight = fontWeight, + textAlign = textAlign, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = modifier, + color = textColor, + ) + } else { + Text( + text = remember(user) { user.pubkeyDisplayHex() }, + fontWeight = fontWeight, + modifier = modifier, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = textColor, + textAlign = textAlign, + ) + } +} diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt index 1cce447446..c6c35db4d0 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt @@ -24,20 +24,35 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent +import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.takeOrElse +import androidx.compose.ui.text.LinkAnnotation import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextLinkStyles +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.text.withLink import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil3.compose.AsyncImage +import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.quartz.nip30CustomEmoji.CustomEmoji import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -75,6 +90,8 @@ fun InLineIconRenderer( wordsInOrder: ImmutableList, style: SpanStyle, fontSize: TextUnit = TextUnit.Unspecified, + maxLines: Int = Int.MAX_VALUE, + overflow: TextOverflow = TextOverflow.Clip, modifier: Modifier = Modifier, ) { val placeholderSize = @@ -109,6 +126,8 @@ fun InLineIconRenderer( text = annotatedText, inlineContent = inlineContent, fontSize = fontSize, + maxLines = maxLines, + overflow = overflow, modifier = modifier, ) } @@ -134,3 +153,277 @@ private fun ImmutableList.buildInlineContent(placeholder null } }.associate { it.first to it.second } + +@Composable +fun CustomEmojiChecker( + text: String, + tags: ImmutableListOfLists?, + onRegularText: @Composable (String) -> Unit, + onEmojiText: @Composable (ImmutableList) -> Unit, +) { + val mayContainEmoji by remember(text, tags) { + mutableStateOf(CustomEmoji.fastMightContainEmoji(text, tags?.lists)) + } + + if (mayContainEmoji) { + var emojiList by + remember(text, tags) { + mutableStateOf?>(null) + } + + LaunchedEffect(text, tags) { + val newEmojiList = CustomEmoji.assembleAnnotatedList(text, tags?.lists) + if (newEmojiList != null) { + emojiList = newEmojiList + } + } + + emojiList?.let { + onEmojiText(it) + } ?: run { + onRegularText(text) + } + } else { + onRegularText(text) + } +} + +@Composable +fun CustomEmojiChecker( + text: String, + emojis: ImmutableMap, + onRegularText: @Composable (String) -> Unit, + onEmojiText: @Composable (ImmutableList) -> Unit, +) { + val mayContainEmoji by remember(text, emojis) { + mutableStateOf(CustomEmoji.fastMightContainEmoji(text, emojis)) + } + + if (mayContainEmoji) { + var emojiList by + remember(text, emojis) { + mutableStateOf?>(null) + } + + LaunchedEffect(text, emojis) { + val newEmojiList = CustomEmoji.assembleAnnotatedList(text, emojis) + if (newEmojiList != null) { + emojiList = newEmojiList + } + } + + emojiList?.let { + onEmojiText(it) + } ?: run { + onRegularText(text) + } + } else { + onRegularText(text) + } +} + +@Composable +fun CreateTextWithEmoji( + text: String, + tags: ImmutableListOfLists?, + color: Color = Color.Unspecified, + textAlign: TextAlign? = null, + fontWeight: FontWeight? = null, + fontSize: TextUnit = TextUnit.Unspecified, + maxLines: Int = Int.MAX_VALUE, + overflow: TextOverflow = TextOverflow.Clip, + modifier: Modifier = Modifier, +) { + CustomEmojiChecker( + text, + tags, + onEmojiText = { + val textColor = + color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } + val style = + LocalTextStyle.current + .merge( + TextStyle( + color = textColor, + textAlign = TextAlign.Unspecified, + fontWeight = fontWeight, + fontSize = fontSize, + ), + ).toSpanStyle() + + InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) + }, + onRegularText = { + val textColor = + color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } + Text( + text = it, + color = textColor, + textAlign = textAlign, + fontWeight = fontWeight, + fontSize = fontSize, + maxLines = maxLines, + overflow = overflow, + modifier = modifier, + ) + }, + ) +} + +@Composable +fun CreateTextWithEmoji( + text: String, + emojis: ImmutableMap, + color: Color = Color.Unspecified, + textAlign: TextAlign? = null, + fontWeight: FontWeight? = null, + fontSize: TextUnit = TextUnit.Unspecified, + maxLines: Int = Int.MAX_VALUE, + overflow: TextOverflow = TextOverflow.Clip, + modifier: Modifier = Modifier, +) { + val textColor = + color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } + + CustomEmojiChecker( + text, + emojis, + onEmojiText = { + val currentStyle = LocalTextStyle.current + val style = + remember(currentStyle) { + currentStyle + .merge( + TextStyle( + color = textColor, + textAlign = TextAlign.Unspecified, + fontWeight = fontWeight, + fontSize = fontSize, + ), + ).toSpanStyle() + } + + InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) + }, + onRegularText = { + Text( + text = it, + color = textColor, + textAlign = textAlign, + fontWeight = fontWeight, + fontSize = fontSize, + maxLines = maxLines, + overflow = overflow, + modifier = modifier, + ) + }, + ) +} + +@Composable +fun CreateClickableTextWithEmoji( + clickablePart: String, + maxLines: Int = Int.MAX_VALUE, + tags: ImmutableListOfLists?, + style: TextStyle, + onClick: () -> Unit, +) { + CustomEmojiChecker( + text = clickablePart, + tags = tags, + onRegularText = { + Text( + text = + buildAnnotatedString { + withLink( + LinkAnnotation.Clickable( + "me", + TextLinkStyles(style = style.toSpanStyle()), + ) { + onClick() + }, + ) { + append(clickablePart) + } + }, + style = style, + maxLines = maxLines, + ) + }, + onEmojiText = { + ClickableInLineIconRenderer(it, maxLines, style.toSpanStyle(), onClick = onClick) + }, + ) +} + +@Composable +fun ClickableInLineIconRenderer( + wordsInOrder: ImmutableList, + maxLines: Int = Int.MAX_VALUE, + style: SpanStyle, + suffix: String? = null, + nonClickableStype: SpanStyle? = null, + onClick: () -> Unit, +) { + val placeholderSize = + remember(style) { + if (style.fontSize == TextUnit.Unspecified) 22.sp else style.fontSize.times(1.1f) + } + + val inlineContent = + wordsInOrder + .mapIndexedNotNull { idx, value -> + if (value is CustomEmoji.ImageUrlType) { + Pair( + "inlineContent$idx", + InlineTextContent( + Placeholder( + width = placeholderSize, + height = placeholderSize, + placeholderVerticalAlign = PlaceholderVerticalAlign.Center, + ), + ) { + AsyncImage( + model = value.url, + contentDescription = null, + modifier = + Modifier + .fillMaxSize() + .padding(1.dp), + ) + }, + ) + } else { + null + } + }.associate { it.first to it.second } + + val annotatedText = + buildAnnotatedString { + wordsInOrder.forEachIndexed { idx, value -> + withLink( + LinkAnnotation.Clickable("link", TextLinkStyles(style)) { + onClick() + }, + ) { + if (value is CustomEmoji.TextType) { + append(value.text) + } else if (value is CustomEmoji.ImageUrlType) { + appendInlineContent("inlineContent$idx", "[icon]") + } + } + } + + if (suffix != null && nonClickableStype != null) { + withStyle(nonClickableStype) { + append(suffix) + } + } + } + + Text( + text = annotatedText, + inlineContent = inlineContent, + maxLines = maxLines, + ) +} diff --git a/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.skiko.kt b/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.skiko.kt new file mode 100644 index 0000000000..c81d3c11c9 --- /dev/null +++ b/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/insets/SafeImeInsets.skiko.kt @@ -0,0 +1,28 @@ +/* + * 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.commons.ui.insets + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.ime +import androidx.compose.runtime.Composable + +@Composable +actual fun rememberSafeImeInsets(): WindowInsets = WindowInsets.ime diff --git a/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.skiko.kt b/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.skiko.kt new file mode 100644 index 0000000000..c71186d11c --- /dev/null +++ b/commonsUI/src/skikoMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ImmersiveStatusBarEffect.skiko.kt @@ -0,0 +1,27 @@ +/* + * 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.commons.ui.layouts + +import androidx.compose.runtime.Composable + +// Desktop and iOS have no OS status bar for the scaffold to hide. +@Composable +internal actual fun ImmersiveStatusBarEffect(state: DisappearingBarState) {} From 07e389508b5575f350b25538f0b5c7c775714aeb Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 12:53:39 +0000 Subject: [PATCH 7/9] build: add androidx.core to commonsUI androidMain The shared DisappearingScaffold's Android status-bar effect uses WindowInsetsControllerCompat, which was only on the app's classpath. androidx.core (Apache-2.0) is already an app dependency. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- commonsUI/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commonsUI/build.gradle.kts b/commonsUI/build.gradle.kts index 453bc84252..5cadbc3ea5 100644 --- a/commonsUI/build.gradle.kts +++ b/commonsUI/build.gradle.kts @@ -180,6 +180,8 @@ kotlin { dependencies { // Android-specific Compose tooling implementation(libs.androidx.ui.tooling.preview) + // WindowInsetsControllerCompat, for DisappearingScaffold's immersive status bar. + implementation(libs.androidx.core.ktx) } } From 96598a042db55e7bc7e71cc0ae6c0b956fa00602 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 13:35:45 +0000 Subject: [PATCH 8/9] refactor: share the clipboard helpers, screen-layout types, FAB padding and account-free route builders - Clipboard.setText/getText become one commonsUI expect: Android keeps ClipData, desktop the AWT StringSelection code (its own copy is deleted), iOS uses UIPasteboard. 49 files repoint their import. - CrossfadeIfEnabled's enabled flag defaults to a new LocalAnimationsEnabled, which AppNavigation provides from the performance-mode feature set (collected, so it follows the setting). Shared composables no longer need the AccountViewModel to respect it. - NavigationStyle, ScreenLayoutSpec and LocalScreenLayout move to commonsUI ui/layouts; the window-size logic that computes them stays in the app. fabBottomBarPadding / FabBottomBarPadded / FABPaddingFromBottom move to commonsUI ui/navigation/bottombars. - The account-free route builders (routeFor for channels, rooms, groups and users, routeForUser, authorRouteFor, minichatRouteFor) move to commons model/navigation. routeFor(Note/Event, Account), routeForPointer and THREAD_VIEW_KINDS stay in the app. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .../vitorpamplona/amethyst/ui/MainActivity.kt | 1 + .../amethyst/ui/actions/InformationDialog.kt | 2 +- .../mediaServers/BlossomBlobManagerScreen.kt | 2 +- .../ui/components/ClickableBuzzInviteLink.kt | 2 +- .../components/ClickableConcordInviteLink.kt | 2 +- .../ui/components/ClickableRelayGroupLink.kt | 2 +- .../ui/components/ClickableRelayUrl.kt | 2 +- .../amethyst/ui/components/ClickableRoute.kt | 1 + .../amethyst/ui/components/PaymentCard.kt | 2 +- .../amethyst/ui/components/RichTextViewer.kt | 1 + .../amethyst/ui/components/UrlPreviewCard.kt | 2 +- .../ui/components/ZoomableContentView.kt | 2 +- .../ui/components/util/LongPressCopyText.kt | 1 + .../ui/layouts/DisappearingScaffold.kt | 1 + .../amethyst/ui/layouts/ScreenLayout.kt | 42 +--------- .../amethyst/ui/navigation/AppNavigation.kt | 9 +- .../ui/navigation/bottombars/AppBottomBar.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 1 + .../ui/navigation/routes/RouteMaker.kt | 53 +----------- .../topbars/UserDrawerSearchTopBar.kt | 2 +- .../amethyst/ui/note/BadgeCompose.kt | 1 + .../amethyst/ui/note/Bolt12ZapGallery.kt | 1 + .../amethyst/ui/note/CopyNoteText.kt | 2 +- .../vitorpamplona/amethyst/ui/note/Gallery.kt | 3 +- .../amethyst/ui/note/MessageSetCompose.kt | 1 + .../amethyst/ui/note/MultiSetCompose.kt | 3 +- .../ui/note/NIP05VerificationDisplay.kt | 3 +- .../amethyst/ui/note/NoteCompose.kt | 1 + .../amethyst/ui/note/NoteQuickActionMenu.kt | 2 +- .../amethyst/ui/note/NutzapGallery.kt | 1 + .../amethyst/ui/note/NutzapUserSetCompose.kt | 1 + .../amethyst/ui/note/OnchainZapGallery.kt | 1 + .../amethyst/ui/note/ReactionsRow.kt | 2 +- .../amethyst/ui/note/RelayListRow.kt | 2 +- .../amethyst/ui/note/ReplyInformation.kt | 1 + .../ui/note/UpdateReactionTypeDialog.kt | 1 + .../amethyst/ui/note/UserCompose.kt | 1 + .../amethyst/ui/note/UserProfilePicture.kt | 1 + .../amethyst/ui/note/ZapUserSetCompose.kt | 1 + .../creators/invoice/ClinkOfferPreview.kt | 1 + .../amethyst/ui/note/elements/ForkInfo.kt | 1 + .../ui/note/elements/NoteActionSections.kt | 2 +- .../amethyst/ui/note/types/AppDefinition.kt | 3 +- .../amethyst/ui/note/types/AudioTrack.kt | 1 + .../amethyst/ui/note/types/Badge.kt | 1 + .../amethyst/ui/note/types/ChatMessage.kt | 1 + .../ui/note/types/ChatMessageEncryptedFile.kt | 1 + .../amethyst/ui/note/types/Chess.kt | 1 + .../amethyst/ui/note/types/CommunityHeader.kt | 1 + .../amethyst/ui/note/types/EntityRating.kt | 1 + .../amethyst/ui/note/types/FollowList.kt | 1 + .../amethyst/ui/note/types/Fundraiser.kt | 2 +- .../amethyst/ui/note/types/Highlight.kt | 1 + .../amethyst/ui/note/types/LiveActivity.kt | 1 + .../amethyst/ui/note/types/MeetingSpace.kt | 1 + .../amethyst/ui/note/types/OnchainZapEvent.kt | 2 +- .../amethyst/ui/note/types/PodcastPeople.kt | 1 + .../amethyst/ui/note/types/Poll.kt | 1 + .../amethyst/ui/note/types/PrivateMessage.kt | 1 + .../amethyst/ui/note/types/ProfileCard.kt | 1 + .../ui/note/types/PublicationSection.kt | 1 + .../ui/note/types/RelayGroupMessage.kt | 1 + .../amethyst/ui/note/types/RelayList.kt | 2 +- .../amethyst/ui/note/types/Text.kt | 1 + .../ui/note/types/TextModification.kt | 1 + .../amethyst/ui/note/types/TorrentComment.kt | 1 + .../AccountSwitcherAndLeftDrawerLayout.kt | 4 +- .../ProfileAppRecommendationsScreen.kt | 1 + .../loggedIn/articles/ArticlesScreen.kt | 2 +- .../backups/BackupConflictEventViews.kt | 1 + .../backups/BackupConflictListViews.kt | 1 + .../backups/BackupConflictReviewScreen.kt | 1 + .../ui/screen/loggedIn/badges/BadgesScreen.kt | 2 +- .../badges/profile/ProfileBadgesScreen.kt | 1 + .../display/BookmarkGroupItemOptions.kt | 2 +- .../list/ListOfBookmarkGroupsScreen.kt | 2 +- .../ArticleBookmarkListManagementScreen.kt | 2 +- .../PostBookmarkListManagementScreen.kt | 2 +- .../old/OldBookmarkListScreen.kt | 2 +- .../loggedIn/buzz/AgentAttestationScreen.kt | 2 +- .../buzz/BuzzWorkspaceOverflowMenu.kt | 2 +- .../calendars/CalendarCollectionsScreen.kt | 2 +- .../loggedIn/calendars/CalendarsScreen.kt | 2 +- .../chats/feed/ChatEngagementDetailSheet.kt | 1 + .../loggedIn/chats/feed/ChatMessageCompose.kt | 1 + .../chats/feed/types/RenderChatZap.kt | 1 + .../chats/geohashChat/GeohashChatsScreen.kt | 2 +- .../marmotGroup/MarmotGroupInfoScreen.kt | 2 +- .../marmotGroup/MarmotGroupListScreen.kt | 2 +- .../send/PrivateMessageEditFieldRow.kt | 1 + .../concord/ConcordChannelListScreen.kt | 2 +- .../concord/ConcordHomeScreen.kt | 2 +- .../concord/ConcordInviteLinksScreen.kt | 2 +- .../concord/ConcordMetadataForm.kt | 2 +- .../header/EphemeralChatChannelHeader.kt | 1 + .../metadata/NewEphemeralChatScreen.kt | 1 + .../header/PublicChatChannelHeader.kt | 1 + .../metadata/ChannelMetadataScreen.kt | 1 + .../header/LiveActivitiesChannelHeader.kt | 1 + .../header/LongLiveActivityChannelHeader.kt | 1 + .../relayGroup/InviteRelayGroupDialog.kt | 2 +- .../relayGroup/RelayGroupChannelListScreen.kt | 1 + .../relayGroup/RelayGroupDiscoveryScreen.kt | 3 +- .../chats/rooms/ChatroomHeaderCompose.kt | 1 + .../rooms/singlepane/MessagesSinglePane.kt | 2 +- .../screen/loggedIn/chess/ChessLobbyScreen.kt | 2 +- .../loggedIn/communities/CommunityScreen.kt | 2 +- .../communities/list/CommunitiesScreen.kt | 2 +- .../loggedIn/discover/DiscoverScreen.kt | 2 +- .../emojipacks/display/EmojiPackScreen.kt | 2 +- .../emojipacks/list/ListOfEmojiPacksScreen.kt | 2 +- .../loggedIn/geocaches/GeocachesScreen.kt | 2 +- .../screen/loggedIn/geohash/GeoHashScreen.kt | 2 +- .../loggedIn/gitRepo/GitRepositoryHomeUi.kt | 1 + .../loggedIn/gitRepo/code/GitFileViewer.kt | 2 +- .../screen/loggedIn/hashtag/HashtagScreen.kt | 2 +- .../ui/screen/loggedIn/home/HomeScreen.kt | 2 +- .../home/live/RenderEphemeralBubble.kt | 1 + .../home/live/RenderLiveActivityBubble.kt | 1 + .../list/ListOfInterestSetsScreen.kt | 2 +- .../loggedIn/keyBackup/AccountBackupScreen.kt | 4 +- .../ui/screen/loggedIn/longs/LongsScreen.kt | 2 +- .../loggedIn/music/MusicPlaylistsScreen.kt | 2 +- .../loggedIn/music/MusicTracksScreen.kt | 2 +- .../screen/loggedIn/nests/NestsFeedLoaded.kt | 1 + .../ui/screen/loggedIn/nests/NestsScreen.kt | 2 +- .../loggedIn/nests/room/lobby/NestJoinCard.kt | 1 + .../nests/room/lobby/NestLobbyScreen.kt | 1 + .../notifications/donations/ZapTheDevsCard.kt | 1 + .../loggedIn/pictures/PicturesScreen.kt | 2 +- .../loggedIn/podcasts/PodcastAuthors.kt | 1 + .../podcasts/PodcastEpisodeListItem.kt | 1 + .../loggedIn/podcasts/PodcastTopSupporters.kt | 1 + .../loggedIn/podcasts/PodcastsScreen.kt | 2 +- .../ui/screen/loggedIn/polls/PollsScreen.kt | 2 +- .../polls/results/PollResultsScreen.kt | 1 + .../loggedIn/products/ProductsScreen.kt | 2 +- .../profile/gallery/GalleryCardCompose.kt | 1 + .../profile/header/Bolt12OffersDialog.kt | 2 +- .../loggedIn/profile/header/DrawBanner.kt | 2 +- .../profile/header/PaymentTargetsDialog.kt | 2 +- .../profile/header/ProfilePaymentRailChips.kt | 2 +- .../profile/header/UserProfileDropDownMenu.kt | 2 +- .../profile/header/badges/DisplayBadges.kt | 1 + .../profile/payment/SendPaymentContent.kt | 2 +- .../loggedIn/profile/relays/RelayFeedView.kt | 2 +- .../loggedIn/profile/zaps/ZapNoteCompose.kt | 1 + .../loggedIn/publicChats/PublicChatsScreen.kt | 2 +- .../loggedIn/redirect/LoadRedirectScreen.kt | 1 + .../screen/loggedIn/relay/RelayFeedScreen.kt | 2 +- .../common/BasicRelaySetupInfoClickableRow.kt | 2 +- .../relays/common/RelayNameAndRemoveButton.kt | 2 +- .../scheduledposts/ScheduledPostsScreen.kt | 2 +- .../ui/screen/loggedIn/search/SearchScreen.kt | 1 + .../loggedIn/settings/ResourceUsageScreen.kt | 2 +- .../loggedIn/settings/SecurityListsCommon.kt | 1 + .../settings/nip46/Nip46SignerScreen.kt | 2 +- .../ui/screen/loggedIn/shorts/ShortsScreen.kt | 2 +- .../loggedIn/threadview/ThreadFeedView.kt | 1 + .../ui/screen/loggedIn/url/UrlScreen.kt | 2 +- .../screen/loggedIn/video/UserCardHeader.kt | 1 + .../ui/screen/loggedIn/video/VideoScreen.kt | 2 +- .../wallet/AddClinkDebitWalletScreen.kt | 2 +- .../loggedIn/wallet/AddNwcWalletScreen.kt | 2 +- .../loggedIn/wallet/CashuWalletScreen.kt | 4 +- .../screen/loggedIn/wallet/OnchainSection.kt | 2 +- .../loggedIn/wallet/ReloadMintScreen.kt | 2 +- .../screen/loggedIn/wallet/TopUpMintScreen.kt | 2 +- .../webBookmarks/WebBookmarksScreen.kt | 2 +- .../loggedIn/workouts/WorkoutsScreen.kt | 2 +- .../notifications/NotificationDeepLinkTest.kt | 1 + .../amethyst/ui/GiftWrapRedirectRouteTest.kt | 1 + .../amethyst/ui/RouteForPointerTest.kt | 1 + .../amethyst/ui/layouts/ScreenLayoutTest.kt | 1 + .../commons/model/navigation/RouteBuilders.kt | 82 +++++++++++++++++++ .../components/util/ClipboardExt.android.kt | 6 +- .../commons/ui/components/Crossfade.kt | 15 +++- .../ui/components/util/ClipboardExt.kt | 29 +++++++ .../commons/ui/layouts/ScreenLayout.kt | 62 ++++++++++++++ .../bottombars/FabBottomBarPadding.kt | 10 +-- .../ui/components/util/ClipboardExt.ios.kt | 31 +++++++ .../ui/components/util/ClipboardExt.jvm.kt | 11 +-- .../desktop/ui/ArticleReaderScreen.kt | 2 +- .../amethyst/desktop/ui/auth/LoginCard.kt | 2 +- 184 files changed, 422 insertions(+), 205 deletions(-) create mode 100644 commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/navigation/RouteBuilders.kt rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/ClipboardExt.kt => commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.android.kt (89%) create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.kt create mode 100644 commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ScreenLayout.kt rename {amethyst/src/main/java/com/vitorpamplona/amethyst => commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons}/ui/navigation/bottombars/FabBottomBarPadding.kt (87%) create mode 100644 commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt rename desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ClipboardExt.kt => commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.jvm.kt (84%) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index c45c7c85fc..194a0f8180 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -30,6 +30,7 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.actions.ConcordActions import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.debugState import com.vitorpamplona.amethyst.model.Account diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/InformationDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/InformationDialog.kt index bb713ee364..ed22a29806 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/InformationDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/InformationDialog.kt @@ -45,12 +45,12 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.copy_stack_to_clipboard import com.vitorpamplona.amethyst.commons.resources.error_dialog_button_ok +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size16dp import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.ui.components.toasts.ThrowableToastMsg import com.vitorpamplona.amethyst.ui.components.toasts.ThrowableToastMsg2 -import com.vitorpamplona.amethyst.ui.components.util.setText import kotlinx.coroutines.launch import java.io.PrintWriter import java.io.StringWriter diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt index cb23b22924..cb59cc7a72 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt @@ -128,6 +128,7 @@ import com.vitorpamplona.amethyst.commons.resources.manage_stored_files_empty import com.vitorpamplona.amethyst.commons.resources.my_blossom_data import com.vitorpamplona.amethyst.commons.resources.quick_action_share 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.pluralStringRes @@ -135,7 +136,6 @@ 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.service.playback.composable.VideoViewInner -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip56Reports.ReportType diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableBuzzInviteLink.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableBuzzInviteLink.kt index 52e989e146..7779422d4b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableBuzzInviteLink.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableBuzzInviteLink.kt @@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.quartz.buzz.invite.BuzzInviteLink import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableConcordInviteLink.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableConcordInviteLink.kt index 0155024eee..3212e52163 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableConcordInviteLink.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableConcordInviteLink.kt @@ -31,8 +31,8 @@ import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.actions.ConcordActions import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.components.util.setText import kotlinx.coroutines.launch /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayGroupLink.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayGroupLink.kt index 74ef271b6b..d968ab300b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayGroupLink.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayGroupLink.kt @@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.quartz.nip29RelayGroups.GroupInviteLink import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayUrl.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayUrl.kt index 5b42ce9ec4..303fd67251 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayUrl.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRelayUrl.kt @@ -30,8 +30,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.components.util.setText import kotlinx.coroutines.launch @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt index fde3038222..588e74c2ed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableRoute.kt @@ -44,6 +44,7 @@ import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.concord_invite_naddr_label import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/PaymentCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/PaymentCard.kt index 322aefb13e..017b90ec6b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/PaymentCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/PaymentCard.kt @@ -50,10 +50,10 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.copied_to_clipboard import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.commons.ui.theme.Size18Modifier -import com.vitorpamplona.amethyst.ui.components.util.setText import kotlinx.coroutines.launch /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 3fd83f2fd5..1c6370fe22 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -70,6 +70,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.richtext.Base64Segment import com.vitorpamplona.amethyst.commons.richtext.BechSegment import com.vitorpamplona.amethyst.commons.richtext.BlossomUriSegment diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt index 3234e12277..d3e60a8a4d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt @@ -51,13 +51,13 @@ import com.vitorpamplona.amethyst.commons.resources.url_preview_open_in_browser 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.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.MaxWidthWithHorzPadding import com.vitorpamplona.amethyst.commons.ui.theme.Size14Modifier import com.vitorpamplona.amethyst.commons.ui.theme.innerPostModifier import com.vitorpamplona.amethyst.commons.ui.theme.previewCardImageModifier -import com.vitorpamplona.amethyst.ui.components.util.setText import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index d7af8ef884..4479ce8a73 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -110,6 +110,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation 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.loadStringRes import com.vitorpamplona.amethyst.commons.ui.note.DownloadForOfflineIcon import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -129,7 +130,6 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.InformationDialog import com.vitorpamplona.amethyst.ui.components.pdf.PdfPreviewCard import com.vitorpamplona.amethyst.ui.components.pdf.PdfViewerDialog -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.BlankNote import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/LongPressCopyText.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/LongPressCopyText.kt index d42515b246..bb58c01144 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/LongPressCopyText.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/LongPressCopyText.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.copied_to_clipboard import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt index 6fb63c1e08..83f0fb31cb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.layouts import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.commons.ui.layouts.DisappearingScaffold as SharedDisappearingScaffold diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayout.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayout.kt index 51ceb43c1e..bd5e34e558 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayout.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayout.kt @@ -29,52 +29,14 @@ import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSiz import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp - -/** How the app shell presents its top-level navigation for the current window size. */ -enum class NavigationStyle { - /** Compact windows (phones): bottom navigation bar + modal drawer. */ - BOTTOM_BAR, - - /** - * Every non-Compact window that does not dock — portrait tablets and unfolded foldables at - * any width, plus short landscape windows: a left navigation rail replaces the bottom bar - * and the drawer stays modal behind the rail's avatar button. - */ - NAV_RAIL, - - /** Wide, landscape, tall windows (landscape tablets, desktop): the drawer docks permanently on the left. */ - PERMANENT_DRAWER, -} - -/** - * The shell layout decisions for the current window, published once per window size change - * through [LocalScreenLayout] so every screen, bar and panel agrees on the same tier. - */ -@Immutable -data class ScreenLayoutSpec( - val navigationStyle: NavigationStyle, - val hasRoomForNotificationPanel: Boolean, -) { - /** - * True on the rail and permanent-drawer tiers. Large screens hide the bottom bar and pin - * the top/bottom chrome (no disappearing bars on scroll). - */ - val isLargeScreen: Boolean get() = navigationStyle != NavigationStyle.BOTTOM_BAR - - companion object { - val Phone = ScreenLayoutSpec(NavigationStyle.BOTTOM_BAR, hasRoomForNotificationPanel = false) - } -} - -val LocalScreenLayout = compositionLocalOf { ScreenLayoutSpec.Phone } +import com.vitorpamplona.amethyst.commons.ui.layouts.NavigationStyle +import com.vitorpamplona.amethyst.commons.ui.layouts.ScreenLayoutSpec /** * Minimum window width for the docked notification panel: a leading navigation pane, a diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 44525525f6..b02f2cc62c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -58,6 +58,9 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.LocalUserFinderAccoun import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.invalid_nip19_uri import com.vitorpamplona.amethyst.commons.resources.invalid_nip19_uri_description +import com.vitorpamplona.amethyst.commons.ui.components.LocalAnimationsEnabled +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout +import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.service.crashreports.DisplayCrashMessages import com.vitorpamplona.amethyst.service.relayClient.authCommand.compose.RelayAuthPromptHost import com.vitorpamplona.amethyst.service.relayClient.notifyCommand.compose.DisplayNotifyMessages @@ -74,7 +77,6 @@ import com.vitorpamplona.amethyst.ui.broadcast.DisplayBroadcastProgress import com.vitorpamplona.amethyst.ui.call.CallActivity import com.vitorpamplona.amethyst.ui.components.getActivity import com.vitorpamplona.amethyst.ui.components.toasts.DisplayErrorMessages -import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.ui.layouts.rememberScreenLayoutSpec import com.vitorpamplona.amethyst.ui.navigation.bottombars.LocalTabReselectCoordinator import com.vitorpamplona.amethyst.ui.navigation.bottombars.TabReselectCoordinator @@ -359,8 +361,13 @@ fun AppNavigation( // can't read LocalScreenLayout (see NavTransitionTier). SideEffect { NavTransitionTier.isLargeScreen = screenLayout.isLargeScreen } + val featureSet by accountViewModel.settings.uiSettingsFlow.featureSet + .collectAsStateWithLifecycle() + CompositionLocalProvider( LocalScreenLayout provides screenLayout, + // Shared composables read this instead of the AccountViewModel's performance-mode flag. + LocalAnimationsEnabled provides (featureSet != FeatureSetType.PERFORMANCE), LocalTabReselectCoordinator provides tabReselectCoordinator, // Provide the shared finder CompositionLocals so any commons composable that // uses the no-arg observeUser*/EventFinderFilterAssemblerSubscription(note) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/AppBottomBar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/AppBottomBar.kt index 71ea81b4c5..42c7f91d64 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/AppBottomBar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/AppBottomBar.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.favorites.FavoriteAppIcon import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.model.navigation.BottomBarEntry import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness @@ -61,7 +62,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.onSurface65 import com.vitorpamplona.amethyst.favorites.BrowserIconRegistry import com.vitorpamplona.amethyst.favorites.FavoriteAppsRegistry import com.vitorpamplona.amethyst.favorites.rememberNappletIconModel -import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel /** Content height of the [AppBottomBar] (the 50.dp Column inside [RenderBottomMenu]), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index df3a7a5014..0ce7435def 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -97,6 +97,7 @@ import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.NavBarItem import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.bookmarks import com.vitorpamplona.amethyst.commons.resources.drafts diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt index f729460f77..13f0e95cf2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt @@ -24,17 +24,16 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.concord.ConcordChannel -import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.marmotGroups.MarmotGroupChatroom import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.minichatRouteFor +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel -import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.buzz.notifications.MemberAddedNotificationEvent import com.vitorpamplona.quartz.experimental.ephemChat.chat.EphemeralChatEvent -import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId import com.vitorpamplona.quartz.experimental.nip82SoftwareApps.application.SoftwareApplicationEvent import com.vitorpamplona.quartz.experimental.zapPolls.ZapPollEvent import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent @@ -79,34 +78,6 @@ import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent import com.vitorpamplona.quartz.nipCCGeocaching.curation.GeocacheCurationListEvent import com.vitorpamplona.quartz.nipCCGeocaching.listing.GeocacheListingEvent -/** - * A minichat reply — a kind-1111 [CommentEvent] posted into a chat message's thread — should open - * that message's minichat ([Route.ChatMinichat]), not the whole channel it lives in. Regular chat - * messages are kind 9 / 42, so a [CommentEvent] in a *chat context* is always a thread reply. We - * gate on the chat context (the reply is attached to a Concord / relay-group / public-chat gatherer, - * or its root message is) precisely so a generic NIP-22 comment on an article or note keeps its own - * thread route and isn't mistaken for a minichat. Returns null when it isn't a chat-context comment. - */ -fun minichatRouteFor(note: Note): Route? { - val comment = note.event as? CommentEvent ?: return null - val rootId = comment.rootEventIds().firstOrNull() ?: return null - - // Prefer the reply's own Concord channel (the reply arrived over that plane, so its gatherer - // always carries the community/channel), else the root note's if it happens to be loaded. Passing - // these lets the minichat screen resolve the plane + relays even when the parent isn't cached. - val concord = - note.inGatherers?.firstNotNullOfOrNull { it as? ConcordChannel } - ?: LocalCache.getNoteIfExists(rootId)?.inGatherers?.firstNotNullOfOrNull { it as? ConcordChannel } - if (concord != null) { - return Route.ChatMinichat(rootId, concord.channelId.communityId, concord.channelId.channelId) - } - - val inChatContext = note.isInChatGatherer() || LocalCache.getNoteIfExists(rootId)?.isInChatGatherer() == true - return if (inChatContext) Route.ChatMinichat(rootId) else null -} - -private fun Note.isInChatGatherer(): Boolean = inGatherers?.any { it is ConcordChannel || it is RelayGroupChannel || it is PublicChatChannel } == true - /** * Kinds whose destination is `Route.Note(id)` — the generic thread view — no matter what the * event body turns out to say. Mirrors the `else ->` branch of [routeForInner]: every kind here @@ -419,26 +390,6 @@ fun routeToMessage( accountViewModel: AccountViewModel, ): Route = routeToMessage(user.pubkeyHex, draftMessage, replyId, draftId, expiresDays, accountViewModel) -fun routeFor(note: EphemeralChatChannel): Route = Route.EphemeralChat(note.roomId.id, note.roomId.relayUrl.url) - -fun routeFor(note: PublicChatChannel): Route = Route.PublicChatChannel(note.idHex) - -fun routeFor(note: LiveActivitiesChannel): Route = Route.LiveActivityChannel(note.address.kind, note.address.pubKeyHex, note.address.dTag) - -fun routeFor(roomId: RoomId): Route = Route.EphemeralChat(roomId.id, roomId.relayUrl.url) - -fun routeFor(note: RelayGroupChannel): Route = Route.RelayGroup(note.groupId.id, note.groupId.relayUrl.url) - -fun routeFor(groupId: GroupId): Route = Route.RelayGroup(groupId.id, groupId.relayUrl.url) - -fun routeFor(channel: ConcordChannel): Route = Route.Concord(channel.channelId.communityId, channel.channelId.channelId) - -fun routeFor(user: User): Route.Profile = Route.Profile(user.pubkeyHex) - -fun routeForUser(userHex: HexKey): Route.Profile = Route.Profile(userHex) - -fun authorRouteFor(note: Note): Route.Profile? = note.author?.pubkeyHex?.let { Route.Profile(it) } - fun routeReplyTo( note: Note, account: Account, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt index 4998b3ae15..91144ba5a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/topbars/UserDrawerSearchTopBar.kt @@ -37,6 +37,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.your_profile_image import com.vitorpamplona.amethyst.commons.search.SearchQuery import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -46,7 +47,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.HeaderPictureModifier import com.vitorpamplona.amethyst.commons.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserPicture -import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel /** diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt index a610ec20b8..a0373864e2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.new_badge_award_notif import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Bolt12ZapGallery.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Bolt12ZapGallery.kt index 387c358645..a5d895987b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Bolt12ZapGallery.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Bolt12ZapGallery.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import com.vitorpamplona.amethyst.commons.model.Bolt12ZapEntry import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon import com.vitorpamplona.amethyst.commons.ui.theme.Size25dp 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 031d7de773..a247124776 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 @@ -35,9 +35,9 @@ import com.vitorpamplona.amethyst.commons.resources.copy_text_translated 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.ui.components.cachedTranslation -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.types.displayedNoteText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Gallery.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Gallery.kt index c9e10fa7e9..b60440f8c1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Gallery.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/Gallery.kt @@ -36,10 +36,11 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor +import com.vitorpamplona.amethyst.commons.model.navigation.routeForUser import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.Size25dp import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor -import com.vitorpamplona.amethyst.ui.navigation.routes.routeForUser import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.HexKey import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt index b8aea7f94d..f032bbb99f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdStartPadding import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index 6a3c005742..f2b915219f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -72,6 +72,8 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.NoteState import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.authorRouteFor +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nutzap import com.vitorpamplona.amethyst.commons.resources.profile_image @@ -108,7 +110,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.ui.components.CoreSecretMessage import com.vitorpamplona.amethyst.ui.components.ExpandableRichTextViewer import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer -import com.vitorpamplona.amethyst.ui.navigation.routes.authorRouteFor import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.elements.NoteDropDownMenu import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 453da51243..367b4d94ab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -49,6 +49,8 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor +import com.vitorpamplona.amethyst.commons.model.navigation.routeForUser import com.vitorpamplona.amethyst.commons.model.nip05DnsIdentifiers.Nip05State import com.vitorpamplona.amethyst.commons.model.nip05DnsIdentifiers.Nip05VerifState import com.vitorpamplona.amethyst.commons.resources.Res @@ -73,7 +75,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor -import com.vitorpamplona.amethyst.ui.navigation.routes.routeForUser import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser 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 e83291659c..771f97e549 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 @@ -66,6 +66,7 @@ import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.concord.ConcordChannel import com.vitorpamplona.amethyst.commons.model.isCommunityDefinition import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.model.replyingDirectlyTo diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index f4e68b4aad..5cb7a5d1cd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -100,6 +100,7 @@ import com.vitorpamplona.amethyst.commons.resources.quick_action_unfollow import com.vitorpamplona.amethyst.commons.resources.quick_action_unmute_thread import com.vitorpamplona.amethyst.commons.resources.report_dialog_block_hide_user_btn import com.vitorpamplona.amethyst.commons.resources.report_dialog_blocking_a_user +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -109,7 +110,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SmallestBorder import com.vitorpamplona.amethyst.commons.ui.theme.isLight import com.vitorpamplona.amethyst.commons.ui.theme.secondaryButtonBackground import com.vitorpamplona.amethyst.commons.util.njumpLink -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeEditDraftTo import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapGallery.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapGallery.kt index bbb5da72db..d0198e2beb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapGallery.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapGallery.kt @@ -38,6 +38,7 @@ import com.vitorpamplona.amethyst.commons.hashtags.Cashu import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.NutzapEntry +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nutzap import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapUserSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapUserSetCompose.kt index 9e38243234..1417cc6c83 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapUserSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NutzapUserSetCompose.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.hashtags.Cashu import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nutzap import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/OnchainZapGallery.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/OnchainZapGallery.kt index 24a8c65490..2c0760b419 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/OnchainZapGallery.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/OnchainZapGallery.kt @@ -41,6 +41,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.OnchainZapEntry import com.vitorpamplona.amethyst.commons.model.OnchainZapStatus import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.OnchainZappedIcon import com.vitorpamplona.amethyst.commons.ui.note.PendingClockBadge 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 c390301cd5..9e865aed4f 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 @@ -153,6 +153,7 @@ import com.vitorpamplona.amethyst.commons.resources.sats_to_complete import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ChangeReactionIcon import com.vitorpamplona.amethyst.commons.ui.note.CommentIcon @@ -228,7 +229,6 @@ import com.vitorpamplona.amethyst.ui.actions.uploads.FloatingRecordingIndicator import com.vitorpamplona.amethyst.ui.actions.uploads.MAX_VOICE_RECORD_SECONDS import com.vitorpamplona.amethyst.ui.actions.uploads.RecordAudioBox import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo import com.vitorpamplona.amethyst.ui.note.elements.ShareOptionsBottomSheet import com.vitorpamplona.amethyst.ui.note.types.EditState diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt index c2c54ffb9d..3ac0cae686 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt @@ -56,6 +56,7 @@ import com.vitorpamplona.amethyst.commons.resources.expand_relay_list import com.vitorpamplona.amethyst.commons.resources.relay_info import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.LargeRelayIconModifier @@ -71,7 +72,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.relayIconModifier import com.vitorpamplona.amethyst.commons.ui.theme.ripple24dp import com.vitorpamplona.amethyst.commons.ui.theme.warningColorOnSecondSurface import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt index 80b2315cf3..a0837b22fe 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReplyInformation.kt @@ -35,6 +35,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.and import com.vitorpamplona.amethyst.commons.resources.replying_to diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt index 9166e84e62..b85424afa0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateReactionTypeDialog.kt @@ -72,6 +72,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.commons.emojicoder.EmojiCoder import com.vitorpamplona.amethyst.commons.model.AddressableNote +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.add import com.vitorpamplona.amethyst.commons.resources.new_reaction_symbol diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt index 395446bb3e..46771e5f29 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserCompose.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.profile.ui.FollowButton import com.vitorpamplona.amethyst.commons.profile.ui.ListButton import com.vitorpamplona.amethyst.commons.profile.ui.UnfollowButton diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index 165d78d292..f2aeb65dba 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.profile_image import com.vitorpamplona.amethyst.commons.resources.profile_image_of_user diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapUserSetCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapUserSetCompose.kt index f2a425e6d4..f1b75ac218 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapUserSetCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapUserSetCompose.kt @@ -33,6 +33,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon import com.vitorpamplona.amethyst.commons.ui.theme.DoubleVertSpacer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/ClinkOfferPreview.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/ClinkOfferPreview.kt index 51271456d5..fa3759d83b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/ClinkOfferPreview.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/ClinkOfferPreview.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons import com.vitorpamplona.amethyst.commons.hashtags.Lightning +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.clink_lightning_offer import com.vitorpamplona.amethyst.commons.resources.clink_offer_amount_range diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt index 57fe18b0ae..1c9e541a98 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ForkInfo.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.forked_from import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteActionSections.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteActionSections.kt index 73acefa153..cbb23ef5a4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteActionSections.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteActionSections.kt @@ -70,10 +70,10 @@ import com.vitorpamplona.amethyst.commons.resources.timestamp_it import com.vitorpamplona.amethyst.commons.resources.timestamp_pending import com.vitorpamplona.amethyst.commons.resources.unfollow import com.vitorpamplona.amethyst.commons.resources.unpin_from_profile +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.LightRedColor -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.QuickActionAlertDialogOneButton import com.vitorpamplona.amethyst.ui.note.copyNoteTextAction import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel 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 82375dddb5..ce0167b863 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 @@ -80,6 +80,7 @@ import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.app_definition_available_on @@ -101,6 +102,7 @@ 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.ClickableTextPrimary +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.LinkIcon import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji @@ -110,7 +112,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.BaseUserPicture import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt index 658a6d9917..58625979f3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/AudioTrack.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.service.playback.composable.LoadThumbAndThenVideoView diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt index 2ea85eed91..5537e616a4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Badge.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.accept_badge import com.vitorpamplona.amethyst.commons.resources.award_badge diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt index d48aebf040..28615c3db0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessage.kt @@ -32,6 +32,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt index b08dbbff3d..e0ee74d808 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ChatMessageEncryptedFile.kt @@ -33,6 +33,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.HalfVertPadding diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Chess.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Chess.kt index f8b0315510..d56e7edd8e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Chess.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Chess.kt @@ -46,6 +46,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.nip64Chess.ChessChallenge import com.vitorpamplona.amethyst.commons.nip64Chess.ui.ChessGameViewer import com.vitorpamplona.amethyst.commons.resources.Res 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 8a95513673..24fc44c863 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 @@ -62,6 +62,7 @@ import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.about_us diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/EntityRating.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/EntityRating.kt index 3b37921f87..3bba1f9328 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/EntityRating.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/EntityRating.kt @@ -56,6 +56,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.preview_card_image_for diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FollowList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FollowList.kt index 14f5fbe5a8..2f394b2fe8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FollowList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/FollowList.kt @@ -43,6 +43,7 @@ import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.follow_list_item_label diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Fundraiser.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Fundraiser.kt index c720be58c9..564ee7077d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Fundraiser.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Fundraiser.kt @@ -48,6 +48,7 @@ import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard import com.vitorpamplona.amethyst.commons.resources.fundraiser_ends import com.vitorpamplona.amethyst.commons.resources.fundraiser_onchain_donation import com.vitorpamplona.amethyst.commons.resources.preview_card_image_for +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.CopyIcon import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -55,7 +56,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size18Modifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.ui.theme.replyModifier import com.vitorpamplona.amethyst.ui.components.MyAsyncImage -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeader import com.vitorpamplona.amethyst.ui.note.elements.DefaultImageHeaderBackground import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt index cdbff32f6a..39071710d7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Highlight.kt @@ -47,6 +47,7 @@ import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.highlights.HighlightQuote +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav 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 dc7b6653a6..1b6d9bc77b 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 @@ -48,6 +48,7 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.live_stream_has_ended import com.vitorpamplona.amethyst.commons.resources.live_stream_is_offline diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt index a521369e12..13aaca7f68 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.unit.sp import androidx.core.net.toUri import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.meeting_room_in_space import com.vitorpamplona.amethyst.commons.resources.meeting_room_in_space_unknown diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/OnchainZapEvent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/OnchainZapEvent.kt index f4a0a1aa82..75f953ca66 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/OnchainZapEvent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/OnchainZapEvent.kt @@ -71,11 +71,11 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.commons.ui.theme.Size25dp import com.vitorpamplona.amethyst.commons.ui.theme.bitcoinColor -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nipBCOnchainZaps.chain.BitcoinTx diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt index 9bd69eb2ae..8f8a2a185a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PodcastPeople.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.podcast_hosts_and_guests import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt index e1a9b4fb62..a0c92badb1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Poll.kt @@ -74,6 +74,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip88Polls.PollResponsesCache import com.vitorpamplona.amethyst.commons.model.nip88Polls.TallyResults import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt index ab7cca27a0..1a2310f3fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PrivateMessage.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.private_conversation_notification diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt index d8e45f3b1d..344fc539a2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/ProfileCard.kt @@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.ImmutableListOfLists import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.number_followers import com.vitorpamplona.amethyst.commons.resources.profile_card_bot diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicationSection.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicationSection.kt index fc2ce974a7..62a07a7526 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicationSection.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicationSection.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.publication_untitled_section diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt index aa62be4e9a..ab17537244 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayGroupMessage.kt @@ -45,6 +45,7 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.nip29RelayGroups.ui.RelayNameChip import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt index d69f2ca5b9..e90e933cbb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/RelayList.kt @@ -58,11 +58,11 @@ import com.vitorpamplona.amethyst.commons.resources.public_home_section import com.vitorpamplona.amethyst.commons.resources.public_notif_section import com.vitorpamplona.amethyst.commons.resources.search_relays_title import com.vitorpamplona.amethyst.commons.resources.trusted_relays_title +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserRelayIntoList import com.vitorpamplona.amethyst.ui.components.ShowMoreButton -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.AddRelayButton import com.vitorpamplona.amethyst.ui.note.RemoveRelayButton import com.vitorpamplona.amethyst.ui.note.getGradient 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 0a8976a615..b9bdd996a6 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 @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.replyingDirectlyTo import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable 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 abae70ba27..593c22c8b4 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 @@ -45,6 +45,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.model.EmptyTagList import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.accept_the_suggestion import com.vitorpamplona.amethyst.commons.resources.proposal_to_edit diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt index 246b5a2407..b899bf43a3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.torrent_file import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountSwitcherAndLeftDrawerLayout.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountSwitcherAndLeftDrawerLayout.kt index d350e79079..19d5be3a79 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountSwitcherAndLeftDrawerLayout.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountSwitcherAndLeftDrawerLayout.kt @@ -48,9 +48,9 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.navigation.NavDestination.Companion.hasRoute import androidx.navigation.compose.currentBackStackEntryAsState import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout +import com.vitorpamplona.amethyst.commons.ui.layouts.NavigationStyle import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness -import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout -import com.vitorpamplona.amethyst.ui.layouts.NavigationStyle import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppNavigationRail import com.vitorpamplona.amethyst.ui.navigation.drawer.AccountSwitchBottomSheet import com.vitorpamplona.amethyst.ui.navigation.drawer.DrawerContent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt index 9d462ebcf1..98793bc953 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/apps/recommendations/ProfileAppRecommendationsScreen.kt @@ -57,6 +57,7 @@ import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.cache.filterIntoSet +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.app_definition_handles import com.vitorpamplona.amethyst.commons.resources.app_definition_no_supported_kinds diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/articles/ArticlesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/articles/ArticlesScreen.kt index ea857c0282..eeb34795ed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/articles/ArticlesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/articles/ArticlesScreen.kt @@ -30,12 +30,12 @@ import com.vitorpamplona.amethyst.commons.nip23LongContent.ui.NewArticleButton import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.articles.datasource.ArticlesFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt index 5667f0e30e..9c552c4f0f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictEventViews.kt @@ -68,6 +68,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt index c8feeaa482..b8f7dca79e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictListViews.kt @@ -61,6 +61,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt index 8bf321ca6c..1a89df595d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/backups/BackupConflictReviewScreen.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.model.backups.BackupEventType import com.vitorpamplona.amethyst.commons.model.backups.ReplaceableBackupConflict import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/BadgesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/BadgesScreen.kt index 90b5921d99..1f84678d6b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/BadgesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/BadgesScreen.kt @@ -29,12 +29,12 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.badges.datasource.BadgesFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt index 0d3cbdf7fb..df7ba7bea0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt @@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.badge_untitled import com.vitorpamplona.amethyst.commons.resources.profile_badges_description diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupItemOptions.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupItemOptions.kt index df4dc63b58..b2a31af51a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupItemOptions.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupItemOptions.kt @@ -60,12 +60,12 @@ import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable 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.navigation.navs.INav 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.ui.actions.EditPostView -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeEditDraftTo import com.vitorpamplona.amethyst.ui.note.copyNoteTextAction import com.vitorpamplona.amethyst.ui.note.elements.DropDownParams diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt index 414981d4b9..18556e4e82 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt @@ -45,11 +45,11 @@ import com.vitorpamplona.amethyst.commons.nip51Lists.ui.ListOfBookmarkGroupsFeed import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.bookmark_lists import com.vitorpamplona.amethyst.commons.resources.follow_set_create_btn_label +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt index 2e1f34e970..ad39788817 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt @@ -43,10 +43,10 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.article_bookmark_management_title import com.vitorpamplona.amethyst.commons.resources.bookmarks_title import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt index b30bb0a5f5..abe4d003d5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt @@ -43,11 +43,11 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.bookmarks_title import com.vitorpamplona.amethyst.commons.resources.post_bookmark_management_title import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.components.LoadNote -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/old/OldBookmarkListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/old/OldBookmarkListScreen.kt index b9c2b378d5..7c8f92bd13 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/old/OldBookmarkListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/old/OldBookmarkListScreen.kt @@ -60,12 +60,12 @@ import com.vitorpamplona.amethyst.commons.resources.private_bookmarks import com.vitorpamplona.amethyst.commons.resources.public_bookmarks import com.vitorpamplona.amethyst.commons.ui.components.DeletedItemsBanner import com.vitorpamplona.amethyst.commons.ui.loadStringRes +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.old.dal.OldBookmarkPrivateFeedViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentAttestationScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentAttestationScreen.kt index d19c2c0c36..eaad72c995 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentAttestationScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentAttestationScreen.kt @@ -90,11 +90,11 @@ import com.vitorpamplona.amethyst.commons.resources.buzz_attest_remove import com.vitorpamplona.amethyst.commons.resources.buzz_attest_signed_title import com.vitorpamplona.amethyst.commons.resources.buzz_attest_topbar import com.vitorpamplona.amethyst.commons.resources.buzz_attest_warning +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.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.buzz.oaOwnerAttestation.AttestationConditions diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt index 6af611f2da..5a78eea7a3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt @@ -56,8 +56,8 @@ import com.vitorpamplona.amethyst.commons.resources.buzz_invite_error_title import com.vitorpamplona.amethyst.commons.resources.buzz_invite_link_title import com.vitorpamplona.amethyst.commons.resources.buzz_invite_share import com.vitorpamplona.amethyst.commons.resources.more_options +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import kotlinx.coroutines.CancellationException diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarCollectionsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarCollectionsScreen.kt index 4f746c2920..f84dee3e2a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarCollectionsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarCollectionsScreen.kt @@ -28,10 +28,10 @@ import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.nip52Calendar.ui.NewCalendarButton import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.datasource.CalendarsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarsScreen.kt index c982112b4d..e498d73b81 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/calendars/CalendarsScreen.kt @@ -33,10 +33,10 @@ import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.nip52Calendar.ui.NewCalendarButton import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.calendars.datasource.CalendarsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatEngagementDetailSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatEngagementDetailSheet.kt index bc688409c5..0ac2efbfa8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatEngagementDetailSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatEngagementDetailSheet.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.Font12SP diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt index 86c534f2f1..ccb19c4c2d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageCompose.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.latestBuzzEdit import com.vitorpamplona.amethyst.commons.model.latestConcordEdit import com.vitorpamplona.amethyst.commons.model.latestMarmotEdit +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.ReactionRowZapraiser import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatZap.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatZap.kt index 0888d12c73..ee5645fa71 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatZap.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderChatZap.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ui.StreamSystemCard import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.chat_zap_amount_suffix diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatsScreen.kt index 659f1703c3..c453d4cfb4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatsScreen.kt @@ -65,11 +65,11 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.location_channels +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt index 6e8108e212..ba58c3bfa8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt @@ -127,6 +127,7 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_unknown_error import com.vitorpamplona.amethyst.commons.resources.marmot_user_fallback_name import com.vitorpamplona.amethyst.commons.resources.members import com.vitorpamplona.amethyst.commons.resources.remove +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -138,7 +139,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.allGoodColor import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.ui.theme.ripple24dp import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.creators.userSuggestions.ShowUserSuggestionList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt index b4231262cd..df8c893e5d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt @@ -81,12 +81,12 @@ import com.vitorpamplona.amethyst.commons.resources.marmot_tab_known_count import com.vitorpamplona.amethyst.commons.resources.marmot_tab_new_requests import com.vitorpamplona.amethyst.commons.resources.marmot_tab_new_requests_count import com.vitorpamplona.amethyst.commons.resources.marmot_unread_messages +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size55dp import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.note.elements.TimeAgoStyle import com.vitorpamplona.amethyst.ui.note.elements.ToggleableTimeAgoText diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/PrivateMessageEditFieldRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/PrivateMessageEditFieldRow.kt index c495fec745..49d996db90 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/PrivateMessageEditFieldRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/PrivateMessageEditFieldRow.kt @@ -53,6 +53,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.commons.chats.ui.ThinSendButton import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.nip30CustomEmojis.ui.ShowEmojiSuggestionList import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.cancel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelListScreen.kt index f66a27d0ac..8a3250abb0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordChannelListScreen.kt @@ -100,11 +100,11 @@ import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard import com.vitorpamplona.amethyst.commons.resources.leave import com.vitorpamplona.amethyst.commons.resources.more_options import com.vitorpamplona.amethyst.commons.resources.quick_action_share +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.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar import com.vitorpamplona.amethyst.ui.note.timeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt index a4300dae56..82407fe7ab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt @@ -68,6 +68,7 @@ import com.vitorpamplona.amethyst.commons.resources.concord_home_title import com.vitorpamplona.amethyst.commons.resources.concord_member_count import com.vitorpamplona.amethyst.commons.resources.concord_show_all_channels import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.pluralStringRes @@ -75,7 +76,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserName import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.timeAgo import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.concord.datasource.ConcordChannelSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordInviteLinksScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordInviteLinksScreen.kt index 94d0aad052..27f4f2205d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordInviteLinksScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordInviteLinksScreen.kt @@ -72,9 +72,9 @@ import com.vitorpamplona.amethyst.commons.resources.concord_invite_revoked_faile import com.vitorpamplona.amethyst.commons.resources.concord_invite_revoked_ok import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard import com.vitorpamplona.amethyst.commons.resources.more_options +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.concord.cord05Invites.ConcordInviteListEntry import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt index 6dafebd7ce..ffdc668609 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordMetadataForm.kt @@ -75,12 +75,12 @@ import com.vitorpamplona.amethyst.commons.resources.concord_edit_banner_hint import com.vitorpamplona.amethyst.commons.resources.failed_to_upload_media_no_details import com.vitorpamplona.amethyst.commons.resources.remove import com.vitorpamplona.amethyst.commons.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.MediumRelayIconModifier import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/EphemeralChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/EphemeralChatChannelHeader.kt index e0abe090b2..f3b1fead68 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/EphemeralChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/header/EphemeralChatChannelHeader.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt index 4dbabca232..52c4b36170 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.text.style.TextDirection import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.channel_name import com.vitorpamplona.amethyst.commons.resources.group_relay diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/PublicChatChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/PublicChatChannelHeader.kt index 7a0d4fcb5a..49537a10c5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/PublicChatChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/header/PublicChatChannelHeader.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt index d685c2e963..ef403698eb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.Amethyst +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.about_us diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LiveActivitiesChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LiveActivitiesChannelHeader.kt index 7ca0f18730..2745ea645a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LiveActivitiesChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LiveActivitiesChannelHeader.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LongLiveActivityChannelHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LongLiveActivityChannelHeader.kt index f1a365032b..8092e4704f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LongLiveActivityChannelHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip53LiveActivities/header/LongLiveActivityChannelHeader.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.commons.resources.Res diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/InviteRelayGroupDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/InviteRelayGroupDialog.kt index 37103f34fd..eac28755b3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/InviteRelayGroupDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/InviteRelayGroupDialog.kt @@ -43,8 +43,8 @@ import com.vitorpamplona.amethyst.commons.resources.relay_group_invite_code_labe import com.vitorpamplona.amethyst.commons.resources.relay_group_invite_description import com.vitorpamplona.amethyst.commons.resources.relay_group_invite_preparing import com.vitorpamplona.amethyst.commons.resources.relay_group_invite_title +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.utils.RandomInstance diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt index 8093f081eb..72c810d975 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupChannelListScreen.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.model.buzz.BuzzCommunityMembership import com.vitorpamplona.amethyst.commons.model.buzz.BuzzRelayDialect import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupDeletions import com.vitorpamplona.amethyst.commons.resources.Res diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt index e55e17f57c..359966439c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/relayGroup/RelayGroupDiscoveryScreen.kt @@ -58,6 +58,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.relay_group_badge_invite_only @@ -74,6 +75,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -88,7 +90,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.navigation.topbars.FeedFilterSpinner import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt index 43bc9c72c8..299a69bf9d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt @@ -58,6 +58,7 @@ import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.geohashChat.GeohashChatChannel import com.vitorpamplona.amethyst.commons.model.marmotGroups.MarmotGroupChatroom import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel import com.vitorpamplona.amethyst.commons.model.privateChatLastReadRoute diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/singlepane/MessagesSinglePane.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/singlepane/MessagesSinglePane.kt index 184255dd0b..ff1e19cd00 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/singlepane/MessagesSinglePane.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/singlepane/MessagesSinglePane.kt @@ -36,10 +36,10 @@ import com.vitorpamplona.amethyst.commons.resources.known import com.vitorpamplona.amethyst.commons.resources.new_requests import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.navigation.topbars.AmethystClickableIcon import com.vitorpamplona.amethyst.ui.navigation.topbars.UserDrawerSearchTopBar import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/ChessLobbyScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/ChessLobbyScreen.kt index 61e97b9c18..639ad50264 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/ChessLobbyScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chess/ChessLobbyScreen.kt @@ -78,9 +78,9 @@ import com.vitorpamplona.amethyst.commons.resources.dismiss import com.vitorpamplona.amethyst.commons.resources.relay_settings import com.vitorpamplona.amethyst.commons.resources.route_chess import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource.ChessSubscription import com.vitorpamplona.quartz.nip64Chess.Color as ChessColor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/CommunityScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/CommunityScreen.kt index d184fd2127..57fe8ac2b1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/CommunityScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/CommunityScreen.kt @@ -50,6 +50,7 @@ import com.vitorpamplona.amethyst.commons.resources.feed import com.vitorpamplona.amethyst.commons.resources.mod_queue import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverPagerState +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TitleIconModifier @@ -59,7 +60,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.commons.ui.theme.isLight import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.nip22Comments.LocalCurrentExternalScope import com.vitorpamplona.amethyst.ui.note.types.LongCommunityHeader diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt index eb47d03f16..323f3d091e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt @@ -43,6 +43,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding @@ -50,7 +51,6 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.list.datasource.CommunitiesListFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt index 6ded9230bd..9f5d01fb0c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverPagerState import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness @@ -82,7 +83,6 @@ import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableGridFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.datasource.DiscoveryFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.TabItem diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/display/EmojiPackScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/display/EmojiPackScreen.kt index ff680cba84..02a30a5ea5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/display/EmojiPackScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/display/EmojiPackScreen.kt @@ -68,12 +68,12 @@ import com.vitorpamplona.amethyst.commons.resources.quick_action_delete 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.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size35Modifier -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip30CustomEmoji.EmojiUrlTag diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/ListOfEmojiPacksScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/ListOfEmojiPacksScreen.kt index 45136e9d87..0f4d8dc8e8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/ListOfEmojiPacksScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/list/ListOfEmojiPacksScreen.kt @@ -74,6 +74,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox 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.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.note.VerticalDotsIcon @@ -83,7 +84,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size40Modifier import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Address diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocachesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocachesScreen.kt index f063c2fdcf..6a271c49e2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocachesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocachesScreen.kt @@ -51,12 +51,12 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverPagerState +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.geocaches.datasource.GeocachesFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.screen.loggedIn.geocaches.map.GeocacheMapTab diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geohash/GeoHashScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geohash/GeoHashScreen.kt index 89503c6da8..fcbd83e541 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geohash/GeoHashScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geohash/GeoHashScreen.kt @@ -39,12 +39,12 @@ import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_ import com.vitorpamplona.amethyst.commons.resources.read_only_user import com.vitorpamplona.amethyst.commons.search.SearchSeed import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingGeohash import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.navigation.topbars.SearchTopBarAction import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/GitRepositoryHomeUi.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/GitRepositoryHomeUi.kt index ecfae53ba9..382157f68d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/GitRepositoryHomeUi.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/GitRepositoryHomeUi.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.git_repo_external_host_body import com.vitorpamplona.amethyst.commons.resources.git_repo_external_host_title diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/code/GitFileViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/code/GitFileViewer.kt index 8c5ad220fb..3c7741fc13 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/code/GitFileViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/gitRepo/code/GitFileViewer.kt @@ -70,11 +70,11 @@ import com.vitorpamplona.amethyst.commons.resources.git_repo_code_loading import com.vitorpamplona.amethyst.commons.resources.git_repo_copy_file import com.vitorpamplona.amethyst.commons.resources.git_repo_file_load_error import com.vitorpamplona.amethyst.commons.resources.git_repo_plain_text +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.components.RichTextViewer -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip34Git.git.GitRepoSnapshot import com.vitorpamplona.quartz.nip34Git.git.GitTreeEntry diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagScreen.kt index 6b298ba1b4..b3add349ab 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/hashtag/HashtagScreen.kt @@ -56,6 +56,7 @@ import com.vitorpamplona.amethyst.commons.resources.read_only_user import com.vitorpamplona.amethyst.commons.resources.unmute_hashtag import com.vitorpamplona.amethyst.commons.search.SearchSeed import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -63,7 +64,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingHashtag import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsMutingHashtag import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.navigation.topbars.SearchTopBarAction import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt index e4b49b4caf..e22aa4e734 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt @@ -82,6 +82,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverPagerState import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.zonedDrawerSwipeIfModal import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -101,7 +102,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.backups.BackupConflictCards diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderEphemeralBubble.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderEphemeralBubble.kt index d41e14d3e7..552d98c52f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderEphemeralBubble.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderEphemeralBubble.kt @@ -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.model.emphChat.EphemeralChatChannel +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.observeChannelNoteAuthors diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderLiveActivityBubble.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderLiveActivityBubble.kt index 73208feba7..2ecf69a51e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderLiveActivityBubble.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/live/RenderLiveActivityBubble.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/ListOfInterestSetsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/ListOfInterestSetsScreen.kt index 92aa79a3b6..e0269d1c9c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/ListOfInterestSetsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/interestSets/list/ListOfInterestSetsScreen.kt @@ -52,13 +52,13 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.interest_set_create_btn_label import com.vitorpamplona.amethyst.commons.resources.interest_sets_empty import com.vitorpamplona.amethyst.commons.resources.interest_sets_title +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.fabBottomBarPadding import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/keyBackup/AccountBackupScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/keyBackup/AccountBackupScreen.kt index 974c4219f0..de2b248ff6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/keyBackup/AccountBackupScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/keyBackup/AccountBackupScreen.kt @@ -102,6 +102,8 @@ import com.vitorpamplona.amethyst.commons.resources.secret_key_copied_to_clipboa import com.vitorpamplona.amethyst.commons.resources.show_encrypted_private_key_qr_code import com.vitorpamplona.amethyst.commons.resources.show_password import com.vitorpamplona.amethyst.commons.resources.show_private_key_qr_code +import com.vitorpamplona.amethyst.commons.ui.components.util.getText +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -113,8 +115,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.commons.ui.theme.grayText import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.model.Account -import com.vitorpamplona.amethyst.ui.components.util.getText -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.authenticate import com.vitorpamplona.amethyst.ui.note.rememberAuthPromptLabels import com.vitorpamplona.amethyst.ui.painterRes diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/longs/LongsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/longs/LongsScreen.kt index 296f11b516..107a3508e2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/longs/LongsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/longs/LongsScreen.kt @@ -29,12 +29,12 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.longs.datasource.LongsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicPlaylistsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicPlaylistsScreen.kt index 5544e0fa73..ebe632548e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicPlaylistsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicPlaylistsScreen.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.amethyst.commons.music.ui.NewMusicPlaylistFab import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn @@ -38,7 +39,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.datasource.MusicPlaylistsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicTracksScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicTracksScreen.kt index 7330473598..d992351abd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicTracksScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/music/MusicTracksScreen.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.amethyst.commons.music.ui.NewMusicTrackButton import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn @@ -38,7 +39,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.music.datasource.MusicTracksFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt index 2554971131..0ebe7c9beb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt @@ -63,6 +63,7 @@ import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.live_stream_ended_tag import com.vitorpamplona.amethyst.commons.resources.nests_ended_ago diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsScreen.kt index 070a931c91..6e7bb87122 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsScreen.kt @@ -47,13 +47,13 @@ import com.vitorpamplona.amethyst.commons.resources.nests import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.create.CreateNestSheet import com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.create.CreateNestViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestJoinCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestJoinCard.kt index 904a25ff36..27b6242818 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestJoinCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestJoinCard.kt @@ -46,6 +46,7 @@ import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nest_join diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt index 22d4c37717..47316d842d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt @@ -64,6 +64,7 @@ import com.vitorpamplona.amethyst.commons.model.AddressableNote import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.nest_chat_empty import com.vitorpamplona.amethyst.commons.resources.nest_lobby_host_label diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/donations/ZapTheDevsCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/donations/ZapTheDevsCard.kt index bd2171f8df..26c85c7ee3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/donations/ZapTheDevsCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/donations/ZapTheDevsCard.kt @@ -57,6 +57,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.brought_to_you_by import com.vitorpamplona.amethyst.commons.resources.cancel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PicturesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PicturesScreen.kt index 59decc69dd..ed7d680d4b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PicturesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PicturesScreen.kt @@ -29,12 +29,12 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.pictures.datasource.PicturesFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastAuthors.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastAuthors.kt index 25e94923de..e5b4c014ea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastAuthors.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastAuthors.kt @@ -41,6 +41,7 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.podcast_author_verified import com.vitorpamplona.amethyst.commons.resources.podcast_role_cohost diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastEpisodeListItem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastEpisodeListItem.kt index 401535b33d..c111567372 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastEpisodeListItem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastEpisodeListItem.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.podcast_episode_number import com.vitorpamplona.amethyst.commons.resources.podcast_season diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTopSupporters.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTopSupporters.kt index 5d22aec59b..aecc3b5f67 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTopSupporters.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastTopSupporters.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.nip53LiveActivities.LiveActivityTopZappersAggregator import com.vitorpamplona.amethyst.commons.nip53LiveActivities.TopZapperEntry import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ZapContribution diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastsScreen.kt index 7b96fe37b5..42173a892e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/podcasts/PodcastsScreen.kt @@ -37,6 +37,7 @@ import com.vitorpamplona.amethyst.commons.resources.podcast_your_podcast import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -45,7 +46,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.podcasts.datasource.PodcastsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/PollsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/PollsScreen.kt index e67f6024d6..92e442ca85 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/PollsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/PollsScreen.kt @@ -45,6 +45,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverPagerState +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight @@ -52,7 +53,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.polls.datasource.PollsFilterAssemblerSubscription import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/results/PollResultsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/results/PollResultsScreen.kt index 584d250ec6..3a84c47426 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/results/PollResultsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/polls/results/PollResultsScreen.kt @@ -71,6 +71,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.poll_multiple_choice import com.vitorpamplona.amethyst.commons.resources.poll_results_all_options diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsScreen.kt index 99c72dfa2d..cc0f69bb77 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsScreen.kt @@ -30,11 +30,11 @@ import com.vitorpamplona.amethyst.commons.nip99Classifieds.ui.NewProductButton import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.SaveableGridFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.products.datasource.ProductsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt index 1c24b1f67c..c41a2b6ab7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryCardCompose.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/Bolt12OffersDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/Bolt12OffersDialog.kt index 7dbd7517c1..d425f7f03e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/Bolt12OffersDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/Bolt12OffersDialog.kt @@ -62,11 +62,11 @@ import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard import com.vitorpamplona.amethyst.commons.resources.no_wallet_found import com.vitorpamplona.amethyst.commons.ui.components.M3ActionDialog import com.vitorpamplona.amethyst.commons.ui.components.M3ActionSection +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.payViaBolt12Intent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawBanner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawBanner.kt index 0e98dbf4cd..4e49948fa6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawBanner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawBanner.kt @@ -45,10 +45,10 @@ import com.vitorpamplona.amethyst.commons.resources.Res 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.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserBanner import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/PaymentTargetsDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/PaymentTargetsDialog.kt index 053fdad2a3..1941a50d95 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/PaymentTargetsDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/PaymentTargetsDialog.kt @@ -63,10 +63,10 @@ import com.vitorpamplona.amethyst.commons.resources.show_qr 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.loadStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.QrCodeDrawer import com.vitorpamplona.quartz.experimental.nipA3.PaymentTarget diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/ProfilePaymentRailChips.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/ProfilePaymentRailChips.kt index 6e006308f9..85eca033f8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/ProfilePaymentRailChips.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/ProfilePaymentRailChips.kt @@ -66,13 +66,13 @@ import com.vitorpamplona.amethyst.commons.resources.copy_to_clipboard import com.vitorpamplona.amethyst.commons.resources.send_payment_method_cashu import com.vitorpamplona.amethyst.commons.resources.send_payment_method_lightning import com.vitorpamplona.amethyst.commons.resources.send_payment_method_onchain +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.Size16Modifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.payment.ProfilePaymentMethod diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserProfileDropDownMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserProfileDropDownMenu.kt index 47457d53f3..07a9bc477b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserProfileDropDownMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/UserProfileDropDownMenu.kt @@ -47,8 +47,8 @@ import com.vitorpamplona.amethyst.commons.resources.unblock_user 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.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.WatchAndLoadMyEmojiList import com.vitorpamplona.amethyst.ui.note.externalLinkForUser import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt index aea887d665..37e2865fe1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt @@ -64,6 +64,7 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.badge_award_image import com.vitorpamplona.amethyst.commons.resources.badge_award_image_for diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt index eb4d0d85d6..c437afb68d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt @@ -91,13 +91,13 @@ import com.vitorpamplona.amethyst.commons.resources.send_payment_method_onchain import com.vitorpamplona.amethyst.commons.resources.send_payment_no_methods import com.vitorpamplona.amethyst.commons.resources.send_payment_receipt_section import com.vitorpamplona.amethyst.commons.resources.send_payment_try_again +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.showAmount import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent import kotlinx.collections.immutable.ImmutableList diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/relays/RelayFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/relays/RelayFeedView.kt index 0184ad8bb1..2b3399da6f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/relays/RelayFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/relays/RelayFeedView.kt @@ -41,9 +41,9 @@ import com.vitorpamplona.amethyst.commons.resources.public_home_section import com.vitorpamplona.amethyst.commons.resources.public_home_section_explainer_profile import com.vitorpamplona.amethyst.commons.resources.public_notif_section import com.vitorpamplona.amethyst.commons.resources.public_notif_section_explainer_profile +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.RelayCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/zaps/ZapNoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/zaps/ZapNoteCompose.kt index 1187705078..ed93534498 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/zaps/ZapNoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/zaps/ZapNoteCompose.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.model.User import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.BitcoinOrange diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/publicChats/PublicChatsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/publicChats/PublicChatsScreen.kt index fa2c5bebab..54752b3e35 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/publicChats/PublicChatsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/publicChats/PublicChatsScreen.kt @@ -30,12 +30,12 @@ import com.vitorpamplona.amethyst.commons.nip28PublicChat.ui.NewPublicChatButton import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.publicChats.datasource.PublicChatsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt index a2060f9e78..c768821527 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.relayClient.event.observeNoteLocally import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.looking_for_event diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relay/RelayFeedScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relay/RelayFeedScreen.kt index 42f31c82eb..4d24a10b04 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relay/RelayFeedScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relay/RelayFeedScreen.kt @@ -34,11 +34,11 @@ import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_ import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_be_able_to_unfollow import com.vitorpamplona.amethyst.commons.resources.read_only_user import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowingRelay import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.dal.SingleRelayFeedViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt index 926266fb4e..abe244fb9b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.relays.ui.relayDragHandle import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.and_more import com.vitorpamplona.amethyst.commons.resources.relay_reorder +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness @@ -60,7 +61,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.ReactionRowHeightChatMaxWidth import com.vitorpamplona.amethyst.commons.ui.theme.Size25dp import com.vitorpamplona.amethyst.model.nip11RelayInfo.Nip11CachedRetriever import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/RelayNameAndRemoveButton.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/RelayNameAndRemoveButton.kt index fec998d639..0689224066 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/RelayNameAndRemoveButton.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/RelayNameAndRemoveButton.kt @@ -43,10 +43,10 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.paid_relay import com.vitorpamplona.amethyst.commons.resources.remove import com.vitorpamplona.amethyst.commons.resources.tor_relay +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.LightRedColor import com.vitorpamplona.amethyst.commons.ui.theme.allGoodColor -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl import kotlinx.coroutines.launch diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/scheduledposts/ScheduledPostsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/scheduledposts/ScheduledPostsScreen.kt index 49f920636f..9d7eedbcfb 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/scheduledposts/ScheduledPostsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/scheduledposts/ScheduledPostsScreen.kt @@ -124,6 +124,7 @@ import com.vitorpamplona.amethyst.commons.scheduledposts.extractEventId import com.vitorpamplona.amethyst.commons.scheduledposts.extractFirstMediaUrl import com.vitorpamplona.amethyst.commons.scheduledposts.ui.MediaThumbnail import com.vitorpamplona.amethyst.commons.ui.components.SwipeToDeleteWithConfirmation +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.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarSize @@ -131,7 +132,6 @@ import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPostWorker -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot import com.vitorpamplona.amethyst.ui.note.timeAheadNoDot diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt index 46072a6f17..b2c953d106 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt @@ -85,6 +85,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.cache.LocalCache import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.ephemeral_relay_chat import com.vitorpamplona.amethyst.commons.resources.npub_hex_username diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ResourceUsageScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ResourceUsageScreen.kt index fda4e185a4..efd3394001 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ResourceUsageScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ResourceUsageScreen.kt @@ -132,6 +132,7 @@ import com.vitorpamplona.amethyst.commons.resources.resource_usage_verifies import com.vitorpamplona.amethyst.commons.resources.resource_usage_wakelock import com.vitorpamplona.amethyst.commons.resources.resource_usage_worker_runs import com.vitorpamplona.amethyst.commons.service.crashreports.DEV_REPORT_PUBKEY +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton @@ -145,7 +146,6 @@ import com.vitorpamplona.amethyst.service.resourceusage.ResourceUsageReportAssem import com.vitorpamplona.amethyst.service.resourceusage.ResourceUsageReportAssembler.Companion.formatConnHours import com.vitorpamplona.amethyst.service.resourceusage.ResourceUsageReportAssembler.Companion.formatDurationMs import com.vitorpamplona.amethyst.service.resourceusage.UsageSummary -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.routes.routeToMessage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SecurityListsCommon.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SecurityListsCommon.kt index a1f539fb5e..790a12547b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SecurityListsCommon.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/SecurityListsCommon.kt @@ -52,6 +52,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.num_selected import com.vitorpamplona.amethyst.commons.resources.unblock diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt index 988dc62a0e..1ce01265b3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt @@ -117,13 +117,13 @@ import com.vitorpamplona.amethyst.commons.resources.nip46_signer_scan_connect import com.vitorpamplona.amethyst.commons.resources.nip46_signer_status_no_relays import com.vitorpamplona.amethyst.commons.resources.nip46_signer_title import com.vitorpamplona.amethyst.commons.resources.nip46_signer_turn_on +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.loadStringRes import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.model.nip46Signer.Nip46SignerState -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.QrCodeDrawer import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/ShortsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/ShortsScreen.kt index 3d67f49374..df69d34184 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/ShortsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/ShortsScreen.kt @@ -29,12 +29,12 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts.datasource.ShortsFilterAssemblerSubscription diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index 54c43540f4..bfcbcefe10 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -81,6 +81,7 @@ import com.vitorpamplona.amethyst.commons.chats.ui.ThinSendButton import com.vitorpamplona.amethyst.commons.feeds.FeedState import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.expand import com.vitorpamplona.amethyst.commons.resources.hi_seller_is_this_still_available diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/url/UrlScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/url/UrlScreen.kt index 5cd1d7b873..47784e4175 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/url/UrlScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/url/UrlScreen.kt @@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.external_content_title import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -40,7 +41,6 @@ import com.vitorpamplona.amethyst.ui.components.UrlPreviewCard import com.vitorpamplona.amethyst.ui.components.rememberUrlPreviewState import com.vitorpamplona.amethyst.ui.feeds.FeedLoaded import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.note.nip22Comments.LocalCurrentExternalScope import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt index 1fba9b43cd..62b3f8d31a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt index 2c1347bb47..a4f8fccfcd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt @@ -39,6 +39,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding @@ -46,7 +47,6 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.pictures.PictureCardCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts.VideoCardCompose diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt index 7e4d6e248c..b5600fa024 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddClinkDebitWalletScreen.kt @@ -63,11 +63,11 @@ import com.vitorpamplona.amethyst.commons.resources.wallet_name import com.vitorpamplona.amethyst.commons.resources.wallet_name_hint import com.vitorpamplona.amethyst.commons.resources.wallet_paste_ndebit import com.vitorpamplona.amethyst.commons.resources.wallet_save +import com.vitorpamplona.amethyst.commons.ui.components.util.getText import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.Size24Modifier -import com.vitorpamplona.amethyst.ui.components.util.getText import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt index 93aa0097fd..ca76d0d25e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddNwcWalletScreen.kt @@ -67,13 +67,13 @@ import com.vitorpamplona.amethyst.commons.resources.wallet_name import com.vitorpamplona.amethyst.commons.resources.wallet_name_hint import com.vitorpamplona.amethyst.commons.resources.wallet_paste_uri import com.vitorpamplona.amethyst.commons.resources.wallet_save +import com.vitorpamplona.amethyst.commons.ui.components.util.getText import com.vitorpamplona.amethyst.commons.ui.insets.imePaddingSafe import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.Size24Modifier -import com.vitorpamplona.amethyst.ui.components.util.getText import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.SimpleQrCodeScanner diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletScreen.kt index 1309850db9..8d768e7bff 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletScreen.kt @@ -155,12 +155,12 @@ import com.vitorpamplona.amethyst.commons.resources.paste_from_clipboard import com.vitorpamplona.amethyst.commons.resources.topup_mint_action import com.vitorpamplona.amethyst.commons.resources.wallet_add_cashu_title import com.vitorpamplona.amethyst.commons.resources.wallet_sats +import com.vitorpamplona.amethyst.commons.ui.components.util.getText +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.pluralStringRes import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.nip60Cashu.CashuWalletHistoryEoseManager -import com.vitorpamplona.amethyst.ui.components.util.getText -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt index c05e39c28f..991f6781e5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/OnchainSection.kt @@ -75,10 +75,10 @@ import com.vitorpamplona.amethyst.commons.resources.wallet_onchain_public_chip import com.vitorpamplona.amethyst.commons.resources.wallet_onchain_public_dialog_body import com.vitorpamplona.amethyst.commons.resources.wallet_onchain_public_dialog_confirm import com.vitorpamplona.amethyst.commons.resources.wallet_onchain_public_dialog_title +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.bitcoinColor -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch import java.text.NumberFormat diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/ReloadMintScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/ReloadMintScreen.kt index eea627c60b..cef6a7c1bd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/ReloadMintScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/ReloadMintScreen.kt @@ -94,10 +94,10 @@ import com.vitorpamplona.amethyst.commons.resources.reload_mint_summary_funded import com.vitorpamplona.amethyst.commons.resources.reload_mint_title import com.vitorpamplona.amethyst.commons.resources.reload_mint_topup_label import com.vitorpamplona.amethyst.commons.resources.sats +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.note.UserPicture import com.vitorpamplona.amethyst.ui.note.showAmount import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/TopUpMintScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/TopUpMintScreen.kt index 8cc6f0700a..768250c714 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/TopUpMintScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/TopUpMintScreen.kt @@ -77,10 +77,10 @@ import com.vitorpamplona.amethyst.commons.resources.sats import com.vitorpamplona.amethyst.commons.resources.topup_mint_amount_label import com.vitorpamplona.amethyst.commons.resources.topup_mint_confirm import com.vitorpamplona.amethyst.commons.resources.topup_mint_title +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.launch import androidx.compose.material3.Icon as Material3Icon diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/webBookmarks/WebBookmarksScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/webBookmarks/WebBookmarksScreen.kt index a6d9dbc60c..149d7d79f5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/webBookmarks/WebBookmarksScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/webBookmarks/WebBookmarksScreen.kt @@ -92,6 +92,7 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.commons.ui.note.ArrowBackIcon @@ -104,7 +105,6 @@ import com.vitorpamplona.amethyst.model.UrlCachedPreviewer import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutsScreen.kt index 7cd6569c25..6f5480f8da 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutsScreen.kt @@ -29,12 +29,12 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.ScrollStateKeys import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel +import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar -import com.vitorpamplona.amethyst.ui.navigation.bottombars.FabBottomBarPadded import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.workouts.datasource.WorkoutsFilterAssemblerSubscription diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/notifications/NotificationDeepLinkTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/notifications/NotificationDeepLinkTest.kt index 592f35bb36..60739b6680 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/service/notifications/NotificationDeepLinkTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/service/notifications/NotificationDeepLinkTest.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.service.notifications import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.chatroomRoute import com.vitorpamplona.amethyst.ui.isChatroomRoute diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/GiftWrapRedirectRouteTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/GiftWrapRedirectRouteTest.kt index d6ae578c23..af223a9489 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/GiftWrapRedirectRouteTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/GiftWrapRedirectRouteTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.ui import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/RouteForPointerTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/RouteForPointerTest.kt index b797a666ff..92337c0f2e 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/RouteForPointerTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/RouteForPointerTest.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.ui import com.vitorpamplona.amethyst.commons.model.navigation.Route +import com.vitorpamplona.amethyst.commons.model.navigation.routeFor import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.navigation.routes.THREAD_VIEW_KINDS import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor diff --git a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayoutTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayoutTest.kt index ac5c69857b..46c164ae5d 100644 --- a/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayoutTest.kt +++ b/amethyst/src/test/java/com/vitorpamplona/amethyst/ui/layouts/ScreenLayoutTest.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.ui.layouts +import com.vitorpamplona.amethyst.commons.ui.layouts.NavigationStyle import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/navigation/RouteBuilders.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/navigation/RouteBuilders.kt new file mode 100644 index 0000000000..e619d25967 --- /dev/null +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/navigation/RouteBuilders.kt @@ -0,0 +1,82 @@ +/* + * 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.commons.model.navigation + +import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.model.cache.LocalCache +import com.vitorpamplona.amethyst.commons.model.concord.ConcordChannel +import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel +import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel +import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel +import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel +import com.vitorpamplona.quartz.experimental.ephemChat.chat.RoomId +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip22Comments.CommentEvent +import com.vitorpamplona.quartz.nip29RelayGroups.GroupId + +/** + * A minichat reply — a kind-1111 [CommentEvent] posted into a chat message's thread — should open + * that message's minichat ([Route.ChatMinichat]), not the whole channel it lives in. Regular chat + * messages are kind 9 / 42, so a [CommentEvent] in a *chat context* is always a thread reply. We + * gate on the chat context (the reply is attached to a Concord / relay-group / public-chat gatherer, + * or its root message is) precisely so a generic NIP-22 comment on an article or note keeps its own + * thread route and isn't mistaken for a minichat. Returns null when it isn't a chat-context comment. + */ +fun minichatRouteFor(note: Note): Route? { + val comment = note.event as? CommentEvent ?: return null + val rootId = comment.rootEventIds().firstOrNull() ?: return null + + // Prefer the reply's own Concord channel (the reply arrived over that plane, so its gatherer + // always carries the community/channel), else the root note's if it happens to be loaded. Passing + // these lets the minichat screen resolve the plane + relays even when the parent isn't cached. + val concord = + note.inGatherers?.firstNotNullOfOrNull { it as? ConcordChannel } + ?: LocalCache.getNoteIfExists(rootId)?.inGatherers?.firstNotNullOfOrNull { it as? ConcordChannel } + if (concord != null) { + return Route.ChatMinichat(rootId, concord.channelId.communityId, concord.channelId.channelId) + } + + val inChatContext = note.isInChatGatherer() || LocalCache.getNoteIfExists(rootId)?.isInChatGatherer() == true + return if (inChatContext) Route.ChatMinichat(rootId) else null +} + +private fun Note.isInChatGatherer(): Boolean = inGatherers?.any { it is ConcordChannel || it is RelayGroupChannel || it is PublicChatChannel } == true + +fun routeFor(note: EphemeralChatChannel): Route = Route.EphemeralChat(note.roomId.id, note.roomId.relayUrl.url) + +fun routeFor(note: PublicChatChannel): Route = Route.PublicChatChannel(note.idHex) + +fun routeFor(note: LiveActivitiesChannel): Route = Route.LiveActivityChannel(note.address.kind, note.address.pubKeyHex, note.address.dTag) + +fun routeFor(roomId: RoomId): Route = Route.EphemeralChat(roomId.id, roomId.relayUrl.url) + +fun routeFor(note: RelayGroupChannel): Route = Route.RelayGroup(note.groupId.id, note.groupId.relayUrl.url) + +fun routeFor(groupId: GroupId): Route = Route.RelayGroup(groupId.id, groupId.relayUrl.url) + +fun routeFor(channel: ConcordChannel): Route = Route.Concord(channel.channelId.communityId, channel.channelId.channelId) + +fun routeFor(user: User): Route.Profile = Route.Profile(user.pubkeyHex) + +fun routeForUser(userHex: HexKey): Route.Profile = Route.Profile(userHex) + +fun authorRouteFor(note: Note): Route.Profile? = note.author?.pubkeyHex?.let { Route.Profile(it) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/ClipboardExt.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.android.kt similarity index 89% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/ClipboardExt.kt rename to commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.android.kt index 8b3b7a0c10..ecf6c4b0d3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/util/ClipboardExt.kt +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.android.kt @@ -18,17 +18,17 @@ * 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.util +package com.vitorpamplona.amethyst.commons.ui.components.util import android.content.ClipData import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.platform.Clipboard -suspend fun Clipboard.setText(text: String) { +actual suspend fun Clipboard.setText(text: String) { setClipEntry(ClipEntry(ClipData.newPlainText("", text))) } -suspend fun Clipboard.getText(): String? = +actual suspend fun Clipboard.getText(): String? = getClipEntry() ?.clipData ?.getItemAt(0) diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/Crossfade.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/Crossfade.kt index 0642d05d96..c8988c4a84 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/Crossfade.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/Crossfade.kt @@ -35,20 +35,27 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.remember +import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.util.fastForEach /** - * [Crossfade][MyCrossfade] between [targetState]s when [enabled], a plain swap otherwise (the app - * turns it off in performance mode). The animated path defers building its transition until the - * target first changes; see [DeferredCrossfade]. + * Whether decorative animations run. The app turns them off in performance mode by providing + * `false` near its root; [CrossfadeIfEnabled] follows it unless told otherwise. + */ +val LocalAnimationsEnabled = staticCompositionLocalOf { true } + +/** + * [Crossfade][MyCrossfade] between [targetState]s when [enabled], a plain swap otherwise. By default + * [enabled] follows [LocalAnimationsEnabled]. The animated path defers building its transition until + * the target first changes; see [DeferredCrossfade]. */ @Composable fun CrossfadeIfEnabled( targetState: T, - enabled: Boolean, + enabled: Boolean = LocalAnimationsEnabled.current, modifier: Modifier = Modifier, contentAlignment: Alignment = Alignment.TopStart, animationSpec: FiniteAnimationSpec = tween(), diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.kt new file mode 100644 index 0000000000..86c657d161 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.kt @@ -0,0 +1,29 @@ +/* + * 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.commons.ui.components.util + +import androidx.compose.ui.platform.Clipboard + +/** Puts [text] on the system clipboard as plain text. */ +expect suspend fun Clipboard.setText(text: String) + +/** The clipboard's current plain text, or null when it holds none. */ +expect suspend fun Clipboard.getText(): String? diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ScreenLayout.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ScreenLayout.kt new file mode 100644 index 0000000000..03fb009018 --- /dev/null +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/ScreenLayout.kt @@ -0,0 +1,62 @@ +/* + * 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.commons.ui.layouts + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.compositionLocalOf + +/** How the app shell presents its top-level navigation for the current window size. */ +enum class NavigationStyle { + /** Compact windows (phones): bottom navigation bar + modal drawer. */ + BOTTOM_BAR, + + /** + * Every non-Compact window that does not dock — portrait tablets and unfolded foldables at + * any width, plus short landscape windows: a left navigation rail replaces the bottom bar + * and the drawer stays modal behind the rail's avatar button. + */ + NAV_RAIL, + + /** Wide, landscape, tall windows (landscape tablets, desktop): the drawer docks permanently on the left. */ + PERMANENT_DRAWER, +} + +/** + * The shell layout decisions for the current window, published once per window size change + * through [LocalScreenLayout] so every screen, bar and panel agrees on the same tier. + */ +@Immutable +data class ScreenLayoutSpec( + val navigationStyle: NavigationStyle, + val hasRoomForNotificationPanel: Boolean, +) { + /** + * True on the rail and permanent-drawer tiers. Large screens hide the bottom bar and pin + * the top/bottom chrome (no disappearing bars on scroll). + */ + val isLargeScreen: Boolean get() = navigationStyle != NavigationStyle.BOTTOM_BAR + + companion object { + val Phone = ScreenLayoutSpec(NavigationStyle.BOTTOM_BAR, hasRoomForNotificationPanel = false) + } +} + +val LocalScreenLayout = compositionLocalOf { ScreenLayoutSpec.Phone } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/FabBottomBarPadding.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/navigation/bottombars/FabBottomBarPadding.kt similarity index 87% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/FabBottomBarPadding.kt rename to commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/navigation/bottombars/FabBottomBarPadding.kt index e74b7a58ff..723231f179 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/FabBottomBarPadding.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/navigation/bottombars/FabBottomBarPadding.kt @@ -18,21 +18,21 @@ * 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.navigation.bottombars +package com.vitorpamplona.amethyst.commons.ui.navigation.bottombars import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.layouts.LocalScreenLayout /** - * Reserves the visual space the [AppBottomBar] occupies on root tab entries so a + * Reserves the visual space the `AppBottomBar` occupies on root tab entries so a * FloatingActionButton stays at the same vertical position whether or not the bar is - * rendered. [AppBottomBar] hides itself on canPop entries (drawer pushes, in-app - * navigations) — without this padding the FAB drops by [AppBottomBarHeight] there. + * rendered. `AppBottomBar` hides itself on canPop entries (drawer pushes, in-app + * navigations) — without this padding the FAB drops by `AppBottomBarHeight` there. * * The system-navigation-bar inset is already handled by the surrounding Scaffold, so * only the bar's content height needs to be reserved. diff --git a/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt new file mode 100644 index 0000000000..636ba02479 --- /dev/null +++ b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt @@ -0,0 +1,31 @@ +/* + * 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.commons.ui.components.util + +import androidx.compose.ui.platform.Clipboard +import platform.UIKit.UIPasteboard + +// Reads and writes the general pasteboard directly: plain text needs nothing from ClipEntry here. +actual suspend fun Clipboard.setText(text: String) { + UIPasteboard.generalPasteboard.string = text +} + +actual suspend fun Clipboard.getText(): String? = UIPasteboard.generalPasteboard.string diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ClipboardExt.kt b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.jvm.kt similarity index 84% rename from desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ClipboardExt.kt rename to commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.jvm.kt index 6221c2d0d8..b1cb251cb1 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ClipboardExt.kt +++ b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.jvm.kt @@ -18,21 +18,22 @@ * 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.desktop +package com.vitorpamplona.amethyst.commons.ui.components.util +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.platform.Clipboard import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.StringSelection import java.awt.datatransfer.Transferable -@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class) -suspend fun Clipboard.setText(text: String) { +@OptIn(ExperimentalComposeUiApi::class) +actual suspend fun Clipboard.setText(text: String) { setClipEntry(ClipEntry(StringSelection(text))) } -@OptIn(androidx.compose.ui.ExperimentalComposeUiApi::class) -suspend fun Clipboard.getText(): String? { +@OptIn(ExperimentalComposeUiApi::class) +actual suspend fun Clipboard.getText(): String? { val entry = getClipEntry() ?: return null val transferable = entry.nativeClipEntry as? Transferable ?: return null return try { diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ArticleReaderScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ArticleReaderScreen.kt index 9f5c7a42aa..8092de6e4e 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ArticleReaderScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ArticleReaderScreen.kt @@ -74,10 +74,10 @@ import com.vitorpamplona.amethyst.commons.nip23LongContent.ui.article.TableOfCon import com.vitorpamplona.amethyst.commons.nip23LongContent.ui.article.extractTableOfContents import com.vitorpamplona.amethyst.commons.ui.components.EmptyState import com.vitorpamplona.amethyst.commons.ui.components.LoadingState +import com.vitorpamplona.amethyst.commons.ui.components.util.getText import com.vitorpamplona.amethyst.commons.ui.markdown.RenderMarkdown import com.vitorpamplona.amethyst.desktop.account.AccountState import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache -import com.vitorpamplona.amethyst.desktop.getText import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.service.highlights.DesktopHighlightStore import com.vitorpamplona.amethyst.desktop.subscriptions.DesktopRelaySubscriptionsCoordinator diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt index 65c8fe7917..c3aad39602 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/auth/LoginCard.kt @@ -60,9 +60,9 @@ import com.vitorpamplona.amethyst.commons.resources.login_button import com.vitorpamplona.amethyst.commons.resources.login_card_subtitle import com.vitorpamplona.amethyst.commons.resources.login_card_title import com.vitorpamplona.amethyst.commons.resources.login_generate_button +import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.desktop.account.LoginProgress import com.vitorpamplona.amethyst.desktop.account.validateBunkerUri -import com.vitorpamplona.amethyst.desktop.setText import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext From c807feaae70a6ffe711046fd8e67f0f5ad527fa1 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 24 Sep 2026 14:18:42 +0000 Subject: [PATCH 9/9] fix: address the audit of the shared insets, emoji text and crossfade - Run :commonsUI:testAndroidHostTest in CI and the pre-push hook. The moved SafeImeInsetsTest lives there and nothing ran it. - Emoji text: one implementation behind both CustomEmojiChecker and CreateTextWithEmoji overloads. The emoji path now keys its merged style on color, weight and size (it kept the first ones), and passes textAlign through InLineIconRenderer (a centered name with a custom emoji was drawn left-aligned, e.g. the audio-room participant grid). - ClickableInLineIconRenderer remembers its inline content and text and reuses the shared builder; it rebuilt both on every recomposition. - RenderCustomEmoji delegates to CreateTextWithEmoji, so shared rich text and names resolve emojis on the same path. - LocalAnimationsEnabled is provided by AmethystTheme from the global feature set, so every activity root has it. The app's CrossfadeIfEnabled wrapper is gone; its 39 callers use the shared one and drop the accountViewModel argument. - KeyboardState / ImeSettler KDoc links point at the moved SafeImeInsets. - iOS getText checks hasStrings before reading the pasteboard. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0168wY9t7i9NC5u3svyMxEz6 --- .git-hooks/pre-push | 2 + .github/workflows/build.yml | 1 + .../amethyst/ui/actions/CrossfadeIfEnabled.kt | 48 --- .../amethyst/ui/components/CashuRedeem.kt | 4 +- .../ui/components/ClickableWithdrawal.kt | 4 +- .../amethyst/ui/components/LoadUrlPreview.kt | 3 +- .../amethyst/ui/components/MyAsyncImage.kt | 4 +- .../ui/components/ReusableZapButton.kt | 4 +- .../amethyst/ui/components/RichTextViewer.kt | 4 +- .../ui/components/SensitivityWarning.kt | 6 +- .../ui/components/ZoomableContentView.kt | 6 +- .../amethyst/ui/feeds/FeedContentStateView.kt | 3 +- .../amethyst/ui/navigation/AppNavigation.kt | 7 - .../ui/navigation/bottombars/KeyboardState.kt | 4 +- .../amethyst/ui/navigation/navs/ImeSettler.kt | 4 +- .../amethyst/ui/note/DisplayAuthorBanner.kt | 4 +- .../ui/note/NIP05VerificationDisplay.kt | 4 +- .../amethyst/ui/note/ReactionsRow.kt | 9 +- .../amethyst/ui/note/RelayListBox.kt | 4 +- .../amethyst/ui/note/UsernameDisplay.kt | 6 +- .../amethyst/ui/note/WatchNoteEvent.kt | 4 +- .../note/creators/invoice/InvoicePreview.kt | 4 +- .../ui/note/creators/previews/PreviewUrl.kt | 4 +- .../amethyst/ui/note/types/Emoji.kt | 4 +- .../amethyst/ui/note/types/FileStorage.kt | 4 +- .../amethyst/ui/note/types/LiveActivity.kt | 4 +- .../amethyst/ui/note/types/MeetingSpace.kt | 6 +- .../amethyst/ui/screen/FeedView.kt | 3 +- .../amethyst/ui/screen/UserFeedView.kt | 4 +- .../loggedIn/chats/feed/ChatFeedView.kt | 4 +- .../privateDM/header/RoomNameOnlyDisplay.kt | 8 +- .../chats/rooms/feed/ChatroomListFeedView.kt | 3 +- .../communities/list/CommunitiesScreen.kt | 3 +- .../loggedIn/discover/DiscoverScreen.kt | 4 +- .../nip53LiveActivities/LiveActivityCard.kt | 4 +- .../browse/BrowseEmojiSetsScreen.kt | 3 +- .../loggedIn/geocaches/GeocacheFeedLoaded.kt | 3 +- .../ui/screen/loggedIn/home/HomeScreen.kt | 3 +- .../screen/loggedIn/nests/NestsFeedLoaded.kt | 4 +- .../loggedIn/products/ProductsFeedLoaded.kt | 3 +- .../loggedIn/profile/gallery/GalleryThumb.kt | 4 +- .../profile/gallery/ProfileGalleryFeed.kt | 3 +- .../header/apps/DisplayAppRecommendations.kt | 3 +- .../loggedIn/relays/RelayInformationScreen.kt | 4 +- .../loggedIn/settings/StringFeedView.kt | 4 +- .../vitorpamplona/amethyst/ui/theme/Theme.kt | 8 +- .../ui/richtext/CustomEmojiRenderer.kt | 361 ++++++++---------- .../ui/components/util/ClipboardExt.ios.kt | 7 +- 48 files changed, 255 insertions(+), 349 deletions(-) delete mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt diff --git a/.git-hooks/pre-push b/.git-hooks/pre-push index 7faea9d18a..97429818f3 100755 --- a/.git-hooks/pre-push +++ b/.git-hooks/pre-push @@ -28,6 +28,8 @@ TASKS=( :quartz:jvmTest :commons:jvmTest :commonsUI:jvmTest + # Android-only commonsUI code (e.g. SafeImeInsets) is tested here, not in jvmTest. + :commonsUI:testAndroidHostTest :nestsClient:jvmTest :quic:jvmTest :marmotQuic:jvmTest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc5c96b109..25df64d47d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -379,6 +379,7 @@ jobs: :quartz:jvmTest \ :commons:jvmTest \ :commonsUI:jvmTest \ + :commonsUI:testAndroidHostTest \ :nestsClient:jvmTest \ :amethyst:testFdroidDebugUnitTest \ :amethyst:testPlayDebugUnitTest \ diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt deleted file mode 100644 index 9470b4e89d..0000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.actions - -import androidx.compose.animation.core.FiniteAnimationSpec -import androidx.compose.animation.core.tween -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled -import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel - -@Composable -fun CrossfadeIfEnabled( - targetState: T, - modifier: Modifier = Modifier, - contentAlignment: Alignment = Alignment.TopStart, - animationSpec: FiniteAnimationSpec = tween(), - label: String = "Crossfade", - accountViewModel: AccountViewModel, - content: @Composable (T) -> Unit, -) = CrossfadeIfEnabled( - targetState = targetState, - enabled = !accountViewModel.settings.isPerformanceMode(), - modifier = modifier, - contentAlignment = contentAlignment, - animationSpec = animationSpec, - label = label, - content = content, -) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt index ccb7965dfc..08537874f9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/CashuRedeem.kt @@ -57,6 +57,7 @@ import com.vitorpamplona.amethyst.commons.resources.cashu_mint_label import com.vitorpamplona.amethyst.commons.resources.cashu_no_wallet_found import com.vitorpamplona.amethyst.commons.resources.cashu_redeem import com.vitorpamplona.amethyst.commons.resources.sats +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.note.OpenInNewIcon @@ -68,7 +69,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn import com.vitorpamplona.amethyst.service.cashu.CachedCashuParser -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip60Cashu.token.CashuToken import kotlinx.collections.immutable.ImmutableList @@ -93,7 +93,7 @@ fun CashuPreview( } } - CrossfadeIfEnabled(targetState = cashuData, label = "CashuPreview", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = cashuData, label = "CashuPreview") { when (it) { is GenericLoadable.Loaded> -> { CashuPreview(it.loaded, accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt index 24418a05f1..ba2ab54aed 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ClickableWithdrawal.kt @@ -34,8 +34,8 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.error_dialog_pay_withdraw_error import com.vitorpamplona.amethyst.commons.resources.no_wallet_found import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog import com.vitorpamplona.amethyst.ui.note.payViaIntent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -54,7 +54,7 @@ fun MayBeWithdrawal( launch(Dispatchers.IO) { lnWithdrawal = LnWithdrawalUtil.findWithdrawal(lnurlWord) } } - CrossfadeIfEnabled(targetState = lnWithdrawal, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = lnWithdrawal) { if (it != null) { ClickableWithdrawal(withdrawalString = it) } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/LoadUrlPreview.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/LoadUrlPreview.kt index fd5018f2bd..c852bc1208 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/LoadUrlPreview.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/LoadUrlPreview.kt @@ -29,11 +29,11 @@ import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlPdf import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.model.UrlCachedPreviewer -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable @@ -82,7 +82,6 @@ fun LoadUrlPreviewDirect( CrossfadeIfEnabled( targetState = urlPreviewState, label = "UrlPreview", - accountViewModel = accountViewModel, ) { state -> when (state) { is UrlPreviewState.Loaded -> { 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 6446525a49..a549723619 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 @@ -38,13 +38,13 @@ import coil3.compose.AsyncImagePainter import coil3.compose.SubcomposeAsyncImage import coil3.compose.SubcomposeAsyncImageContent import com.vitorpamplona.amethyst.commons.richtext.isAnimatedMediaUrl +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.note.DownloadForOfflineIcon import com.vitorpamplona.amethyst.commons.ui.theme.Size40dp import com.vitorpamplona.amethyst.commons.ui.theme.Size6dp import com.vitorpamplona.amethyst.commons.ui.theme.Size75dp import com.vitorpamplona.amethyst.model.MediaAspectRatioCache -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable @@ -74,7 +74,7 @@ fun MyAsyncImage( val ratio = MediaAspectRatioCache.get(imageUrl) val showImage = remember { mutableStateOf(accountViewModel.settings.showImages()) } - CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center) { if (it) { SubcomposeAsyncImage( model = imageUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt index 52cc74e840..5e801b6926 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt @@ -56,6 +56,7 @@ import com.vitorpamplona.amethyst.commons.resources.login_with_a_private_key_to_ import com.vitorpamplona.amethyst.commons.resources.no_wallet_found import com.vitorpamplona.amethyst.commons.resources.no_zap_amount_setup_long_press_to_change import com.vitorpamplona.amethyst.commons.resources.thank_you +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.note.ZapIcon import com.vitorpamplona.amethyst.commons.ui.note.ZappedIcon @@ -66,7 +67,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderFilterAssemblerSubscription -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage import com.vitorpamplona.amethyst.ui.note.ObserveZapIcon import com.vitorpamplona.amethyst.ui.note.ZapAmountChoicePopup @@ -254,7 +254,6 @@ fun ReusableZapButton( CrossfadeIfEnabled( targetState = wasZappedByLoggedInUser.value, label = "ZapIcon", - accountViewModel = accountViewModel, ) { if (it) { ZappedIcon(config.iconSizeModifier) @@ -286,7 +285,6 @@ fun ReusableZapButton( CrossfadeIfEnabled( targetState = wasZappedByLoggedInUser.value, label = "ZapIcon", - accountViewModel = accountViewModel, ) { if (it) { ZappedIcon(config.iconSizeModifier) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index 1c6370fe22..cec01b06fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -103,6 +103,7 @@ import com.vitorpamplona.amethyst.commons.richtext.VideoSegment import com.vitorpamplona.amethyst.commons.richtext.WithdrawSegment import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.NowhereLinkCard import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -119,7 +120,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinder import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserNickname import com.vitorpamplona.amethyst.service.uploads.blossom.bud10.openBlossomUriAsIntent -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.creators.invoice.ClinkOfferPreview import com.vitorpamplona.amethyst.ui.note.creators.invoice.MayBeInvoicePreview @@ -980,7 +980,7 @@ private fun DisplayUserFromTag( val nickname by observeUserNickname(baseUser, accountViewModel) val petName = nickname?.petName - CrossfadeIfEnabled(targetState = meta, label = "DisplayUserFromTag", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = meta, label = "DisplayUserFromTag") { Row { CreateClickableTextWithEmoji( clickablePart = remember(meta, petName) { petName ?: it?.info?.bestName() ?: baseUser.pubkeyDisplayHex() }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt index ca3f5b8816..fabeb56dd5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SensitivityWarning.kt @@ -67,12 +67,12 @@ import com.vitorpamplona.amethyst.commons.resources.content_warning_explanation import com.vitorpamplona.amethyst.commons.resources.content_warning_with_reason import com.vitorpamplona.amethyst.commons.resources.show_anyway import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.ButtonPadding import com.vitorpamplona.amethyst.commons.ui.theme.PaddingHorizontal12Modifier import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonColumn -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip36SensitiveContent.ContentWarningTag @@ -154,7 +154,7 @@ fun ContentWarningGate( } } - CrossfadeIfEnabled(targetState = showContentWarningNote, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = showContentWarningNote) { if (it) { if (backdrop != null) { Box(modifier = modifier.clipToBounds()) { @@ -180,7 +180,7 @@ fun ObserveSensitivityWarning( var showContentWarningNote by remember(accountState) { mutableStateOf(accountState.value != true) } - CrossfadeIfEnabled(targetState = showContentWarningNote, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = showContentWarningNote) { if (it) { ContentWarningNote(reason) { showContentWarningNote = false } } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 4479ce8a73..820a1ae3b2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt @@ -106,6 +106,7 @@ import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.RichTextParser import com.vitorpamplona.amethyst.commons.richtext.isAnimatedMediaUrl import com.vitorpamplona.amethyst.commons.service.image.placeholderModel +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.components.M3ActionDialog import com.vitorpamplona.amethyst.commons.ui.components.M3ActionRow @@ -126,7 +127,6 @@ import com.vitorpamplona.amethyst.model.MediaAspectRatioCache import com.vitorpamplona.amethyst.service.images.BlossomFetcher import com.vitorpamplona.amethyst.service.playback.composable.VideoView import com.vitorpamplona.amethyst.service.uploads.blossom.bud10.openBlossomUriAsIntent -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.InformationDialog import com.vitorpamplona.amethyst.ui.components.pdf.PdfPreviewCard import com.vitorpamplona.amethyst.ui.components.pdf.PdfViewerDialog @@ -414,7 +414,7 @@ fun LocalImageView( } else { content.localFile } - CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center, accountViewModel = accountViewModel) { imageVisible -> + CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center) { imageVisible -> if (imageVisible) { SubcomposeAsyncImage( model = imageModel, @@ -547,7 +547,7 @@ fun UrlImageView( content.url } - CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center) { if (it) { SubcomposeAsyncImage( model = imageModel, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt index 3c39e7fe2e..ce29dc0daf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/feeds/FeedContentStateView.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.feeds.FeedState +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -37,7 +38,6 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.RefresheableBox import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverLazyGridState import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverLazyListState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable @@ -111,7 +111,6 @@ fun RenderFeedContentState( CrossfadeIfEnabled( targetState = feedState, animationSpec = tween(durationMillis = 100), - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> onEmpty() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index b02f2cc62c..c99e788323 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -58,9 +58,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.LocalUserFinderAccoun import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.invalid_nip19_uri import com.vitorpamplona.amethyst.commons.resources.invalid_nip19_uri_description -import com.vitorpamplona.amethyst.commons.ui.components.LocalAnimationsEnabled import com.vitorpamplona.amethyst.commons.ui.layouts.LocalScreenLayout -import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.service.crashreports.DisplayCrashMessages import com.vitorpamplona.amethyst.service.relayClient.authCommand.compose.RelayAuthPromptHost import com.vitorpamplona.amethyst.service.relayClient.notifyCommand.compose.DisplayNotifyMessages @@ -361,13 +359,8 @@ fun AppNavigation( // can't read LocalScreenLayout (see NavTransitionTier). SideEffect { NavTransitionTier.isLargeScreen = screenLayout.isLargeScreen } - val featureSet by accountViewModel.settings.uiSettingsFlow.featureSet - .collectAsStateWithLifecycle() - CompositionLocalProvider( LocalScreenLayout provides screenLayout, - // Shared composables read this instead of the AccountViewModel's performance-mode flag. - LocalAnimationsEnabled provides (featureSet != FeatureSetType.PERFORMANCE), LocalTabReselectCoordinator provides tabReselectCoordinator, // Provide the shared finder CompositionLocals so any commons composable that // uses the no-arg observeUser*/EventFinderFilterAssemblerSubscription(note) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt index 45789c3425..4d9a7fde2d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt @@ -35,7 +35,7 @@ enum class KeyboardState { /** * Whether the soft keyboard is currently on screen, derived from the IME inset. * - * This intentionally reads the same [SafeImeInsets] that drives `Modifier.imePaddingSafe()` + * This intentionally reads the same [SafeImeInsets][com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] that drives `Modifier.imePaddingSafe()` * everywhere else in the app, so the two can never disagree about whether the keyboard is up. * * The original implementation measured `View.getWindowVisibleDisplayFrame` from a @@ -47,7 +47,7 @@ enum class KeyboardState { * * Reading `WindowInsets.ime` fixed that, but has a latch of its own: Compose stops updating the * inset entirely once its insets listener is left mid-animation, which pins this back at [Opened] - * in exactly the same way. [SafeImeInsets] is what closes that last hole, which is why this reads + * in exactly the same way. [SafeImeInsets][com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] is what closes that last hole, which is why this reads * the corrected inset rather than the raw one. */ @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt index fd25ab6772..67fa104dba 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt @@ -43,7 +43,7 @@ const val IME_SETTLE_TIMEOUT_MS = 700L * [WindowInsetsAnimationCompat][androidx.core.view.WindowInsetsAnimationCompat] is cancelled before * its terminal (zero) frame reaches Compose. `WindowInsets.ime` is a single app-wide holder, so it * stays "animating" and every IME padding in the app — not just the screen being left — freezes at - * the keyboard height. [SafeImeInsets] is the backstop for when that freeze turns out to be + * the keyboard height. [SafeImeInsets][com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] is the backstop for when that freeze turns out to be * permanent; this is the prevention, and it is the cheaper of the two because it keeps the padding * from ever being wrong. * @@ -63,7 +63,7 @@ fun interface ImeSettler { } /** - * Reads the same [SafeImeInsets] that drives `Modifier.imePaddingSafe()`, so the settler and the + * Reads the same [SafeImeInsets][com.vitorpamplona.amethyst.commons.ui.insets.SafeImeInsets] that drives `Modifier.imePaddingSafe()`, so the settler and the * padding can never disagree about whether the keyboard is gone. Reading the raw `WindowInsets.ime` * here would make every navigation burn the full [IME_SETTLE_TIMEOUT_MS] once the inset is stranded, * waiting on a value that is never going to move again. diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/DisplayAuthorBanner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/DisplayAuthorBanner.kt index a92697f134..5f78f383a7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/DisplayAuthorBanner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/DisplayAuthorBanner.kt @@ -24,9 +24,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.theme.SimpleImageBorder import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.elements.BannerImage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -45,7 +45,7 @@ fun DisplayAuthorBanner( ) } else { val authorState by observeNote(baseNote, accountViewModel) - CrossfadeIfEnabled(authorState.note.author, accountViewModel = accountViewModel) { author -> + CrossfadeIfEnabled(authorState.note.author) { author -> if (author != null) { BannerImage( author, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 367b4d94ab..f4d70e76ea 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -58,6 +58,7 @@ import com.vitorpamplona.amethyst.commons.resources.nip05_checking import com.vitorpamplona.amethyst.commons.resources.nip05_failed import com.vitorpamplona.amethyst.commons.resources.nip05_verified import com.vitorpamplona.amethyst.commons.ui.components.ClickableTextPrimary +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -72,7 +73,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserStatuses -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.painterRes @@ -467,7 +467,7 @@ fun RenderNIP05VerifiedSymbol( modifier: Modifier, accountViewModel: AccountViewModel, ) { - CrossfadeIfEnabled(targetState = state, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = state) { when (it) { is Nip05VerifState.Verifying, is Nip05VerifState.NotStarted -> { // Treat "not started" and "in flight" as a single loading visual so the 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 9e865aed4f..21e93147f4 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 @@ -152,6 +152,7 @@ import com.vitorpamplona.amethyst.commons.resources.reload_mint_title import com.vitorpamplona.amethyst.commons.resources.sats_to_complete import com.vitorpamplona.amethyst.commons.ui.components.AnimatedBorderTextCornerRadius import com.vitorpamplona.amethyst.commons.ui.components.ClickableBox +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable import com.vitorpamplona.amethyst.commons.ui.components.util.setText import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -224,7 +225,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteZaps import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.actions.uploads.FloatingRecordingIndicator import com.vitorpamplona.amethyst.ui.actions.uploads.MAX_VOICE_RECORD_SECONDS import com.vitorpamplona.amethyst.ui.actions.uploads.RecordAudioBox @@ -603,7 +603,6 @@ private fun RenderShowIndividualReactionsButton( CrossfadeIfEnabled( targetState = wantsToSeeReactions.value, label = "RenderShowIndividualReactionsButton", - accountViewModel = accountViewModel, ) { if (it) { ExpandLessIcon(modifier = Size22Modifier, Res.string.close_all_reactions_to_this_post) @@ -1112,7 +1111,7 @@ fun LikeReaction( onLongClick = { nav.nav(Route.UpdateReactionType) }, ) { ObserveLikeIcon(baseNote, accountViewModel) { reactionType -> - CrossfadeIfEnabled(targetState = reactionType, contentAlignment = Center, label = "LikeIcon", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = reactionType, contentAlignment = Center, label = "LikeIcon") { if (reactionType != null) { RenderReactionType(reactionType, heartSizeModifier, iconFontSize) } else { @@ -1447,7 +1446,7 @@ fun ZapReaction( accountViewModel, zapStartingTime, ) { zapIconState -> - CrossfadeIfEnabled(targetState = zapIconState, label = "ZapIcon", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = zapIconState, label = "ZapIcon") { if (it.wasZappedByLoggedInUser) { ZappedIcon(iconSizeModifier) } else { @@ -1460,7 +1459,7 @@ fun ZapReaction( baseNote, accountViewModel, ) { zapIconState -> - CrossfadeIfEnabled(targetState = zapIconState, label = "ZapIcon", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = zapIconState, label = "ZapIcon") { if (it.wasZappedByLoggedInUser) { ZappedIcon(iconSizeModifier) } else if (it.hasPendingPaymentRequest) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt index 8e116af9fc..6dfd2b8037 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListBox.kt @@ -50,13 +50,13 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.expand_relay_list +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ShowMoreRelaysButtonBoxModifer import com.vitorpamplona.amethyst.commons.ui.theme.Size17Modifier import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import kotlinx.coroutines.FlowPreview @@ -130,7 +130,7 @@ private fun RenderRelaySlot( accountViewModel: AccountViewModel, nav: INav, ) { - CrossfadeIfEnabled(targetState = relay, label = "RenderRelay", modifier = Size17Modifier, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = relay, label = "RenderRelay", modifier = Size17Modifier) { if (it != null) { RenderRelay(it, accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt index f17517e544..98fd7a4478 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UsernameDisplay.kt @@ -34,6 +34,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.note.PlayIcon import com.vitorpamplona.amethyst.commons.ui.note.UserNameText import com.vitorpamplona.amethyst.commons.ui.theme.StdButtonSizeModifier @@ -42,7 +43,6 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserNickname import com.vitorpamplona.amethyst.service.tts.TextToSpeechHelper -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.utils.Log @@ -87,7 +87,7 @@ fun WatchAuthorWithBlank( inner(noteAuthor) } else { val authorState by observeNote(baseNote, accountViewModel) - CrossfadeIfEnabled(targetState = authorState.note.author, modifier = modifier, label = "WatchAuthorWithBlank", accountViewModel = accountViewModel) { newAuthor -> + CrossfadeIfEnabled(targetState = authorState.note.author, modifier = modifier, label = "WatchAuthorWithBlank") { newAuthor -> inner(newAuthor) } } @@ -105,7 +105,7 @@ fun UsernameDisplay( val userMetadata by observeUserInfo(baseUser, accountViewModel) val nickname by observeUserNickname(baseUser, accountViewModel) - CrossfadeIfEnabled(targetState = userMetadata, modifier = weight, label = "UsernameDisplay", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = userMetadata, modifier = weight, label = "UsernameDisplay") { // the account's own nickname for this user wins over the user's metadata; // its custom emojis resolve against the contact card's tags, not the profile's val petName = nickname?.petName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/WatchNoteEvent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/WatchNoteEvent.kt index 20d878afb9..cb435bf6d0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/WatchNoteEvent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/WatchNoteEvent.kt @@ -27,10 +27,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteHasEvent import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderByParentFilterAssemblerSubscription -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @OptIn(ExperimentalFoundationApi::class) @@ -80,7 +80,7 @@ fun WatchNoteEvent( } else { // avoid observing costs if already has an event. val hasEvent by observeNoteHasEvent(baseNote, accountViewModel) - CrossfadeIfEnabled(targetState = hasEvent, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = hasEvent) { if (it) { onNoteEventFound() } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/InvoicePreview.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/InvoicePreview.kt index b302101342..46c455f13c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/InvoicePreview.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/invoice/InvoicePreview.kt @@ -47,12 +47,12 @@ import com.vitorpamplona.amethyst.commons.resources.invoice_expired import com.vitorpamplona.amethyst.commons.resources.lightning_invoice import com.vitorpamplona.amethyst.commons.resources.pay import com.vitorpamplona.amethyst.commons.resources.sats +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.commons.ui.theme.Size18Modifier import com.vitorpamplona.amethyst.service.lnurl.CachedLnInvoiceParser import com.vitorpamplona.amethyst.service.lnurl.InvoiceAmount -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.PaymentCard import com.vitorpamplona.amethyst.ui.components.PaymentCardAmount import com.vitorpamplona.amethyst.ui.components.PaymentCardDescription @@ -85,7 +85,7 @@ fun MayBeInvoicePreview( accountViewModel: AccountViewModel, ) { LoadValueFromInvoice(lnbcWord = lnbcWord) { invoiceAmount -> - CrossfadeIfEnabled(targetState = invoiceAmount, label = "MayBeInvoicePreview", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = invoiceAmount, label = "MayBeInvoicePreview") { if (it != null) { InvoicePreview(it.invoice, it.amount, it.description, it.expiresAt, accountViewModel) } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/previews/PreviewUrl.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/previews/PreviewUrl.kt index 27e39c86f7..4e7aa7b8f3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/previews/PreviewUrl.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/creators/previews/PreviewUrl.kt @@ -42,12 +42,12 @@ import androidx.compose.ui.text.style.TextOverflow import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.richtext.RichTextParser +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.state.produceCachedState import com.vitorpamplona.amethyst.model.UrlCachedPreviewer import com.vitorpamplona.amethyst.service.playback.composable.VideoView -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.ClickableUrl import com.vitorpamplona.amethyst.ui.components.DisplayUrlWithLoadingSymbol import com.vitorpamplona.amethyst.ui.components.UrlPreviewCard @@ -217,7 +217,6 @@ private fun MyLoadUrlPreviewDirect( CrossfadeIfEnabled( targetState = urlPreviewState, label = "UrlPreview", - accountViewModel = accountViewModel, ) { state -> when (state) { is UrlPreviewState.Loaded -> { @@ -286,7 +285,6 @@ private fun MyLoadUrlPreviewDirectFillWidth( CrossfadeIfEnabled( targetState = urlPreviewState, label = "UrlPreview", - accountViewModel = accountViewModel, ) { state -> when (state) { is UrlPreviewState.Loaded -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt index 0dda818c67..fab63e5e05 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Emoji.kt @@ -49,11 +49,11 @@ import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.ui.components.AddButton +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.RemoveButton import com.vitorpamplona.amethyst.commons.ui.theme.Size35Modifier import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteEvent -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.ShowMoreButton import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.note.getGradient @@ -189,7 +189,7 @@ private fun EmojiListOptions( usersEmojiList.event?.isTaggedAddressableNote(emojiPackNote.idHex) } - CrossfadeIfEnabled(targetState = hasAddedThis, label = "EmojiListOptions", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = hasAddedThis, label = "EmojiListOptions") { if (it != true) { AddButton(modifier = Modifier.padding(start = 3.dp)) { accountViewModel.addEmojiPack(emojiPackNote) } } else { 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 a232489b6b..87acaabb24 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 @@ -30,8 +30,8 @@ import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.richtext.BaseMediaContent import com.vitorpamplona.amethyst.commons.richtext.MediaLocalImage import com.vitorpamplona.amethyst.commons.richtext.MediaLocalVideo +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.LoadNote import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView @@ -110,7 +110,7 @@ private fun ObserverAndRenderNIP95( mutableStateOf(newContent) } - CrossfadeIfEnabled(targetState = content, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = content) { if (it != null) { SensitivityWarning(note = header, accountViewModel = accountViewModel) { ZoomableContentView( 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 1b6d9bc77b..cb90389db7 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 @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.live_stream_has_ended import com.vitorpamplona.amethyst.commons.resources.live_stream_is_offline import com.vitorpamplona.amethyst.commons.resources.preview_card_image_for +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -62,7 +63,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.imageModifier import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.playback.composable.VideoView import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.MyAsyncImage import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture @@ -165,7 +165,7 @@ fun RenderLiveActivityEventInner( Spacer(modifier = StdHorzSpacer) - CrossfadeIfEnabled(targetState = status, label = "RenderLiveActivityEventInner", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = status, label = "RenderLiveActivityEventInner") { when (it) { StatusTag.STATUS.LIVE -> { media?.let { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt index 13aaca7f68..1398cd086c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/MeetingSpace.kt @@ -65,6 +65,7 @@ import com.vitorpamplona.amethyst.commons.resources.nest_presence_listening import com.vitorpamplona.amethyst.commons.resources.nest_presence_on_stage import com.vitorpamplona.amethyst.commons.resources.nest_presence_raised_hand import com.vitorpamplona.amethyst.commons.resources.nest_presence_speaking +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.SmallBorder @@ -72,7 +73,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.SpacedBy5dp import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.ClickableUserPicture import com.vitorpamplona.amethyst.ui.note.UsernameDisplay @@ -141,7 +141,7 @@ fun RenderMeetingSpaceEventInner( Spacer(modifier = StdHorzSpacer) - CrossfadeIfEnabled(targetState = status, label = "MeetingSpaceStatus", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = status, label = "MeetingSpaceStatus") { when (it) { MeetingSpaceStatusTag.STATUS.LIVE -> { MeetingSpaceOpenFlag() @@ -296,7 +296,7 @@ fun RenderMeetingRoomEventInner( Spacer(modifier = StdHorzSpacer) - CrossfadeIfEnabled(targetState = status, label = "MeetingRoomStatus", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = status, label = "MeetingRoomStatus") { when (it) { StatusTag.STATUS.LIVE -> { media?.let { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt index 18a54e4545..421549ffb6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedView.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.feeds.FeedState +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -38,7 +39,6 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverLazyGridState import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverLazyListState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.viewmodels.FeedViewModel -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.FeedLoaded import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.feeds.StickToTopOnPrepend @@ -130,7 +130,6 @@ fun RenderFeedState( CrossfadeIfEnabled( targetState = feedState, animationSpec = tween(durationMillis = 100), - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> onEmpty() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt index 89fb4e824d..880e12de22 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedView.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -38,7 +39,6 @@ import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.StickToTopOnPrepend import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -61,7 +61,7 @@ fun UserFeedView( ) { val feedState by viewModel.feedContent.collectAsStateWithLifecycle() - CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100), accountViewModel = accountViewModel) { state -> + CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is UserFeedState.Empty -> { FeedEmpty { viewModel.invalidateData() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatFeedView.kt index f705b7d07d..ba50867242 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatFeedView.kt @@ -39,12 +39,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.feeds.FeedState import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.creators.draftTags.DraftTagState import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -145,7 +145,7 @@ fun RenderChatFeedView( ) { val feedState by feed.feedContent.collectAsStateWithLifecycle() - CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100), accountViewModel = accountViewModel) { state -> + CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is FeedState.Loading -> { LoadingFeed() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt index ebf74ad944..5aeb07a68e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/header/RoomNameOnlyDisplay.kt @@ -30,9 +30,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.model.User +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.richtext.CreateTextWithEmoji import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserInfo -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.UsernameDisplay import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser @@ -53,7 +53,7 @@ fun RoomNameOnlyDisplay( .subject .collectAsStateWithLifecycle() - CrossfadeIfEnabled(targetState = roomSubject, modifier, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = roomSubject, modifier = modifier) { if (!it.isNullOrBlank()) { DisplayRoomSubject(it, fontWeight) } else { @@ -120,7 +120,7 @@ fun RoomNameDisplay( .subject .collectAsStateWithLifecycle() - CrossfadeIfEnabled(targetState = roomSubject, modifier, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = roomSubject, modifier = modifier) { if (!it.isNullOrBlank()) { if (room.users.size > 1) { DisplayRoomSubject(it) @@ -187,7 +187,7 @@ fun ShortUsernameDisplay( userInfo?.info?.firstName() ?: baseUser.pubkeyDisplayHex() } - CrossfadeIfEnabled(targetState = firstName, modifier = weight, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = firstName, modifier = weight) { CreateTextWithEmoji( text = it, tags = userInfo?.tags, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/feed/ChatroomListFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/feed/ChatroomListFeedView.kt index 6dc6b60da4..eefcbb1888 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/feed/ChatroomListFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/feed/ChatroomListFeedView.kt @@ -46,6 +46,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.paging.PagingStatus import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.chats_history_proto_nip04 import com.vitorpamplona.amethyst.commons.resources.chats_history_proto_nip17 +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.DmHistoryLoadingCard import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError @@ -61,7 +62,6 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.feed.formatHistoryReachDate @@ -131,7 +131,6 @@ private fun CrossFadeState( CrossfadeIfEnabled( targetState = feedState, animationSpec = tween(durationMillis = 100), - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt index 323f3d091e..776dffceff 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/communities/list/CommunitiesScreen.kt @@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.feeds.FeedState import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.nip72ModCommunities.ui.NewCommunityButton +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -47,7 +48,6 @@ import com.vitorpamplona.amethyst.commons.ui.navigation.bottombars.FabBottomBarP import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar @@ -125,7 +125,6 @@ private fun RenderCommunitiesFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderCommunitiesFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> FeedEmpty(feedContentState::invalidateData) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt index 9f5d01fb0c..bb061315f3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt @@ -62,6 +62,7 @@ import com.vitorpamplona.amethyst.commons.resources.discover_follows import com.vitorpamplona.amethyst.commons.resources.discover_live_v2 import com.vitorpamplona.amethyst.commons.resources.discover_marketplace import com.vitorpamplona.amethyst.commons.resources.discover_reads +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -77,7 +78,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState import com.vitorpamplona.amethyst.ui.feeds.SaveableGridFeedContentState @@ -337,7 +337,6 @@ private fun RenderDiscoverFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderDiscoverFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { @@ -381,7 +380,6 @@ private fun RenderDiscoverFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderDiscoverFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/LiveActivityCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/LiveActivityCard.kt index 661f2826a1..75404c3494 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/LiveActivityCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/LiveActivityCard.kt @@ -52,11 +52,11 @@ import com.vitorpamplona.amethyst.commons.model.topNavFeeds.noteBased.author.Aut import com.vitorpamplona.amethyst.commons.model.topNavFeeds.noteBased.community.SingleCommunityTopNavFilter import com.vitorpamplona.amethyst.commons.model.topNavFeeds.noteBased.muted.MutedAuthorsByOutboxTopNavFilter import com.vitorpamplona.amethyst.commons.model.topNavFeeds.noteBased.muted.MutedAuthorsByProxyTopNavFilter +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.commons.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.DisplayAuthorBanner import com.vitorpamplona.amethyst.ui.note.Gallery import com.vitorpamplona.amethyst.ui.note.LoadLiveActivityChannel @@ -192,7 +192,7 @@ fun RenderLiveActivityThumb( } ?: run { DisplayAuthorBanner(baseNote, accountViewModel) } Box(Modifier.padding(10.dp)) { - CrossfadeIfEnabled(targetState = card.status, label = "RenderLiveActivityThumb", accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = card.status, label = "RenderLiveActivityThumb") { when (it) { StatusTag.STATUS.LIVE -> { val url = card.media diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/browse/BrowseEmojiSetsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/browse/BrowseEmojiSetsScreen.kt index 26bc97ea27..4aa7c25131 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/browse/BrowseEmojiSetsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/emojipacks/browse/BrowseEmojiSetsScreen.kt @@ -40,6 +40,7 @@ import com.vitorpamplona.amethyst.commons.feeds.FeedState import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.amethyst.commons.model.navigation.Route import com.vitorpamplona.amethyst.commons.nip30CustomEmojis.ui.EmojiPackCard +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -49,7 +50,6 @@ import com.vitorpamplona.amethyst.commons.ui.feeds.WatchLifecycleAndUpdateModel import com.vitorpamplona.amethyst.commons.ui.feeds.rememberForeverLazyGridState import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.StickToTopOnPrepend import com.vitorpamplona.amethyst.ui.feeds.WatchScrollToTop import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold @@ -122,7 +122,6 @@ private fun RenderBrowseEmojiSetsGrid( CrossfadeIfEnabled( targetState = feedState, animationSpec = tween(durationMillis = 100), - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocacheFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocacheFeedLoaded.kt index 7e5c171b8a..8038175f52 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocacheFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/geocaches/GeocacheFeedLoaded.kt @@ -60,6 +60,7 @@ import com.vitorpamplona.amethyst.commons.resources.geocache_sorted_by_distance import com.vitorpamplona.amethyst.commons.resources.geocache_sorted_by_recent import com.vitorpamplona.amethyst.commons.resources.geocache_use_my_location import com.vitorpamplona.amethyst.commons.service.georelay.GeoRelayDirectory +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding @@ -69,7 +70,6 @@ import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding import com.vitorpamplona.amethyst.service.location.LocationState -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.types.RenderGeocache import com.vitorpamplona.amethyst.ui.note.types.RenderGeocacheFoundLog import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -106,7 +106,6 @@ fun RenderGeocacheFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderGeocacheFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> GeocacheEmpty(kind) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt index e22aa4e734..b3fb2e01f5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt @@ -74,6 +74,7 @@ import com.vitorpamplona.amethyst.commons.resources.feed_is_empty import com.vitorpamplona.amethyst.commons.resources.home_tab_everything import com.vitorpamplona.amethyst.commons.resources.new_threads import com.vitorpamplona.amethyst.commons.resources.refresh +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.commons.ui.feeds.PagerStateKeys @@ -95,7 +96,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.commons.ui.theme.ThemeComparisonRow import com.vitorpamplona.amethyst.service.OnlineChecker import com.vitorpamplona.amethyst.service.location.LocationState -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.ChannelFeedContentState import com.vitorpamplona.amethyst.ui.feeds.ChannelFeedState import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState @@ -631,7 +631,6 @@ fun CrossfadeCheckIfVideoIsOnline( CrossfadeIfEnabled( targetState = online, label = "CheckIfUrlIsOnline", - accountViewModel = accountViewModel, ) { if (it) { whenOnline() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt index 0ebe7c9beb..52ca972185 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt @@ -71,6 +71,7 @@ import com.vitorpamplona.amethyst.commons.resources.nests_section_live_now import com.vitorpamplona.amethyst.commons.resources.nests_section_recently_ended import com.vitorpamplona.amethyst.commons.resources.nests_section_scheduled import com.vitorpamplona.amethyst.commons.resources.wallet_loading +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -86,7 +87,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.StdHorzSpacer import com.vitorpamplona.amethyst.commons.ui.theme.StdPadding import com.vitorpamplona.amethyst.commons.ui.theme.grayText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteAndMap -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.DisplayAuthorBanner @@ -622,7 +622,7 @@ fun RenderLiveSpacesThumb( } ?: run { DisplayAuthorBanner(baseNote, accountViewModel) } Box(Modifier.padding(10.dp)) { - CrossfadeIfEnabled(targetState = card.status, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = card.status) { when (it) { StatusTag.STATUS.LIVE -> { RenderLiveOrEndedFromPresence(baseNote, accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt index a9b8e69034..92baf2422b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/products/ProductsFeedLoaded.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.feeds.FeedContentState import com.vitorpamplona.amethyst.commons.feeds.FeedState +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed @@ -42,7 +43,6 @@ import com.vitorpamplona.amethyst.commons.ui.layouts.rememberFeedContentPadding import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose @@ -61,7 +61,6 @@ fun RenderProductsFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderProductsFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt index edd22dba6b..45e7ab52b9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/GalleryThumb.kt @@ -49,6 +49,7 @@ import com.vitorpamplona.amethyst.commons.richtext.MediaUrlImage import com.vitorpamplona.amethyst.commons.richtext.MediaUrlVideo import com.vitorpamplona.amethyst.commons.richtext.RichTextParser.Companion.isHlsMimeType import com.vitorpamplona.amethyst.commons.richtext.RichTextParser.Companion.isVideoUrl +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.LoadingAnimation import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes @@ -56,7 +57,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.commons.ui.theme.Size50Modifier import com.vitorpamplona.amethyst.service.playback.composable.mediaitem.isHlsMedia import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.components.AutoNonlazyGrid import com.vitorpamplona.amethyst.ui.components.DisplayBlurHash import com.vitorpamplona.amethyst.ui.components.SensitivityWarning @@ -261,7 +261,7 @@ fun UrlImageView( val imageModelUrl = artworkUri ?: content.url val canLoadAsImage = !isVideo || artworkUri != null || !isHlsMedia(content.url, content.mimeType) - CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(targetState = showImage.value, contentAlignment = Alignment.Center) { if (it && canLoadAsImage) { SubcomposeAsyncImage( model = imageModelUrl, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt index ef844bde65..3e6a73c0e3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/ProfileGalleryFeed.kt @@ -34,13 +34,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.feeds.FeedState +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedEmpty import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding import com.vitorpamplona.amethyst.commons.viewmodels.FeedViewModel -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.feeds.PrefetchLoadedFeedMedia import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -56,7 +56,6 @@ fun RenderGalleryFeed( targetState = feedState, animationSpec = tween(durationMillis = 100), label = "RenderDiscoverFeed", - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Empty -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/apps/DisplayAppRecommendations.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/apps/DisplayAppRecommendations.kt index 03b8992b80..8b15cee0da 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/apps/DisplayAppRecommendations.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/apps/DisplayAppRecommendations.kt @@ -50,9 +50,9 @@ import com.vitorpamplona.amethyst.commons.resources.profile_app_recommendations_ import com.vitorpamplona.amethyst.commons.resources.profile_apps_empty_hint import com.vitorpamplona.amethyst.commons.resources.profile_apps_header import com.vitorpamplona.amethyst.commons.resources.profile_apps_header_empty +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.stringRes -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable @@ -70,7 +70,6 @@ fun DisplayAppRecommendations( CrossfadeIfEnabled( targetState = feedState, animationSpec = tween(durationMillis = 100), - accountViewModel = accountViewModel, ) { state -> when (state) { is FeedState.Loaded -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt index 06684ee0cb..e3382c8646 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt @@ -154,6 +154,7 @@ import com.vitorpamplona.amethyst.commons.resources.topics import com.vitorpamplona.amethyst.commons.resources.used_by import com.vitorpamplona.amethyst.commons.resources.version import com.vitorpamplona.amethyst.commons.resources.yes +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.appendLink import com.vitorpamplona.amethyst.commons.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav @@ -172,7 +173,6 @@ import com.vitorpamplona.amethyst.commons.ui.theme.redColorOnSecondSurface import com.vitorpamplona.amethyst.commons.ui.theme.warningColor import com.vitorpamplona.amethyst.commons.util.timeDiffAgoShortish import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.note.UserPicture @@ -857,7 +857,7 @@ private fun DisplayOwnerInformation( nav: INav, ) { LoadUser(baseUserHex = userHex, accountViewModel) { loadedUser -> - CrossfadeIfEnabled(loadedUser, accountViewModel = accountViewModel) { + CrossfadeIfEnabled(loadedUser) { if (it != null) { Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { UserCompose( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedView.kt index eb23b5d0d1..99db311d0f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedView.kt @@ -38,12 +38,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.commons.resources.Res import com.vitorpamplona.amethyst.commons.resources.feed_is_empty import com.vitorpamplona.amethyst.commons.resources.refresh +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.feeds.FeedError import com.vitorpamplona.amethyst.commons.ui.feeds.LoadingFeed import com.vitorpamplona.amethyst.commons.ui.stringRes import com.vitorpamplona.amethyst.commons.ui.theme.DividerThickness import com.vitorpamplona.amethyst.commons.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @Composable @@ -56,7 +56,7 @@ fun StringFeedView( ) { val feedState by viewModel.feedContent.collectAsStateWithLifecycle() - CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100), accountViewModel = accountViewModel) { state -> + CrossfadeIfEnabled(targetState = feedState, animationSpec = tween(durationMillis = 100)) { state -> when (state) { is StringFeedState.Empty -> { StringFeedEmpty(pre, post) { viewModel.invalidateData() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 7fbbf5fed1..78ea2ecf9d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -44,6 +44,7 @@ import com.patrykandpatrick.vico.compose.common.VicoTheme import com.patrykandpatrick.vico.compose.common.VicoTheme.CandlestickCartesianLayerColors import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.commons.icons.symbols.ProvideAppIcons +import com.vitorpamplona.amethyst.commons.ui.components.LocalAnimationsEnabled import com.vitorpamplona.amethyst.commons.ui.components.LocalProfilePictureCache import com.vitorpamplona.amethyst.commons.ui.theme.AccentBlueDark import com.vitorpamplona.amethyst.commons.ui.theme.AccentBlueLight @@ -66,6 +67,7 @@ import com.vitorpamplona.amethyst.commons.ui.theme.isLight import com.vitorpamplona.amethyst.commons.ui.theme.transparentBackground import com.vitorpamplona.amethyst.commons.ui.theme.withFontFamily import com.vitorpamplona.amethyst.model.AccentColorType +import com.vitorpamplona.amethyst.model.FeatureSetType import com.vitorpamplona.amethyst.model.FontFamilyType import com.vitorpamplona.amethyst.model.FontSizeType import com.vitorpamplona.amethyst.model.ThemeType @@ -146,8 +148,9 @@ fun AmethystTheme(content: @Composable () -> Unit) { val accentColor by uiPrefs.accentColor.collectAsStateWithLifecycle() val fontFamily by uiPrefs.fontFamily.collectAsStateWithLifecycle() val fontSize by uiPrefs.fontSize.collectAsStateWithLifecycle() + val featureSet by uiPrefs.featureSet.collectAsStateWithLifecycle() - AmethystTheme(theme, accentColor, fontFamily, fontSize, content) + AmethystTheme(theme, accentColor, fontFamily, fontSize, animationsEnabled = featureSet != FeatureSetType.PERFORMANCE, content = content) } @Composable @@ -156,6 +159,7 @@ fun AmethystTheme( accentColor: AccentColorType = AccentColorType.PURPLE, fontFamily: FontFamilyType = FontFamilyType.SYSTEM, fontSize: FontSizeType = FontSizeType.NORMAL, + animationsEnabled: Boolean = true, content: @Composable () -> Unit, ) { // Deliberately no UiModeManager.nightMode write: changing the device night mode needs @@ -192,6 +196,8 @@ fun AmethystTheme( LocalDensity provides scaledDensity, // ImageLoaderSetup registers the avatar thumbnail cache and the local Blossom bridge. LocalProfilePictureCache provides true, + // Performance mode turns decorative animations (crossfades) off app-wide. + LocalAnimationsEnabled provides animationsEnabled, LocalTextStyle provides LocalTextStyle.current.merge(TextStyle(fontFamily = resolvedFontFamily)), content = content, ) diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt index c6c35db4d0..67b5ca343a 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/richtext/CustomEmojiRenderer.kt @@ -32,6 +32,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -48,6 +49,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.withLink import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -58,32 +60,20 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap /** - * Inline custom emoji: renders [text], replacing each `:shortcode:` present in - * [emojis] with its image. Universal to every front end, so it lives in the - * shared core rather than the platform seam. Falls back to plain [Text] when the - * text carries no known emoji. - * - * Cross-platform equivalent of Amethyst's `CreateTextWithEmoji`, built on quartz's - * [CustomEmoji.assembleAnnotatedList] + [InLineIconRenderer]. + * Inline custom emoji: renders [text], replacing each `:shortcode:` present in [emojis] with its + * image. Falls back to plain [Text] when the text carries no known emoji. Same path as + * [CreateTextWithEmoji], so rich text and names resolve emojis identically. */ @Composable fun RenderCustomEmoji( text: String, emojis: ImmutableMap, modifier: Modifier = Modifier, -) { - val renderable = remember(text, emojis) { CustomEmoji.assembleAnnotatedList(text, emojis) } - - if (renderable.isNullOrEmpty()) { - Text(text, modifier) - } else { - InLineIconRenderer(renderable, LocalTextStyle.current.toSpanStyle(), modifier = modifier) - } -} +) = CreateTextWithEmoji(text = text, emojis = emojis, modifier = modifier) /** * Renders an already-assembled list of [CustomEmoji.Renderable]s: text spans as - * text, image spans as inline [AsyncImage]s sized to ~1.1× the current font. + * text, image spans as inline [AsyncImage]s sized to ~1.1x the current font. */ @Composable fun InLineIconRenderer( @@ -93,18 +83,16 @@ fun InLineIconRenderer( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, modifier: Modifier = Modifier, + textAlign: TextAlign? = null, ) { - val placeholderSize = - remember(fontSize) { - if (fontSize == TextUnit.Unspecified) 22.sp else fontSize.times(1.1f) - } + val placeholderSize = remember(fontSize) { emojiPlaceholderSize(fontSize) } // Remembered like annotatedText below: rebuilding this map handed Text a // fresh unstable Map (plus a Placeholder and lambda per emoji) on every // recomposition of every name/note with a custom emoji. val inlineContent = remember(wordsInOrder, placeholderSize) { - wordsInOrder.buildInlineContent(placeholderSize) + wordsInOrder.buildInlineContent(placeholderSize, imagePadding = 0.dp) } val annotatedText = @@ -126,13 +114,19 @@ fun InLineIconRenderer( text = annotatedText, inlineContent = inlineContent, fontSize = fontSize, + textAlign = textAlign, maxLines = maxLines, overflow = overflow, modifier = modifier, ) } -private fun ImmutableList.buildInlineContent(placeholderSize: TextUnit): Map = +private fun emojiPlaceholderSize(fontSize: TextUnit): TextUnit = if (fontSize == TextUnit.Unspecified) 22.sp else fontSize.times(1.1f) + +private fun ImmutableList.buildInlineContent( + placeholderSize: TextUnit, + imagePadding: Dp, +): Map = mapIndexedNotNull { idx, value -> if (value is CustomEmoji.ImageUrlType) { "inlineContent$idx" to @@ -146,7 +140,7 @@ private fun ImmutableList.buildInlineContent(placeholder AsyncImage( model = value.url, contentDescription = null, - modifier = Modifier.fillMaxSize().padding(horizontal = 0.dp), + modifier = Modifier.fillMaxSize().padding(imagePadding), ) } } else { @@ -154,74 +148,73 @@ private fun ImmutableList.buildInlineContent(placeholder } }.associate { it.first to it.second } +/** + * Calls [onEmojiText] with [text] split into text and emoji spans when it resolves any custom emoji + * from the event's [tags], and [onRegularText] otherwise (and while the split is being assembled). + */ @Composable fun CustomEmojiChecker( text: String, tags: ImmutableListOfLists?, onRegularText: @Composable (String) -> Unit, onEmojiText: @Composable (ImmutableList) -> Unit, -) { - val mayContainEmoji by remember(text, tags) { - mutableStateOf(CustomEmoji.fastMightContainEmoji(text, tags?.lists)) - } - - if (mayContainEmoji) { - var emojiList by - remember(text, tags) { - mutableStateOf?>(null) - } - - LaunchedEffect(text, tags) { - val newEmojiList = CustomEmoji.assembleAnnotatedList(text, tags?.lists) - if (newEmojiList != null) { - emojiList = newEmojiList - } - } - - emojiList?.let { - onEmojiText(it) - } ?: run { - onRegularText(text) - } - } else { - onRegularText(text) - } -} +) = EmojiChecker( + text = text, + source = tags, + mightContainEmoji = { CustomEmoji.fastMightContainEmoji(text, tags?.lists) }, + assemble = { CustomEmoji.assembleAnnotatedList(text, tags?.lists) }, + onRegularText = onRegularText, + onEmojiText = onEmojiText, +) +/** [CustomEmojiChecker] for an already-resolved `shortcode -> url` map. */ @Composable fun CustomEmojiChecker( text: String, emojis: ImmutableMap, onRegularText: @Composable (String) -> Unit, onEmojiText: @Composable (ImmutableList) -> Unit, +) = EmojiChecker( + text = text, + source = emojis, + mightContainEmoji = { CustomEmoji.fastMightContainEmoji(text, emojis) }, + assemble = { CustomEmoji.assembleAnnotatedList(text, emojis) }, + onRegularText = onRegularText, + onEmojiText = onEmojiText, +) + +/** + * The one implementation behind both [CustomEmojiChecker]s. [source] is whatever the emoji come + * from (tags or a map); it keys the cached answers together with [text]. + */ +@Composable +private fun EmojiChecker( + text: String, + source: Any?, + mightContainEmoji: () -> Boolean, + assemble: () -> ImmutableList?, + onRegularText: @Composable (String) -> Unit, + onEmojiText: @Composable (ImmutableList) -> Unit, ) { - val mayContainEmoji by remember(text, emojis) { - mutableStateOf(CustomEmoji.fastMightContainEmoji(text, emojis)) - } + val mayContainEmoji = remember(text, source) { mightContainEmoji() } if (mayContainEmoji) { - var emojiList by - remember(text, emojis) { - mutableStateOf?>(null) - } + var emojiList by remember(text, source) { mutableStateOf?>(null) } - LaunchedEffect(text, emojis) { - val newEmojiList = CustomEmoji.assembleAnnotatedList(text, emojis) + LaunchedEffect(text, source) { + val newEmojiList = assemble() if (newEmojiList != null) { emojiList = newEmojiList } } - emojiList?.let { - onEmojiText(it) - } ?: run { - onRegularText(text) - } + emojiList?.let { onEmojiText(it) } ?: onRegularText(text) } else { onRegularText(text) } } +/** [text] with its custom emojis, resolved from the event's [tags]. */ @Composable fun CreateTextWithEmoji( text: String, @@ -233,43 +226,14 @@ fun CreateTextWithEmoji( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, modifier: Modifier = Modifier, -) { - CustomEmojiChecker( - text, - tags, - onEmojiText = { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - val style = - LocalTextStyle.current - .merge( - TextStyle( - color = textColor, - textAlign = TextAlign.Unspecified, - fontWeight = fontWeight, - fontSize = fontSize, - ), - ).toSpanStyle() - - InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) - }, - onRegularText = { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - Text( - text = it, - color = textColor, - textAlign = textAlign, - fontWeight = fontWeight, - fontSize = fontSize, - maxLines = maxLines, - overflow = overflow, - modifier = modifier, - ) - }, - ) -} +) = CustomEmojiChecker( + text = text, + tags = tags, + onRegularText = { PlainText(it, color, textAlign, fontWeight, fontSize, maxLines, overflow, modifier) }, + onEmojiText = { EmojiText(it, color, textAlign, fontWeight, fontSize, maxLines, overflow, modifier) }, +) +/** [text] with its custom emojis, resolved from an already-built `shortcode -> url` map. */ @Composable fun CreateTextWithEmoji( text: String, @@ -281,45 +245,70 @@ fun CreateTextWithEmoji( maxLines: Int = Int.MAX_VALUE, overflow: TextOverflow = TextOverflow.Clip, modifier: Modifier = Modifier, +) = CustomEmojiChecker( + text = text, + emojis = emojis, + onRegularText = { PlainText(it, color, textAlign, fontWeight, fontSize, maxLines, overflow, modifier) }, + onEmojiText = { EmojiText(it, color, textAlign, fontWeight, fontSize, maxLines, overflow, modifier) }, +) + +@Composable +private fun resolveTextColor(color: Color): Color = color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } + +@Composable +private fun PlainText( + text: String, + color: Color, + textAlign: TextAlign?, + fontWeight: FontWeight?, + fontSize: TextUnit, + maxLines: Int, + overflow: TextOverflow, + modifier: Modifier, ) { - val textColor = - color.takeOrElse { LocalTextStyle.current.color.takeOrElse { LocalContentColor.current } } - - CustomEmojiChecker( - text, - emojis, - onEmojiText = { - val currentStyle = LocalTextStyle.current - val style = - remember(currentStyle) { - currentStyle - .merge( - TextStyle( - color = textColor, - textAlign = TextAlign.Unspecified, - fontWeight = fontWeight, - fontSize = fontSize, - ), - ).toSpanStyle() - } - - InLineIconRenderer(it, style, fontSize, maxLines, overflow, modifier) - }, - onRegularText = { - Text( - text = it, - color = textColor, - textAlign = textAlign, - fontWeight = fontWeight, - fontSize = fontSize, - maxLines = maxLines, - overflow = overflow, - modifier = modifier, - ) - }, + Text( + text = text, + color = resolveTextColor(color), + textAlign = textAlign, + fontWeight = fontWeight, + fontSize = fontSize, + maxLines = maxLines, + overflow = overflow, + modifier = modifier, ) } +@Composable +private fun EmojiText( + words: ImmutableList, + color: Color, + textAlign: TextAlign?, + fontWeight: FontWeight?, + fontSize: TextUnit, + maxLines: Int, + overflow: TextOverflow, + modifier: Modifier, +) { + val textColor = resolveTextColor(color) + val currentStyle = LocalTextStyle.current + // Keyed on everything merged in: keying on the ambient style alone kept the first color / + // weight / size when the caller changed them (e.g. a row turning selected). + val style = + remember(currentStyle, textColor, fontWeight, fontSize) { + currentStyle + .merge( + TextStyle( + color = textColor, + fontWeight = fontWeight, + fontSize = fontSize, + ), + ).toSpanStyle() + } + + InLineIconRenderer(words, style, fontSize, maxLines, overflow, modifier, textAlign) +} + +/** A clickable [clickablePart] with its custom emojis resolved from [tags]. */ @Composable fun CreateClickableTextWithEmoji( clickablePart: String, @@ -328,34 +317,33 @@ fun CreateClickableTextWithEmoji( style: TextStyle, onClick: () -> Unit, ) { + val currentOnClick by rememberUpdatedState(onClick) CustomEmojiChecker( text = clickablePart, tags = tags, onRegularText = { - Text( - text = + val linkStyle = remember(style) { TextLinkStyles(style = style.toSpanStyle()) } + val annotated = + remember(it, linkStyle) { buildAnnotatedString { - withLink( - LinkAnnotation.Clickable( - "me", - TextLinkStyles(style = style.toSpanStyle()), - ) { - onClick() - }, - ) { - append(clickablePart) + withLink(LinkAnnotation.Clickable("me", linkStyle) { currentOnClick() }) { + append(it) } - }, - style = style, - maxLines = maxLines, - ) + } + } + Text(text = annotated, style = style, maxLines = maxLines) }, onEmojiText = { - ClickableInLineIconRenderer(it, maxLines, style.toSpanStyle(), onClick = onClick) + val spanStyle = remember(style) { style.toSpanStyle() } + ClickableInLineIconRenderer(it, maxLines, spanStyle, onClick = { currentOnClick() }) }, ) } +/** + * [InLineIconRenderer] where the whole run (text and emoji) is one link that calls [onClick], with + * an optional non-clickable [suffix]. + */ @Composable fun ClickableInLineIconRenderer( wordsInOrder: ImmutableList, @@ -365,58 +353,35 @@ fun ClickableInLineIconRenderer( nonClickableStype: SpanStyle? = null, onClick: () -> Unit, ) { - val placeholderSize = - remember(style) { - if (style.fontSize == TextUnit.Unspecified) 22.sp else style.fontSize.times(1.1f) + val currentOnClick by rememberUpdatedState(onClick) + val placeholderSize = remember(style.fontSize) { emojiPlaceholderSize(style.fontSize) } + + // Remembered for the same reason as InLineIconRenderer's: this renders every clickable name + // with emoji in a feed, and rebuilding both on each recomposition allocated a new map, + // placeholders, lambdas and string every time. + val inlineContent = + remember(wordsInOrder, placeholderSize) { + wordsInOrder.buildInlineContent(placeholderSize, imagePadding = 1.dp) } - val inlineContent = - wordsInOrder - .mapIndexedNotNull { idx, value -> - if (value is CustomEmoji.ImageUrlType) { - Pair( - "inlineContent$idx", - InlineTextContent( - Placeholder( - width = placeholderSize, - height = placeholderSize, - placeholderVerticalAlign = PlaceholderVerticalAlign.Center, - ), - ) { - AsyncImage( - model = value.url, - contentDescription = null, - modifier = - Modifier - .fillMaxSize() - .padding(1.dp), - ) - }, - ) - } else { - null - } - }.associate { it.first to it.second } - val annotatedText = - buildAnnotatedString { - wordsInOrder.forEachIndexed { idx, value -> - withLink( - LinkAnnotation.Clickable("link", TextLinkStyles(style)) { - onClick() - }, - ) { - if (value is CustomEmoji.TextType) { - append(value.text) - } else if (value is CustomEmoji.ImageUrlType) { - appendInlineContent("inlineContent$idx", "[icon]") + remember(wordsInOrder, style, suffix, nonClickableStype) { + val linkStyles = TextLinkStyles(style) + buildAnnotatedString { + wordsInOrder.forEachIndexed { idx, value -> + withLink(LinkAnnotation.Clickable("link", linkStyles) { currentOnClick() }) { + when (value) { + is CustomEmoji.TextType -> append(value.text) + is CustomEmoji.ImageUrlType -> appendInlineContent("inlineContent$idx", "[icon]") + else -> {} + } } } - } - if (suffix != null && nonClickableStype != null) { - withStyle(nonClickableStype) { - append(suffix) + if (suffix != null && nonClickableStype != null) { + withStyle(nonClickableStype) { + append(suffix) + } } } } diff --git a/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt index 636ba02479..c89f1cb3b6 100644 --- a/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt +++ b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt @@ -28,4 +28,9 @@ actual suspend fun Clipboard.setText(text: String) { UIPasteboard.generalPasteboard.string = text } -actual suspend fun Clipboard.getText(): String? = UIPasteboard.generalPasteboard.string +// hasStrings answers without reading the pasteboard, so it never shows the iOS 16+ "Allow Paste" +// prompt; only an actual read of text that is there can. +actual suspend fun Clipboard.getText(): String? { + val pasteboard = UIPasteboard.generalPasteboard + return if (pasteboard.hasStrings) pasteboard.string else null +}