refactor(ui): CompositionLocal for scaffold padding + scaffold hygiene
Follow-up polish to the disappearing-scaffold migration addressing
the review items:
1. Replace the `scaffoldPadding: PaddingValues` sprawl across ~15 feed
entry points with a single `LocalDisappearingScaffoldPadding`
CompositionLocal published by the scaffold, plus a
`rememberFeedContentPadding(inner)` helper that merges it with the
list's own baseline padding. The contract becomes implicit at the
call site ("inner LazyColumn uses rememberFeedContentPadding") and
there's no more optional parameter for a future dev to forget.
`rememberMergedPadding` stays available for manual use.
2. Fix the stale-closure bug in `DisappearingScaffold`: the NSC is
`remember`'d and keeps its captured `canScroll` lambda across
recompositions, but the lambda was reading `allowBarHide`,
`isActive`, and `accountViewModel` by closure — so later parameter
updates wouldn't be visible. Wrapped them in `rememberUpdatedState`
so the NSC's `canScroll` always sees current values.
3. Gate `ResetBarsOnResume` and the `Modifier.nestedScroll(connection)`
install on `allowBarHide`. Chat detail screens (pinned chrome) no
longer wire up a lifecycle observer or dispatch scroll events
through the NSC for bars that never move.
4. Unify header-slot naming: `SearchScreen.DisplaySearchResults` now
uses `headerContent` to match `CardFeedView.RenderCardFeed`.
5. Add `DisappearingBarNestedScrollTest` covering:
- onPostScroll never consumes
- hide/reveal deltas applied to both bars
- per-bar clamping at their independent limits
- consumed + available sum (so overscroll works)
- canScroll=false freezes the bars
- reverseLayout inverts the delta sign
- setting a smaller heightLimit clamps the current offset
- onPostFling returns Velocity.Zero to swallow phantom velocity
All 41 consumer / shared-helper files touched to remove the now-unused
`scaffoldPadding` parameter, replaced with `rememberFeedContentPadding(
FeedPadding)` at the innermost LazyColumn / LazyVerticalGrid. Behaviour
is unchanged; API surface is smaller.
https://claude.ai/code/session_01M3Bj24jLc9aVhMuvn55jXa
This commit is contained in:
@@ -21,14 +21,12 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.feeds
|
package com.vitorpamplona.amethyst.ui.feeds
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.grid.LazyGridState
|
import androidx.compose.foundation.lazy.grid.LazyGridState
|
||||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
@@ -41,13 +39,12 @@ fun RefresheableFeedContentStateView(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
enablePullRefresh: Boolean = true,
|
enablePullRefresh: Boolean = true,
|
||||||
scrollStateKey: String? = null,
|
scrollStateKey: String? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
RefresheableBox(feedContentState, enablePullRefresh) {
|
RefresheableBox(feedContentState, enablePullRefresh) {
|
||||||
SaveableFeedContentState(feedContentState, scrollStateKey) { listState ->
|
SaveableFeedContentState(feedContentState, scrollStateKey) { listState ->
|
||||||
RenderFeedContentState(feedContentState, accountViewModel, listState, nav, routeForLastRead, scaffoldPadding)
|
RenderFeedContentState(feedContentState, accountViewModel, listState, nav, routeForLastRead)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,8 +92,7 @@ fun RenderFeedContentState(
|
|||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
onLoaded: @Composable (FeedState.Loaded) -> Unit = { FeedLoaded(it, listState, routeForLastRead, accountViewModel, nav) },
|
||||||
onLoaded: @Composable (FeedState.Loaded) -> Unit = { FeedLoaded(it, listState, routeForLastRead, accountViewModel, nav, scaffoldPadding) },
|
|
||||||
onEmpty: @Composable () -> Unit = { FeedEmpty(feedContentState::invalidateData) },
|
onEmpty: @Composable () -> Unit = { FeedEmpty(feedContentState::invalidateData) },
|
||||||
onError: @Composable (String) -> Unit = { FeedError(it, feedContentState::invalidateData) },
|
onError: @Composable (String) -> Unit = { FeedError(it, feedContentState::invalidateData) },
|
||||||
onLoading: @Composable () -> Unit = { LoadingFeed() },
|
onLoading: @Composable () -> Unit = { LoadingFeed() },
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.feeds
|
package com.vitorpamplona.amethyst.ui.feeds
|
||||||
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -31,10 +30,9 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -49,12 +47,11 @@ fun FeedLoaded(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+27
-12
@@ -26,9 +26,12 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
@@ -59,27 +62,37 @@ fun DisappearingScaffold(
|
|||||||
) {
|
) {
|
||||||
val state = rememberDisappearingBarState()
|
val state = rememberDisappearingBarState()
|
||||||
|
|
||||||
val canScroll = {
|
// Hold the latest values in state so the NSC's captured lambda stays fresh across
|
||||||
allowBarHide && isActive() && accountViewModel.settings.isImmersiveScrollingActive()
|
// recompositions without rebuilding the NSC itself.
|
||||||
}
|
val latestIsActive by rememberUpdatedState(isActive)
|
||||||
|
val latestAllowBarHide by rememberUpdatedState(allowBarHide)
|
||||||
|
val latestAccountViewModel by rememberUpdatedState(accountViewModel)
|
||||||
|
|
||||||
val connection =
|
val connection =
|
||||||
remember(state, isInvertedLayout) {
|
remember(state, isInvertedLayout) {
|
||||||
DisappearingBarNestedScroll(
|
DisappearingBarNestedScroll(
|
||||||
state = state,
|
state = state,
|
||||||
canScroll = canScroll,
|
canScroll = {
|
||||||
|
latestAllowBarHide &&
|
||||||
|
latestIsActive() &&
|
||||||
|
latestAccountViewModel.settings.isImmersiveScrollingActive()
|
||||||
|
},
|
||||||
reverseLayout = isInvertedLayout,
|
reverseLayout = isInvertedLayout,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetBarsOnResume(state)
|
// Only wire the lifecycle observer when the scaffold actually moves its bars.
|
||||||
|
if (allowBarHide) ResetBarsOnResume(state)
|
||||||
|
|
||||||
SubcomposeLayout(
|
// When bars are pinned, skip attaching the nested-scroll connection entirely.
|
||||||
modifier =
|
val rootModifier =
|
||||||
Modifier
|
if (allowBarHide) {
|
||||||
.imePadding()
|
Modifier.imePadding().nestedScroll(connection)
|
||||||
.nestedScroll(connection),
|
} else {
|
||||||
) { constraints ->
|
Modifier.imePadding()
|
||||||
|
}
|
||||||
|
|
||||||
|
SubcomposeLayout(modifier = rootModifier) { constraints ->
|
||||||
val layoutWidth = constraints.maxWidth
|
val layoutWidth = constraints.maxWidth
|
||||||
val layoutHeight = constraints.maxHeight
|
val layoutHeight = constraints.maxHeight
|
||||||
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
|
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
|
||||||
@@ -127,7 +140,9 @@ fun DisappearingScaffold(
|
|||||||
|
|
||||||
val contentPlaceable =
|
val contentPlaceable =
|
||||||
subcompose(DisappearingSlot.Content) {
|
subcompose(DisappearingSlot.Content) {
|
||||||
mainContent(contentPadding)
|
CompositionLocalProvider(LocalDisappearingScaffoldPadding provides contentPadding) {
|
||||||
|
mainContent(contentPadding)
|
||||||
|
}
|
||||||
}.firstOrNull()?.measure(
|
}.firstOrNull()?.measure(
|
||||||
Constraints.fixed(layoutWidth, layoutHeight),
|
Constraints.fixed(layoutWidth, layoutHeight),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,14 +24,24 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||||||
import androidx.compose.foundation.layout.calculateEndPadding
|
import androidx.compose.foundation.layout.calculateEndPadding
|
||||||
import androidx.compose.foundation.layout.calculateStartPadding
|
import androidx.compose.foundation.layout.calculateStartPadding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The padding the surrounding [DisappearingScaffold] would like its inner scrollable
|
||||||
|
* to apply as `contentPadding`. Defaults to [PaddingValues] of 0 when no scaffold is
|
||||||
|
* providing it, so feed composables used outside a scaffold behave as before.
|
||||||
|
*
|
||||||
|
* Read it via [rememberFeedContentPadding] to merge with the list's own
|
||||||
|
* baseline padding (typically `FeedPadding`).
|
||||||
|
*/
|
||||||
|
val LocalDisappearingScaffoldPadding = compositionLocalOf { PaddingValues(0.dp) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges two [PaddingValues] component-wise, resolving start/end against the current
|
* Merges two [PaddingValues] component-wise, resolving start/end against the current
|
||||||
* [LocalLayoutDirection]. Used to combine the scaffold's bar padding with an inner
|
* [LocalLayoutDirection].
|
||||||
* list's own padding (e.g. FeedPadding) into a single `contentPadding` value for a
|
|
||||||
* LazyColumn / LazyVerticalGrid.
|
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun rememberMergedPadding(
|
fun rememberMergedPadding(
|
||||||
@@ -48,3 +58,10 @@ fun rememberMergedPadding(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience for inner LazyColumns/LazyVerticalGrids inside a [DisappearingScaffold]:
|
||||||
|
* merges the scaffold's reserved space with the list's own baseline padding.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun rememberFeedContentPadding(inner: PaddingValues): PaddingValues = rememberMergedPadding(LocalDisappearingScaffoldPadding.current, inner)
|
||||||
|
|||||||
@@ -21,14 +21,12 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.grid.LazyGridState
|
import androidx.compose.foundation.lazy.grid.LazyGridState
|
||||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
@@ -50,13 +48,12 @@ fun RefresheableFeedView(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
enablePullRefresh: Boolean = true,
|
enablePullRefresh: Boolean = true,
|
||||||
scrollStateKey: String? = null,
|
scrollStateKey: String? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
RefresheableBox(viewModel, enablePullRefresh) {
|
RefresheableBox(viewModel, enablePullRefresh) {
|
||||||
SaveableFeedState(viewModel.feedState, scrollStateKey) { listState ->
|
SaveableFeedState(viewModel.feedState, scrollStateKey) { listState ->
|
||||||
RenderFeedState(viewModel, accountViewModel, listState, nav, routeForLastRead, scaffoldPadding)
|
RenderFeedState(viewModel, accountViewModel, listState, nav, routeForLastRead)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,9 +101,8 @@ fun RenderFeedState(
|
|||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
onLoaded: @Composable (FeedState.Loaded) -> Unit = {
|
onLoaded: @Composable (FeedState.Loaded) -> Unit = {
|
||||||
FeedLoaded(it, listState, routeForLastRead, accountViewModel, nav, scaffoldPadding)
|
FeedLoaded(it, listState, routeForLastRead, accountViewModel, nav)
|
||||||
},
|
},
|
||||||
onEmpty: @Composable () -> Unit = { FeedEmpty { viewModel.invalidateData() } },
|
onEmpty: @Composable () -> Unit = { FeedEmpty { viewModel.invalidateData() } },
|
||||||
onError: @Composable (String) -> Unit = { FeedError(it) { viewModel.invalidateData() } },
|
onError: @Composable (String) -> Unit = { FeedError(it) { viewModel.invalidateData() } },
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen
|
package com.vitorpamplona.amethyst.ui.screen
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
@@ -30,14 +29,13 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserCompose
|
import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -50,15 +48,13 @@ fun RefreshingFeedUserFeedView(
|
|||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
enablePullRefresh: Boolean = true,
|
enablePullRefresh: Boolean = true,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
) {
|
) {
|
||||||
RefresheableBox(viewModel, enablePullRefresh) { UserFeedView(viewModel, scaffoldPadding, accountViewModel, nav) }
|
RefresheableBox(viewModel, enablePullRefresh) { UserFeedView(viewModel, accountViewModel, nav) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserFeedView(
|
fun UserFeedView(
|
||||||
viewModel: UserFeedViewModel,
|
viewModel: UserFeedViewModel,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -75,7 +71,7 @@ fun UserFeedView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is UserFeedState.Loaded -> {
|
is UserFeedState.Loaded -> {
|
||||||
FeedLoaded(state, scaffoldPadding, accountViewModel, nav)
|
FeedLoaded(state, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
is UserFeedState.Loading -> {
|
is UserFeedState.Loading -> {
|
||||||
@@ -88,7 +84,6 @@ fun UserFeedView(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun FeedLoaded(
|
private fun FeedLoaded(
|
||||||
state: UserFeedState.Loaded,
|
state: UserFeedState.Loaded,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -97,7 +92,7 @@ private fun FeedLoaded(
|
|||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items, key = { _, item -> item.pubkeyHex }) { _, item ->
|
itemsIndexed(items, key = { _, item -> item.pubkeyHex }) { _, item ->
|
||||||
|
|||||||
+2
-5
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.articles
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.articles
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -30,10 +29,9 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose
|
||||||
@@ -45,14 +43,13 @@ import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent
|
|||||||
fun ArticlesFeedLoaded(
|
fun ArticlesFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+1
-2
@@ -77,7 +77,7 @@ fun ArticlesScreen(
|
|||||||
NewArticleButton(nav)
|
NewArticleButton(nav)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
RefresheableBox(articlesFeedContentState, true) {
|
RefresheableBox(articlesFeedContentState, true) {
|
||||||
SaveableFeedContentState(articlesFeedContentState, scrollStateKey = ScrollStateKeys.ARTICLES_SCREEN) { listState ->
|
SaveableFeedContentState(articlesFeedContentState, scrollStateKey = ScrollStateKeys.ARTICLES_SCREEN) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -90,7 +90,6 @@ fun ArticlesScreen(
|
|||||||
ArticlesFeedLoaded(
|
ArticlesFeedLoaded(
|
||||||
loaded = loaded,
|
loaded = loaded,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-2
@@ -125,7 +125,6 @@ private fun RenderBookmarkScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
privateFeedViewModel,
|
privateFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -135,7 +134,6 @@ private fun RenderBookmarkScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
publicFeedViewModel,
|
publicFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-2
@@ -159,7 +159,6 @@ private fun RenderOldBookmarkScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
privateFeedViewModel,
|
privateFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -169,7 +168,6 @@ private fun RenderOldBookmarkScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
publicFeedViewModel,
|
publicFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-9
@@ -21,7 +21,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -31,7 +30,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
@@ -41,7 +39,7 @@ import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState
|
import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChatroomHeaderCompose
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChatroomHeaderCompose
|
||||||
@@ -52,13 +50,12 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
|||||||
fun ChatroomListFeedView(
|
fun ChatroomListFeedView(
|
||||||
feedContentState: FeedContentState,
|
feedContentState: FeedContentState,
|
||||||
scrollStateKey: String,
|
scrollStateKey: String,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
RefresheableBox(feedContentState, true) {
|
RefresheableBox(feedContentState, true) {
|
||||||
SaveableFeedContentState(feedContentState, scrollStateKey) { listState ->
|
SaveableFeedContentState(feedContentState, scrollStateKey) { listState ->
|
||||||
CrossFadeState(feedContentState, listState, scaffoldPadding, accountViewModel, nav)
|
CrossFadeState(feedContentState, listState, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +64,6 @@ fun ChatroomListFeedView(
|
|||||||
private fun CrossFadeState(
|
private fun CrossFadeState(
|
||||||
feedContentState: FeedContentState,
|
feedContentState: FeedContentState,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -88,7 +84,7 @@ private fun CrossFadeState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is FeedState.Loaded -> {
|
is FeedState.Loaded -> {
|
||||||
FeedLoaded(state, listState, scaffoldPadding, accountViewModel, nav)
|
FeedLoaded(state, listState, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedState.Loading -> {
|
FeedState.Loading -> {
|
||||||
@@ -102,14 +98,13 @@ private fun CrossFadeState(
|
|||||||
private fun FeedLoaded(
|
private fun FeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
-3
@@ -21,7 +21,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.feed
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
@@ -122,7 +121,6 @@ fun MessagesTabHeader(
|
|||||||
fun MessagesPager(
|
fun MessagesPager(
|
||||||
pagerState: PagerState,
|
pagerState: PagerState,
|
||||||
tabs: List<MessagesTabItem>,
|
tabs: List<MessagesTabItem>,
|
||||||
paddingValues: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -138,7 +136,6 @@ fun MessagesPager(
|
|||||||
ChatroomListFeedView(
|
ChatroomListFeedView(
|
||||||
feedContentState = tabs[page].feedContentState,
|
feedContentState = tabs[page].feedContentState,
|
||||||
scrollStateKey = tabs[page].scrollStateKey,
|
scrollStateKey = tabs[page].scrollStateKey,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -98,7 +98,6 @@ fun MessagesSinglePane(
|
|||||||
MessagesPager(
|
MessagesPager(
|
||||||
pagerState,
|
pagerState,
|
||||||
tabs,
|
tabs,
|
||||||
it,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-4
@@ -21,13 +21,11 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.twopane
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
||||||
@@ -44,7 +42,6 @@ import kotlinx.collections.immutable.persistentListOf
|
|||||||
fun ChatroomList(
|
fun ChatroomList(
|
||||||
knownFeedContentState: FeedContentState,
|
knownFeedContentState: FeedContentState,
|
||||||
newFeedContentState: FeedContentState,
|
newFeedContentState: FeedContentState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -76,7 +73,6 @@ fun ChatroomList(
|
|||||||
MessagesPager(
|
MessagesPager(
|
||||||
pagerState,
|
pagerState,
|
||||||
tabs,
|
tabs,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -96,7 +96,6 @@ fun MessagesTwoPane(
|
|||||||
ChatroomList(
|
ChatroomList(
|
||||||
knownFeedContentState,
|
knownFeedContentState,
|
||||||
newFeedContentState,
|
newFeedContentState,
|
||||||
padding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
twoPaneNav,
|
twoPaneNav,
|
||||||
)
|
)
|
||||||
|
|||||||
-2
@@ -198,7 +198,6 @@ fun CommunityScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
feedViewModel,
|
feedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -208,7 +207,6 @@ fun CommunityScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
modFeedViewModel,
|
modFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-12
@@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.discover
|
|||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -70,7 +69,7 @@ import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.rememberForeverPagerState
|
import com.vitorpamplona.amethyst.ui.feeds.rememberForeverPagerState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||||
@@ -277,7 +276,6 @@ private fun DiscoverPages(
|
|||||||
routeForLastRead = tab.routeForLastRead,
|
routeForLastRead = tab.routeForLastRead,
|
||||||
forceEventKind = tab.forceEventKind,
|
forceEventKind = tab.forceEventKind,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -289,7 +287,6 @@ private fun DiscoverPages(
|
|||||||
routeForLastRead = tab.routeForLastRead,
|
routeForLastRead = tab.routeForLastRead,
|
||||||
forceEventKind = tab.forceEventKind,
|
forceEventKind = tab.forceEventKind,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -307,7 +304,6 @@ private fun RenderDiscoverFeed(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
listState: LazyGridState,
|
listState: LazyGridState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -334,7 +330,6 @@ private fun RenderDiscoverFeed(
|
|||||||
routeForLastRead,
|
routeForLastRead,
|
||||||
listState,
|
listState,
|
||||||
forceEventKind,
|
forceEventKind,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -397,7 +392,6 @@ private fun RenderDiscoverFeed(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -424,7 +418,6 @@ private fun RenderDiscoverFeed(
|
|||||||
routeForLastRead,
|
routeForLastRead,
|
||||||
listState,
|
listState,
|
||||||
forceEventKind,
|
forceEventKind,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -468,14 +461,13 @@ private fun DiscoverFeedLoaded(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
@@ -504,7 +496,6 @@ private fun DiscoverFeedColumnsLoaded(
|
|||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
listState: LazyGridState,
|
listState: LazyGridState,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -512,7 +503,7 @@ private fun DiscoverFeedColumnsLoaded(
|
|||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(2),
|
columns = GridCells.Fixed(2),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
|
|||||||
+4
-6
@@ -21,7 +21,6 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.drafts
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.drafts
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -54,7 +53,7 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys.DRAFTS
|
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys.DRAFTS
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
|
||||||
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
||||||
@@ -146,7 +145,7 @@ private fun RenderDraftListScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { scaffoldPadding ->
|
) {
|
||||||
RefresheableBox(feedState) {
|
RefresheableBox(feedState) {
|
||||||
SaveableFeedState(feedState, DRAFTS) { listState ->
|
SaveableFeedState(feedState, DRAFTS) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -155,7 +154,7 @@ private fun RenderDraftListScreen(
|
|||||||
listState = listState,
|
listState = listState,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = null,
|
routeForLastRead = null,
|
||||||
onLoaded = { DraftFeedLoaded(it, listState, scaffoldPadding, accountViewModel, nav) },
|
onLoaded = { DraftFeedLoaded(it, listState, accountViewModel, nav) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,14 +165,13 @@ private fun RenderDraftListScreen(
|
|||||||
private fun DraftFeedLoaded(
|
private fun DraftFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
|
|||||||
+3
-11
@@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.dvms
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
@@ -96,13 +95,13 @@ fun DvmContentDiscoveryScreen(
|
|||||||
DvmTopBar(appDefinitionEventId, accountViewModel, nav)
|
DvmTopBar(appDefinitionEventId, accountViewModel, nav)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
LoadNote(baseNoteHex = appDefinitionEventId, accountViewModel = accountViewModel) { note ->
|
LoadNote(baseNoteHex = appDefinitionEventId, accountViewModel = accountViewModel) { note ->
|
||||||
note?.let { baseNote ->
|
note?.let { baseNote ->
|
||||||
WatchNoteEvent(
|
WatchNoteEvent(
|
||||||
baseNote,
|
baseNote,
|
||||||
onNoteEventFound = {
|
onNoteEventFound = {
|
||||||
DvmContentDiscoveryScreen(baseNote, paddingValues, accountViewModel, nav)
|
DvmContentDiscoveryScreen(baseNote, accountViewModel, nav)
|
||||||
},
|
},
|
||||||
onBlank = {
|
onBlank = {
|
||||||
FeedEmptyWithStatus(baseNote, stringRes(R.string.dvm_looking_for_app), accountViewModel, nav)
|
FeedEmptyWithStatus(baseNote, stringRes(R.string.dvm_looking_for_app), accountViewModel, nav)
|
||||||
@@ -117,7 +116,6 @@ fun DvmContentDiscoveryScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun DvmContentDiscoveryScreen(
|
fun DvmContentDiscoveryScreen(
|
||||||
appDefinition: Note,
|
appDefinition: Note,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -152,7 +150,6 @@ fun DvmContentDiscoveryScreen(
|
|||||||
appDefinition,
|
appDefinition,
|
||||||
myRequestEventID,
|
myRequestEventID,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -169,7 +166,6 @@ fun ObserverContentDiscoveryResponse(
|
|||||||
appDefinition: Note,
|
appDefinition: Note,
|
||||||
dvmRequestId: Note,
|
dvmRequestId: Note,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -198,7 +194,6 @@ fun ObserverContentDiscoveryResponse(
|
|||||||
dvmRequestId.idHex,
|
dvmRequestId.idHex,
|
||||||
myResponse,
|
myResponse,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -251,7 +246,6 @@ fun PrepareViewContentDiscoveryModels(
|
|||||||
dvmRequestId: String,
|
dvmRequestId: String,
|
||||||
latestResponse: NIP90ContentDiscoveryResponseEvent,
|
latestResponse: NIP90ContentDiscoveryResponseEvent,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -265,14 +259,13 @@ fun PrepareViewContentDiscoveryModels(
|
|||||||
resultFeedViewModel.invalidateData()
|
resultFeedViewModel.invalidateData()
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderNostrNIP90ContentDiscoveryScreen(resultFeedViewModel, onRefresh, scaffoldPadding, accountViewModel, nav)
|
RenderNostrNIP90ContentDiscoveryScreen(resultFeedViewModel, onRefresh, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderNostrNIP90ContentDiscoveryScreen(
|
fun RenderNostrNIP90ContentDiscoveryScreen(
|
||||||
resultFeedViewModel: NIP90ContentDiscoveryFeedViewModel,
|
resultFeedViewModel: NIP90ContentDiscoveryFeedViewModel,
|
||||||
onRefresh: () -> Unit,
|
onRefresh: () -> Unit,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -284,7 +277,6 @@ fun RenderNostrNIP90ContentDiscoveryScreen(
|
|||||||
listState,
|
listState,
|
||||||
nav,
|
nav,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding,
|
|
||||||
onEmpty = {
|
onEmpty = {
|
||||||
FeedEmpty {
|
FeedEmpty {
|
||||||
onRefresh()
|
onRefresh()
|
||||||
|
|||||||
-3
@@ -179,7 +179,6 @@ fun FollowPackFeedScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
newThreadFeedViewModel,
|
newThreadFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -189,7 +188,6 @@ fun FollowPackFeedScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
conversationsFeedViewModel,
|
conversationsFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -198,7 +196,6 @@ fun FollowPackFeedScreen(
|
|||||||
2 -> {
|
2 -> {
|
||||||
UserFeedView(
|
UserFeedView(
|
||||||
membersFeedViewModel,
|
membersFeedViewModel,
|
||||||
it,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -103,7 +103,6 @@ fun GeoHashScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
feedViewModel,
|
feedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -108,7 +108,6 @@ fun HashtagScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
feedViewModel,
|
feedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-10
@@ -24,7 +24,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -52,7 +51,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.Amethyst
|
import com.vitorpamplona.amethyst.Amethyst
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
@@ -75,7 +73,7 @@ import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.rememberForeverPagerState
|
import com.vitorpamplona.amethyst.ui.feeds.rememberForeverPagerState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||||
@@ -226,7 +224,6 @@ private fun HomePages(
|
|||||||
routeForLastRead = tabs[page].routeForLastRead,
|
routeForLastRead = tabs[page].routeForLastRead,
|
||||||
scrollStateKey = tabs[page].scrollStateKey,
|
scrollStateKey = tabs[page].scrollStateKey,
|
||||||
liveSection = tabs[page].liveSection,
|
liveSection = tabs[page].liveSection,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -280,7 +277,6 @@ fun HomeFeeds(
|
|||||||
enablePullRefresh: Boolean = true,
|
enablePullRefresh: Boolean = true,
|
||||||
scrollStateKey: String? = null,
|
scrollStateKey: String? = null,
|
||||||
liveSection: ChannelFeedContentState? = null,
|
liveSection: ChannelFeedContentState? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -292,7 +288,7 @@ fun HomeFeeds(
|
|||||||
listState = listState,
|
listState = listState,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = routeForLastRead,
|
routeForLastRead = routeForLastRead,
|
||||||
onLoaded = { FeedLoaded(it, listState, routeForLastRead, liveSection, scaffoldPadding, accountViewModel, nav) },
|
onLoaded = { FeedLoaded(it, listState, routeForLastRead, liveSection, accountViewModel, nav) },
|
||||||
onEmpty = { HomeFeedEmpty(feedState::invalidateData) },
|
onEmpty = { HomeFeedEmpty(feedState::invalidateData) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -306,16 +302,13 @@ fun FeedLoaded(
|
|||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
liveSection: ChannelFeedContentState? = null,
|
liveSection: ChannelFeedContentState? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
val listPadding = rememberMergedPadding(scaffoldPadding, FeedPadding)
|
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = listPadding,
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
if (liveSection != null) {
|
if (liveSection != null) {
|
||||||
|
|||||||
+2
-4
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.longs
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.longs
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -33,7 +32,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts.VideoCardCompose
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts.VideoCardCompose
|
||||||
@@ -45,14 +44,13 @@ import com.vitorpamplona.quartz.nip71Video.VideoEvent
|
|||||||
fun LongsFeedLoaded(
|
fun LongsFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+1
-2
@@ -77,7 +77,7 @@ fun LongsScreen(
|
|||||||
NewLongVideoButton(accountViewModel, nav, longsFeedContentState::sendToTop)
|
NewLongVideoButton(accountViewModel, nav, longsFeedContentState::sendToTop)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
RefresheableBox(longsFeedContentState, true) {
|
RefresheableBox(longsFeedContentState, true) {
|
||||||
SaveableFeedContentState(longsFeedContentState, scrollStateKey = ScrollStateKeys.LONGS_SCREEN) { listState ->
|
SaveableFeedContentState(longsFeedContentState, scrollStateKey = ScrollStateKeys.LONGS_SCREEN) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -90,7 +90,6 @@ fun LongsScreen(
|
|||||||
LongsFeedLoaded(
|
LongsFeedLoaded(
|
||||||
loaded = loaded,
|
loaded = loaded,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-7
@@ -26,7 +26,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -52,7 +51,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
||||||
@@ -61,7 +59,7 @@ import com.vitorpamplona.amethyst.logTime
|
|||||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.BadgeCompose
|
import com.vitorpamplona.amethyst.ui.note.BadgeCompose
|
||||||
import com.vitorpamplona.amethyst.ui.note.CloseIcon
|
import com.vitorpamplona.amethyst.ui.note.CloseIcon
|
||||||
@@ -89,7 +87,6 @@ fun RenderCardFeed(
|
|||||||
nav: INav,
|
nav: INav,
|
||||||
routeForLastRead: String,
|
routeForLastRead: String,
|
||||||
scrollToEventId: String? = null,
|
scrollToEventId: String? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
headerContent: (@Composable () -> Unit)? = null,
|
headerContent: (@Composable () -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
val feedState by feedContent.feedContent.collectAsStateWithLifecycle()
|
val feedState by feedContent.feedContent.collectAsStateWithLifecycle()
|
||||||
@@ -118,7 +115,6 @@ fun RenderCardFeed(
|
|||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
scrollToEventId = scrollToEventId,
|
scrollToEventId = scrollToEventId,
|
||||||
scaffoldPadding = scaffoldPadding,
|
|
||||||
headerContent = headerContent,
|
headerContent = headerContent,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -153,7 +149,6 @@ private fun FeedLoaded(
|
|||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
scrollToEventId: String? = null,
|
scrollToEventId: String? = null,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
headerContent: (@Composable () -> Unit)? = null,
|
headerContent: (@Composable () -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
@@ -179,7 +174,7 @@ private fun FeedLoaded(
|
|||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
if (headerContent != null) {
|
if (headerContent != null) {
|
||||||
|
|||||||
-1
@@ -102,7 +102,6 @@ fun NotificationScreen(
|
|||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = "Notification",
|
routeForLastRead = "Notification",
|
||||||
scrollToEventId = scrollToEventId,
|
scrollToEventId = scrollToEventId,
|
||||||
scaffoldPadding = it,
|
|
||||||
headerContent = { ObserveInboxRelayListAndDisplayIfNotFound(accountViewModel, nav) },
|
headerContent = { ObserveInboxRelayListAndDisplayIfNotFound(accountViewModel, nav) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.pictures
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.pictures
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -33,7 +32,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
@@ -44,14 +43,13 @@ import com.vitorpamplona.quartz.nip68Picture.PictureEvent
|
|||||||
fun PictureFeedLoaded(
|
fun PictureFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+1
-2
@@ -77,7 +77,7 @@ fun PicturesScreen(
|
|||||||
NewPictureButton(accountViewModel, nav, picturesFeedContentState::sendToTop)
|
NewPictureButton(accountViewModel, nav, picturesFeedContentState::sendToTop)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
RefresheableBox(picturesFeedContentState, true) {
|
RefresheableBox(picturesFeedContentState, true) {
|
||||||
SaveableFeedContentState(picturesFeedContentState, scrollStateKey = ScrollStateKeys.PICTURES_SCREEN) { listState ->
|
SaveableFeedContentState(picturesFeedContentState, scrollStateKey = ScrollStateKeys.PICTURES_SCREEN) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -90,7 +90,6 @@ fun PicturesScreen(
|
|||||||
PictureFeedLoaded(
|
PictureFeedLoaded(
|
||||||
loaded = loaded,
|
loaded = loaded,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -78,7 +78,6 @@ private fun RenderPinnedNotesScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
pinnedNotesFeedViewModel,
|
pinnedNotesFeedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -172,7 +172,6 @@ private fun PollsPages(
|
|||||||
listState = listState,
|
listState = listState,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = tabs[page].routeForLastRead,
|
routeForLastRead = tabs[page].routeForLastRead,
|
||||||
scaffoldPadding = it,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.products
|
|||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
@@ -33,7 +32,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedContentState
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
@@ -41,7 +39,7 @@ import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
import com.vitorpamplona.amethyst.ui.feeds.FeedEmpty
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
import com.vitorpamplona.amethyst.ui.feeds.LoadingFeed
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.ChannelCardCompose
|
||||||
@@ -53,7 +51,6 @@ import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
|||||||
fun RenderProductsFeed(
|
fun RenderProductsFeed(
|
||||||
feedContentState: FeedContentState,
|
feedContentState: FeedContentState,
|
||||||
gridState: LazyGridState,
|
gridState: LazyGridState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -78,7 +75,6 @@ fun RenderProductsFeed(
|
|||||||
ProductsFeedColumnsLoaded(
|
ProductsFeedColumnsLoaded(
|
||||||
state,
|
state,
|
||||||
gridState,
|
gridState,
|
||||||
scaffoldPadding,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -96,7 +92,6 @@ fun RenderProductsFeed(
|
|||||||
private fun ProductsFeedColumnsLoaded(
|
private fun ProductsFeedColumnsLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyGridState,
|
listState: LazyGridState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -104,7 +99,7 @@ private fun ProductsFeedColumnsLoaded(
|
|||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(2),
|
columns = GridCells.Fixed(2),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
|
|||||||
+1
-2
@@ -76,13 +76,12 @@ fun ProductsScreen(
|
|||||||
NewProductButton(accountViewModel, nav)
|
NewProductButton(accountViewModel, nav)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
RefresheableBox(productsFeedContentState, true) {
|
RefresheableBox(productsFeedContentState, true) {
|
||||||
SaveableGridFeedContentState(productsFeedContentState, scrollStateKey = ScrollStateKeys.PRODUCTS_SCREEN) { gridState ->
|
SaveableGridFeedContentState(productsFeedContentState, scrollStateKey = ScrollStateKeys.PRODUCTS_SCREEN) { gridState ->
|
||||||
RenderProductsFeed(
|
RenderProductsFeed(
|
||||||
feedContentState = productsFeedContentState,
|
feedContentState = productsFeedContentState,
|
||||||
gridState = gridState,
|
gridState = gridState,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
-1
@@ -106,7 +106,6 @@ fun RelayFeedScreen(
|
|||||||
RefresheableFeedView(
|
RefresheableFeedView(
|
||||||
feedViewModel,
|
feedViewModel,
|
||||||
null,
|
null,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+6
-9
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.search
|
|||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.defaultMinSize
|
import androidx.compose.foundation.layout.defaultMinSize
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
@@ -58,7 +57,7 @@ import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo
|
|||||||
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.TextSearchDataSourceSubscription
|
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.TextSearchDataSourceSubscription
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||||
@@ -123,11 +122,10 @@ fun SearchScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { scaffoldPadding ->
|
) {
|
||||||
DisplaySearchResults(
|
DisplaySearchResults(
|
||||||
searchBarViewModel = searchBarViewModel,
|
searchBarViewModel = searchBarViewModel,
|
||||||
scaffoldPadding = scaffoldPadding,
|
headerContent = { ObserveRelayListForSearchAndDisplayIfNotFound(accountViewModel, nav) },
|
||||||
header = { ObserveRelayListForSearchAndDisplayIfNotFound(accountViewModel, nav) },
|
|
||||||
nav = nav,
|
nav = nav,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
)
|
)
|
||||||
@@ -220,8 +218,7 @@ private fun SearchTextField(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun DisplaySearchResults(
|
private fun DisplaySearchResults(
|
||||||
searchBarViewModel: SearchBarViewModel,
|
searchBarViewModel: SearchBarViewModel,
|
||||||
scaffoldPadding: PaddingValues,
|
headerContent: @Composable () -> Unit,
|
||||||
header: @Composable () -> Unit,
|
|
||||||
nav: INav,
|
nav: INav,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
) {
|
) {
|
||||||
@@ -236,10 +233,10 @@ private fun DisplaySearchResults(
|
|||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxHeight(),
|
modifier = Modifier.fillMaxHeight(),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = searchBarViewModel.listState,
|
state = searchBarViewModel.listState,
|
||||||
) {
|
) {
|
||||||
item(key = "scaffold-header") { header() }
|
item(key = "scaffold-header") { headerContent() }
|
||||||
|
|
||||||
if (!isRefreshing) return@LazyColumn
|
if (!isRefreshing) return@LazyColumn
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.shorts
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -33,7 +32,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
@@ -44,14 +43,13 @@ import com.vitorpamplona.quartz.nip71Video.VideoEvent
|
|||||||
fun ShortsFeedLoaded(
|
fun ShortsFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+1
-2
@@ -77,7 +77,7 @@ fun ShortsScreen(
|
|||||||
NewShortVideoButton(accountViewModel, nav, shortsFeedContentState::sendToTop)
|
NewShortVideoButton(accountViewModel, nav, shortsFeedContentState::sendToTop)
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { paddingValues ->
|
) {
|
||||||
RefresheableBox(shortsFeedContentState, true) {
|
RefresheableBox(shortsFeedContentState, true) {
|
||||||
SaveableFeedContentState(shortsFeedContentState, scrollStateKey = ScrollStateKeys.SHORTS_SCREEN) { listState ->
|
SaveableFeedContentState(shortsFeedContentState, scrollStateKey = ScrollStateKeys.SHORTS_SCREEN) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -90,7 +90,6 @@ fun ShortsScreen(
|
|||||||
ShortsFeedLoaded(
|
ShortsFeedLoaded(
|
||||||
loaded = loaded,
|
loaded = loaded,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = paddingValues,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-5
@@ -85,7 +85,7 @@ import com.vitorpamplona.amethyst.ui.components.LoadNote
|
|||||||
import com.vitorpamplona.amethyst.ui.components.MyAsyncImage
|
import com.vitorpamplona.amethyst.ui.components.MyAsyncImage
|
||||||
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
import com.vitorpamplona.amethyst.ui.components.ZoomableContentView
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||||
@@ -298,7 +298,6 @@ import kotlinx.coroutines.withContext
|
|||||||
fun ThreadFeedView(
|
fun ThreadFeedView(
|
||||||
noteId: String,
|
noteId: String,
|
||||||
viewModel: LevelFeedViewModel,
|
viewModel: LevelFeedViewModel,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -310,7 +309,7 @@ fun ThreadFeedView(
|
|||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = null,
|
routeForLastRead = null,
|
||||||
onLoaded = {
|
onLoaded = {
|
||||||
RenderThreadFeed(noteId, it, viewModel.llState, viewModel, scaffoldPadding, accountViewModel, nav)
|
RenderThreadFeed(noteId, it, viewModel.llState, viewModel, accountViewModel, nav)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -322,7 +321,6 @@ fun RenderThreadFeed(
|
|||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
viewModel: LevelFeedViewModel,
|
viewModel: LevelFeedViewModel,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -359,7 +357,7 @@ fun RenderThreadFeed(
|
|||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+1
-1
@@ -69,6 +69,6 @@ fun ThreadScreen(
|
|||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) {
|
) {
|
||||||
ThreadFeedView(noteId, feedViewModel, it, accountViewModel, nav)
|
ThreadFeedView(noteId, feedViewModel, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.video
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.video
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@@ -41,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.feeds.SaveableFeedContentState
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||||
@@ -99,7 +98,6 @@ fun VideoScreen(
|
|||||||
RenderFeed(
|
RenderFeed(
|
||||||
videoFeedContentState = videoFeedContentState,
|
videoFeedContentState = videoFeedContentState,
|
||||||
scrollKey = ScrollStateKeys.VIDEO_SCREEN,
|
scrollKey = ScrollStateKeys.VIDEO_SCREEN,
|
||||||
scaffoldPadding = it,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -125,7 +123,6 @@ fun WatchAccountForVideoScreen(
|
|||||||
private fun RenderFeed(
|
private fun RenderFeed(
|
||||||
videoFeedContentState: FeedContentState,
|
videoFeedContentState: FeedContentState,
|
||||||
scrollKey: String?,
|
scrollKey: String?,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
@@ -141,7 +138,6 @@ private fun RenderFeed(
|
|||||||
VideoFeedLoaded(
|
VideoFeedLoaded(
|
||||||
loaded = loaded,
|
loaded = loaded,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
scaffoldPadding = scaffoldPadding,
|
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
@@ -155,14 +151,13 @@ private fun RenderFeed(
|
|||||||
fun VideoFeedLoaded(
|
fun VideoFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues = PaddingValues(0.dp),
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
|
|||||||
+4
-6
@@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.webBookmarks
|
|||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -81,7 +80,7 @@ import com.vitorpamplona.amethyst.ui.feeds.RenderFeedContentState
|
|||||||
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||||
import com.vitorpamplona.amethyst.ui.layouts.rememberMergedPadding
|
import com.vitorpamplona.amethyst.ui.layouts.rememberFeedContentPadding
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
|
||||||
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
||||||
@@ -155,7 +154,7 @@ private fun RenderWebBookmarksScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
) { scaffoldPadding ->
|
) {
|
||||||
RefresheableBox(feedState) {
|
RefresheableBox(feedState) {
|
||||||
SaveableFeedState(feedState, ScrollStateKeys.WEB_BOOKMARKS) { listState ->
|
SaveableFeedState(feedState, ScrollStateKeys.WEB_BOOKMARKS) { listState ->
|
||||||
RenderFeedContentState(
|
RenderFeedContentState(
|
||||||
@@ -164,7 +163,7 @@ private fun RenderWebBookmarksScreen(
|
|||||||
listState = listState,
|
listState = listState,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
routeForLastRead = null,
|
routeForLastRead = null,
|
||||||
onLoaded = { WebBookmarksFeedLoaded(it, listState, scaffoldPadding, accountViewModel, nav) },
|
onLoaded = { WebBookmarksFeedLoaded(it, listState, accountViewModel, nav) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,14 +174,13 @@ private fun RenderWebBookmarksScreen(
|
|||||||
private fun WebBookmarksFeedLoaded(
|
private fun WebBookmarksFeedLoaded(
|
||||||
loaded: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
scaffoldPadding: PaddingValues,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val items by loaded.feed.collectAsStateWithLifecycle()
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = rememberMergedPadding(scaffoldPadding, FeedPadding),
|
contentPadding = rememberFeedContentPadding(FeedPadding),
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
|
|||||||
+170
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.layouts
|
||||||
|
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||||
|
import androidx.compose.ui.unit.Velocity
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class DisappearingBarNestedScrollTest {
|
||||||
|
private fun state(
|
||||||
|
topLimit: Float = 100f,
|
||||||
|
bottomLimit: Float = 50f,
|
||||||
|
) = DisappearingBarState().apply {
|
||||||
|
topHeightLimit = topLimit
|
||||||
|
bottomHeightLimit = bottomLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nsc(
|
||||||
|
state: DisappearingBarState,
|
||||||
|
canScroll: Boolean = true,
|
||||||
|
reverseLayout: Boolean = false,
|
||||||
|
) = DisappearingBarNestedScroll(
|
||||||
|
state = state,
|
||||||
|
canScroll = { canScroll },
|
||||||
|
reverseLayout = reverseLayout,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `onPostScroll does not consume any delta`() {
|
||||||
|
val state = state()
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
val consumed = connection.onPostScroll(Offset(0f, -20f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(Offset.Zero, consumed)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `scrolling content up hides both bars by the total delta`() {
|
||||||
|
val state = state(topLimit = 100f, bottomLimit = 50f)
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
connection.onPostScroll(Offset(0f, -30f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(-30f, state.topHeightOffset)
|
||||||
|
assertEquals(-30f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bars clamp at their individual limits`() {
|
||||||
|
val state = state(topLimit = 100f, bottomLimit = 50f)
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
connection.onPostScroll(Offset(0f, -200f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(-100f, state.topHeightOffset)
|
||||||
|
assertEquals(-50f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `scrolling content down reveals both bars from a hidden state`() {
|
||||||
|
val state = state(topLimit = 100f, bottomLimit = 50f)
|
||||||
|
state.topHeightOffset = -100f
|
||||||
|
state.bottomHeightOffset = -50f
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
connection.onPostScroll(Offset(0f, 30f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(-70f, state.topHeightOffset)
|
||||||
|
assertEquals(-20f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `uses consumed plus available so the bars see the whole scroll attempt`() {
|
||||||
|
val state = state()
|
||||||
|
state.topHeightOffset = -50f
|
||||||
|
state.bottomHeightOffset = -50f
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
// The list consumed 20px of a 40px reveal drag; 20 more was left as overscroll.
|
||||||
|
// The bars should move by the total 40, not just one of the halves.
|
||||||
|
connection.onPostScroll(Offset(0f, 20f), Offset(0f, 20f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(-10f, state.topHeightOffset)
|
||||||
|
assertEquals(-10f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `canScroll returning false freezes the bars`() {
|
||||||
|
val state = state()
|
||||||
|
val connection = nsc(state, canScroll = false)
|
||||||
|
|
||||||
|
connection.onPostScroll(Offset(0f, -100f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(0f, state.topHeightOffset)
|
||||||
|
assertEquals(0f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `reverseLayout inverts the delta sign`() {
|
||||||
|
val state = state()
|
||||||
|
val connection = nsc(state, reverseLayout = true)
|
||||||
|
|
||||||
|
// In reverse layout, a positive Y is a "hide" direction
|
||||||
|
connection.onPostScroll(Offset(0f, 20f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(-20f, state.topHeightOffset)
|
||||||
|
assertEquals(-20f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `bar offsets never exceed zero when revealing`() {
|
||||||
|
val state = state()
|
||||||
|
// Start from a mid-hidden position
|
||||||
|
state.topHeightOffset = -10f
|
||||||
|
state.bottomHeightOffset = -10f
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
connection.onPostScroll(Offset(0f, 100f), Offset(0f, 0f), NestedScrollSource.UserInput)
|
||||||
|
|
||||||
|
assertEquals(0f, state.topHeightOffset)
|
||||||
|
assertEquals(0f, state.bottomHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setting topHeightLimit smaller than current offset clamps it in`() {
|
||||||
|
val state = state(topLimit = 100f)
|
||||||
|
state.topHeightOffset = -80f
|
||||||
|
|
||||||
|
state.topHeightLimit = 40f
|
||||||
|
|
||||||
|
assertEquals(-40f, state.topHeightOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `onPostFling swallows all velocity so parents don't get a phantom fling`() =
|
||||||
|
runTest {
|
||||||
|
val state = state()
|
||||||
|
val connection = nsc(state)
|
||||||
|
|
||||||
|
val remaining =
|
||||||
|
connection.onPostFling(
|
||||||
|
consumed = Velocity(0f, 1000f),
|
||||||
|
available = Velocity(0f, 200f),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(Velocity.Zero, remaining)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user