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/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/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/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 72cb57115b..406c21e081 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -2076,7 +2076,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/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/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/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/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/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/UserFinderFilterAssemblerSubscription.kt index 9d67b5d442..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,39 +26,22 @@ 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 @SuppressLint("StateFlowValueCalledInComposition") @Composable fun UserFinderFilterAssemblerSubscription( user: User, accountViewModel: AccountViewModel, -) = UserFinderFilterAssemblerSubscription( +) = SharedUserFinderSubscription( user, accountViewModel.account, accountViewModel.dataSources().userFinder, ) -@Composable -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) -} - /** * 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/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/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/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/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/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/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/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/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/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 ea6b028609..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 @@ -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,34 +28,29 @@ 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 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 +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 +73,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 +392,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 +437,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/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/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/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 757b7e4244..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 @@ -37,13 +37,14 @@ 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.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 @@ -73,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, @@ -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/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/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/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 62b2ea9458..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 @@ -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 @@ -102,9 +103,12 @@ 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 +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 @@ -116,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 @@ -977,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/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/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/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/ZoomableContentView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ZoomableContentView.kt index 36fc70c585..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 @@ -104,11 +104,14 @@ 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.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 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 @@ -124,11 +127,9 @@ 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 -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 @@ -413,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, @@ -546,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, @@ -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/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/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/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/layouts/DisappearingScaffold.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt index 0911db8b8b..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 @@ -20,57 +20,17 @@ */ 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.commons.ui.layouts.LocalScreenLayout 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 +41,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/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 3c40b81e6f..e1c4b10801 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,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.layouts.LocalScreenLayout 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 +75,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 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/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/bottombars/KeyboardState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/bottombars/KeyboardState.kt index 7fa55a8744..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 @@ -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, @@ -36,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 @@ -48,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/drawer/AccountSwitchBottomSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/AccountSwitchBottomSheet.kt index 02f8689296..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 @@ -71,15 +71,15 @@ 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.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.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..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 @@ -116,8 +117,10 @@ 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.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 @@ -145,8 +148,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.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/navs/ImeSettler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/navs/ImeSettler.kt index 765537f572..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 @@ -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 @@ -44,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. * @@ -64,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/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 cc1d87909b..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 @@ -36,6 +36,8 @@ 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.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 @@ -45,8 +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.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/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/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/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 775488a32a..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,16 +72,21 @@ 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 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.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 @@ -104,10 +109,7 @@ 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.RobohashFallbackAsyncImage 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 0bcb164f32..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 @@ -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 @@ -56,7 +58,9 @@ 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 import com.vitorpamplona.amethyst.commons.ui.theme.Font14SP import com.vitorpamplona.amethyst.commons.ui.theme.NIP05IconSize @@ -69,11 +73,8 @@ 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.CreateTextWithEmoji 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 @@ -466,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/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 20c88f6e1c..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 @@ -85,6 +86,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 +119,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/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 055279c4e9..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,7 +152,9 @@ 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 import com.vitorpamplona.amethyst.commons.ui.note.ChangeReactionIcon import com.vitorpamplona.amethyst.commons.ui.note.CommentIcon @@ -167,6 +169,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 @@ -222,13 +225,10 @@ 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 -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 import com.vitorpamplona.amethyst.ui.note.elements.ShareOptionsBottomSheet import com.vitorpamplona.amethyst.ui.note.types.EditState @@ -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/RelayListRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/RelayListRow.kt index eb589ce309..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 @@ -55,6 +55,8 @@ 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.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 @@ -70,8 +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.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 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 70eeaa776c..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,10 +35,12 @@ 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 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..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,13 +72,16 @@ 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 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 +89,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/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 5cfa7ff7cd..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 @@ -21,47 +21,38 @@ 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 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 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.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 +516,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 +536,17 @@ fun InnerUserPicture( modifier: Modifier, accountViewModel: AccountViewModel, ) { - val myImageModifier = - remember { - modifier.size(size).clip(shape = CircleShape) - } - - RobohashFallbackAsyncImage( - robot = userHex, - model = userPicture, + UserAvatar( + userHex = userHex, + 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) }, - modifier = myImageModifier, - contentScale = ContentScale.Crop, loadProfilePicture = accountViewModel.settings.showProfilePictures(), loadRobohash = accountViewModel.settings.isNotPerformanceMode(), autoPlayGif = 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..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 @@ -23,30 +23,26 @@ 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.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 import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNote 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.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.utils.Log @@ -91,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) } } @@ -109,59 +105,22 @@ 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 - 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/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/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/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/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/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/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/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/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..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,16 +102,16 @@ 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 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 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 4522c97552..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 @@ -74,12 +75,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/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 8a5eb85fe9..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 @@ -76,6 +77,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 +95,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/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/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/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/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 4c221f750c..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 @@ -54,6 +55,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/LiveActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt index dc7b6653a6..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 @@ -48,10 +48,12 @@ 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 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 @@ -61,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 @@ -164,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 a521369e12..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 @@ -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 @@ -64,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 @@ -71,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 @@ -140,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() @@ -295,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/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 5b25f5ecc1..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,13 +42,14 @@ 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 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/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 236d426d32..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,12 +61,14 @@ 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 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 +79,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/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 67ff0aff42..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,14 +45,15 @@ 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 +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/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/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/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 a56295a56c..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 @@ -67,6 +68,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 +79,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/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 d68ba9f721..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,7 +68,9 @@ 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 import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText import com.vitorpamplona.amethyst.commons.util.toShortDisplay @@ -76,7 +78,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..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,12 +61,13 @@ 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 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/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. */ 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..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,8 @@ 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 import com.vitorpamplona.amethyst.commons.ui.theme.Size35dp @@ -70,7 +72,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/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/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/badges/profile/ProfileBadgesScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/badges/profile/ProfileBadgesScreen.kt index 5b09074883..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,17 +52,18 @@ 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 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/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/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/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/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..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 @@ -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.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.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 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 c12b8ea124..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 @@ -42,12 +42,12 @@ 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.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.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 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/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/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/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/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/ChatReactionChips.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatReactionChips.kt index eb2857c4b8..cee05e166e 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/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/GeohashChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/geohashChat/GeohashChatScreen.kt index ce9df281b9..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 @@ -64,13 +64,13 @@ 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.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.components.RobohashFallbackAsyncImage -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/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/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/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/marmotGroup/MarmotGroupInfoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupInfoScreen.kt index 405e8ca763..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,8 @@ 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 import com.vitorpamplona.amethyst.commons.ui.pluralStringRes @@ -137,8 +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.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/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/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/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..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.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 @@ -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/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/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/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/concord/ConcordHomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/concord/ConcordHomeScreen.kt index 8df0607a89..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 @@ -67,15 +67,15 @@ 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.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 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 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 eec6288437..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 @@ -74,13 +74,13 @@ 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.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.RobohashFallbackAsyncImage -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/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/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/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/ephemChat/metadata/NewEphemeralChatScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/ephemChat/metadata/NewEphemeralChatScreen.kt index e7a86bb697..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 @@ -47,6 +48,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 +57,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 ae56c76d54..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 @@ -50,7 +50,9 @@ 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.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 @@ -58,9 +60,7 @@ 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.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/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/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/nip28PublicChat/metadata/ChannelMetadataScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/publicChannels/nip28PublicChat/metadata/ChannelMetadataScreen.kt index 44e6fa96a2..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 @@ -60,6 +61,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 +74,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/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 43ccd79d8d..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 @@ -94,6 +95,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 +105,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..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 @@ -69,10 +70,12 @@ 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 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 @@ -83,12 +86,10 @@ 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 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/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/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/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/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 9cb1c9eef2..0e7c2f5e3b 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 @@ -59,6 +59,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 @@ -99,6 +100,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 @@ -117,7 +119,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/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/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/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 f1b33cc788..637f91bb53 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/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..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 @@ -43,14 +44,13 @@ 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 -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 @@ -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/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/DiscoverScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/DiscoverScreen.kt index 6ded9230bd..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 @@ -71,18 +72,17 @@ 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 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 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 @@ -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/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/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/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/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/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/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/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/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/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/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/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/HomeScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/HomeScreen.kt index e4b49b4caf..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 @@ -82,6 +83,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 @@ -94,14 +96,12 @@ 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 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 @@ -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/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/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/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/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/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/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/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/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/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/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/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/NestsFeedLoaded.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/NestsFeedLoaded.kt index 2554971131..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 @@ -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 @@ -70,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 @@ -85,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 @@ -621,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/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/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/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 f4057e5f87..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,18 +64,19 @@ 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 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/profile/header/badges/DisplayBadges.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/badges/DisplayBadges.kt index 40a1adaf7a..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,18 +64,19 @@ 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 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/profile/payment/SendPaymentContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/payment/SendPaymentContent.kt index 94455ed169..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.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/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/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 c733ea070f..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 @@ -53,19 +53,19 @@ 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.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.components.RobohashFallbackAsyncImage -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/redirect/LoadRedirectScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/redirect/LoadRedirectScreen.kt index 5c25c80a54..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,8 @@ 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 import com.vitorpamplona.amethyst.commons.resources.looking_for_event_title @@ -44,7 +46,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/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/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/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/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/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/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/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/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/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/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/screen/loggedIn/settings/cordn/CordnCoordinatorsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/cordn/CordnCoordinatorsScreen.kt index 0c9852fe31..65d0424184 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/cordn/CordnCoordinatorsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/cordn/CordnCoordinatorsScreen.kt @@ -63,11 +63,11 @@ import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_d import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_manual import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_section_yours import com.vitorpamplona.amethyst.commons.resources.cordn_coordinators_title +import com.vitorpamplona.amethyst.commons.ui.components.CrossfadeIfEnabled import com.vitorpamplona.amethyst.commons.ui.components.EmptyState import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav import com.vitorpamplona.amethyst.commons.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.model.cordn.CordnRuntime -import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsSection @@ -360,7 +360,6 @@ private fun DiscoverCoordinators( CrossfadeIfEnabled( targetState = result, label = "cordn-discovery", - accountViewModel = accountViewModel, ) { found -> Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { if (found == null) return@Column 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 d42f164b96..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.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..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.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/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/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/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/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/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/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/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/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/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..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,8 @@ 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 import com.vitorpamplona.amethyst.commons.ui.theme.AccentGreenDark @@ -65,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 @@ -145,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 @@ -155,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 @@ -189,6 +194,10 @@ fun AmethystTheme( ProvideAppIcons { CompositionLocalProvider( 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/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt b/amethyst/src/test/java/com/vitorpamplona/amethyst/calendar/CalendarsViewModelFlowTest.kt index e7bb035e20..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,16 +34,17 @@ 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.withContext +import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeoutOrNull -import kotlinx.coroutines.yield import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before @@ -79,24 +81,6 @@ class CalendarsViewModelFlowTest { @After fun tearDown() { - // Unconfined makes cancellation finish synchronously ON THE CANCELLING THREAD, which is - // what the class comment above describes — but it does not cover the upstreams. Every - // derived flow is `flowOn(Dispatchers.Default)`, so those run on the pool, and a cancelled - // one completes on a Default worker and resumes its Main-side parent from there. If - // `resetMain()` already ran, that resume throws `IllegalStateException: Dispatchers.Main - // was accessed when the platform dispatcher was absent` on a background thread. - // - // Nothing here fails when it happens. The next test in the JVM to call `runTest` does, - // with `UncaughtExceptionsBeforeTest` — for a long time that was - // `Nip46ConsentInfoBuilderTest`, which is innocent and passes in isolation. - // - // So: drain the pool while Main is still valid. Same mitigation as the sibling suite - // `CalendarsViewModelTest`, and the same caveat — there is no public handle on - // viewModelScope's Job to join and a pool has no "everything queued has run" barrier, so - // this closes the window rather than removing it. The real fix is for the ViewModel to - // take its dispatcher as a parameter. - runBlocking { withContext(Dispatchers.Default) { yield() } } - Dispatchers.resetMain() } @@ -157,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 b47703a920..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,16 +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.withContext -import kotlinx.coroutines.yield +import kotlinx.coroutines.withTimeout import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNull @@ -61,34 +64,24 @@ class CalendarsViewModelTest { store = ViewModelStore() } + private val scopes = mutableListOf() + @After fun tearDown() { store.clear() - - // `clear()` CANCELS viewModelScope; it does not WAIT for it, and the two are not the same - // thing here. Every derived flow is `flowOn(Dispatchers.Default).stateIn(viewModelScope, - // ...)`: the upstream runs on the Default pool while stateIn's sharing coroutine lives on - // Main. A cancelled upstream therefore finishes on a Default worker and resumes its parent - // onto Main — and if `resetMain()` has already run, that resume throws - // `IllegalStateException: Dispatchers.Main was accessed when the platform dispatcher was - // absent` on a background thread. - // - // Nothing in THIS suite fails when that happens. The next test in the JVM to call - // `runTest` does, with `UncaughtExceptionsBeforeTest` — for a long time that was - // `Nip46ConsentInfoBuilderTest`, which is innocent and passes in isolation, which is what - // made it so slow to find. - // - // So: drain the pool while Main is still valid. This is a mitigation, not a proof — there - // is no public handle on viewModelScope's Job to join, and a thread pool has no - // "everything queued has run" barrier. It closes the window rather than removing it. The - // real fix is for the ViewModel to take its dispatcher as a parameter, at which point the - // test supplies one it can drain deterministically. - runBlocking { withContext(Dispatchers.Default) { yield() } } - + // 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() { @@ -172,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 + } } 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/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/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/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..7bdde9baf2 --- /dev/null +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/richtext/AnimatedMediaUrl.kt @@ -0,0 +1,36 @@ +/* + * 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 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) + +/** 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/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/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/build.gradle.kts b/commonsUI/build.gradle.kts index 3efa0ca030..4d54405f96 100644 --- a/commonsUI/build.gradle.kts +++ b/commonsUI/build.gradle.kts @@ -191,6 +191,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) } } @@ -215,6 +217,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/AnimatedImageAutoPlay.android.kt b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.kt new file mode 100644 index 0000000000..4205e6d09a --- /dev/null +++ b/commonsUI/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.android.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.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 + +@Composable +internal actual fun AnimatedImageAutoPlay( + image: Image?, + autoPlay: Boolean, +) { + val resources = LocalContext.current.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) { + if (autoPlay) drawable.start() else drawable.stop() + } + } +} 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/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/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/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) +} 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/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/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/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/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/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/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/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..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 @@ -24,70 +24,75 @@ 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.rememberUpdatedState +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.Dp 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 /** - * 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( wordsInOrder: ImmutableList, style: SpanStyle, fontSize: TextUnit = TextUnit.Unspecified, + 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 = @@ -109,11 +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 @@ -127,10 +140,255 @@ private fun ImmutableList.buildInlineContent(placeholder AsyncImage( model = value.url, contentDescription = null, - modifier = Modifier.fillMaxSize().padding(horizontal = 0.dp), + modifier = Modifier.fillMaxSize().padding(imagePadding), ) } } else { null } }.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, +) = 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 = remember(text, source) { mightContainEmoji() } + + if (mayContainEmoji) { + var emojiList by remember(text, source) { mutableStateOf?>(null) } + + LaunchedEffect(text, source) { + val newEmojiList = assemble() + if (newEmojiList != null) { + emojiList = newEmojiList + } + } + + 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, + 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 = 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, + 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, +) = 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, +) { + 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, + maxLines: Int = Int.MAX_VALUE, + tags: ImmutableListOfLists?, + style: TextStyle, + onClick: () -> Unit, +) { + val currentOnClick by rememberUpdatedState(onClick) + CustomEmojiChecker( + text = clickablePart, + tags = tags, + onRegularText = { + val linkStyle = remember(style) { TextLinkStyles(style = style.toSpanStyle()) } + val annotated = + remember(it, linkStyle) { + buildAnnotatedString { + withLink(LinkAnnotation.Clickable("me", linkStyle) { currentOnClick() }) { + append(it) + } + } + } + Text(text = annotated, style = style, maxLines = maxLines) + }, + onEmojiText = { + 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, + maxLines: Int = Int.MAX_VALUE, + style: SpanStyle, + suffix: String? = null, + nonClickableStype: SpanStyle? = null, + onClick: () -> Unit, +) { + 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 annotatedText = + 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) + } + } + } + } + + Text( + text = annotatedText, + inlineContent = inlineContent, + maxLines = maxLines, + ) +} 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/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..c89f1cb3b6 --- /dev/null +++ b/commonsUI/src/iosMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/util/ClipboardExt.ios.kt @@ -0,0 +1,36 @@ +/* + * 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 +} + +// 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 +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt similarity index 57% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt rename to commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt index 9470b4e89d..bd9f3ae050 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/CrossfadeIfEnabled.kt +++ b/commonsUI/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AvatarImage.jvmAndroid.kt @@ -18,31 +18,30 @@ * 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 +package com.vitorpamplona.amethyst.commons.ui.components -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 +import androidx.compose.ui.layout.ContentScale @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, -) +internal actual fun AvatarImage( + userHex: String, + pictureUrl: String?, + contentDescription: String?, + modifier: Modifier, + loadProfilePicture: Boolean, + loadRobohash: Boolean, + autoPlayGif: Boolean, +) { + RobohashFallbackAsyncImage( + robot = userHex, + model = pictureUrl, + contentDescription = contentDescription, + modifier = modifier, + contentScale = ContentScale.Crop, + loadProfilePicture = loadProfilePicture, + loadRobohash = loadRobohash, + autoPlayGif = autoPlayGif, + ) +} 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 80% 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..ff55834b65 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,23 @@ 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 decodes only the first frame, so there [autoPlay] has + * no effect. + */ +@Composable +internal expect fun AnimatedImageAutoPlay( + image: CoilImage?, + autoPlay: Boolean, +) @Composable fun RobohashAsyncImage( @@ -93,6 +101,7 @@ fun RobohashFallbackAsyncImage( loadRobohash: Boolean, autoPlayGif: Boolean = true, ) { + val useThumbnailCache = LocalProfilePictureCache.current if (model != null && loadProfilePicture && isAnimatedMediaUrl(model)) { GifProfilePicture( userHex = robot, @@ -115,14 +124,14 @@ fun RobohashFallbackAsyncImage( ) } - val resources = LocalContext.current.resources 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 @@ -136,14 +145,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 +196,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,20 +206,27 @@ fun GifProfilePicture( ) } - val context = LocalContext.current + 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) { @@ -229,14 +237,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/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..27474a2773 --- /dev/null +++ b/commonsUI/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/AnimatedImageAutoPlay.jvm.kt @@ -0,0 +1,33 @@ +/* + * 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, +) { + // 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/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/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) {} 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 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) { {