Skip to content

Commit

Permalink
update profile screen ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Tlaster committed Dec 2, 2024
1 parent a9e8714 commit 0f8128e
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,10 @@ import compose.icons.fontawesomeicons.solid.VolumeXmark
import dev.dimension.flare.R
import dev.dimension.flare.common.AppDeepLink
import dev.dimension.flare.common.PagingState
import dev.dimension.flare.common.isLoading
import dev.dimension.flare.common.isSuccess
import dev.dimension.flare.common.onLoading
import dev.dimension.flare.common.onSuccess
import dev.dimension.flare.data.datasource.microblog.ProfileAction
import dev.dimension.flare.data.datasource.microblog.ProfileTab
import dev.dimension.flare.model.AccountType
import dev.dimension.flare.model.MicroBlogKey
import dev.dimension.flare.model.PlatformType
Expand Down Expand Up @@ -608,68 +607,71 @@ private fun ProfileScreen(
isRefreshing = state.isRefreshing,
indicatorPadding = it,
content = {
val pagerState = rememberPagerState { state.profileTabs.size }
val content = @Composable {
Column {
Box {
if (state.profileTabs.size > 1) {
SecondaryScrollableTabRow(
selectedTabIndex = pagerState.currentPage,
modifier = Modifier.fillMaxWidth(),
edgePadding = screenHorizontalPadding,
divider = {},
) {
state.profileTabs.forEachIndexed { index, profileTab ->
Tab(
selected = pagerState.currentPage == index,
onClick = {
scope.launch {
pagerState.animateScrollToPage(index)
}
},
) {
Text(
profileTab.title,
modifier =
Modifier
.padding(8.dp),
)
state.state.tabs.onSuccess { tabs ->
val pagerState = rememberPagerState { tabs.size }
Column {
Box {
if (tabs.size > 1) {
SecondaryScrollableTabRow(
selectedTabIndex = pagerState.currentPage,
modifier = Modifier.fillMaxWidth(),
edgePadding = screenHorizontalPadding,
divider = {},
) {
tabs.toImmutableList().forEachIndexed { index, profileTab ->
Tab(
selected = pagerState.currentPage == index,
onClick = {
scope.launch {
pagerState.animateScrollToPage(index)
}
},
) {
Text(
profileTab.title,
modifier =
Modifier
.padding(8.dp),
)
}
}
}
}
HorizontalDivider(
modifier =
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth(),
)
}
HorizontalDivider(
modifier =
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth(),
)
}
HorizontalPager(
state = pagerState,
) { index ->
val type = state.profileTabs[index]
when (type) {
ProfileTab.Timeline ->
LazyStatusVerticalStaggeredGrid(
state = listState,
contentPadding =
PaddingValues(
top = 8.dp,
bottom = 8.dp + it.calculateBottomPadding(),
),
modifier = Modifier.fillMaxSize(),
) {
status(state.state.listState)
HorizontalPager(
state = pagerState,
) { index ->
val type = tabs[index]
when (type) {
is ProfileState.Tab.Media -> {
ProfileMediaTab(
mediaState = type.data,
onItemClicked = { statusKey, index, preview ->
onMediaClick(statusKey, index, preview)
},
modifier = Modifier.fillMaxSize(),
)
}
is ProfileState.Tab.Timeline -> {
LazyStatusVerticalStaggeredGrid(
state = listState,
contentPadding =
PaddingValues(
top = 8.dp,
bottom = 8.dp + it.calculateBottomPadding(),
),
modifier = Modifier.fillMaxSize(),
) {
status(type.data)
}
}
ProfileTab.Media -> {
ProfileMediaTab(
mediaState = state.state.mediaState,
onItemClicked = { statusKey, index, preview ->
onMediaClick(statusKey, index, preview)
},
modifier = Modifier.fillMaxSize(),
)
}
}
}
Expand Down Expand Up @@ -718,7 +720,9 @@ private fun ProfileScreen(
)
}
},
content = content,
content = {
content.invoke()
},
)
}
},
Expand Down Expand Up @@ -1563,17 +1567,16 @@ private fun profilePresenter(
var showMoreMenus by remember {
mutableStateOf(false)
}
val mediaState = state.mediaState

val profileTabs =
listOfNotNull(
ProfileTab.Timeline,
if (mediaState.isSuccess() && mediaState.itemCount > 0 || mediaState.isLoading) {
ProfileTab.Media
} else {
null
},
)
// val mediaState = state.mediaState
// val profileTabs =
// listOfNotNull(
// ProfileTab.Timeline,
// if (mediaState.isSuccess() && mediaState.itemCount > 0 || mediaState.isLoading) {
// ProfileTab.Media
// } else {
// null
// },
// )
val allAccounts =
remember {
AccountsPresenter()
Expand All @@ -1590,7 +1593,7 @@ private fun profilePresenter(
}
val showMoreMenus = showMoreMenus
val isRefreshing = isRefreshing
val profileTabs = profileTabs
// val profileTabs = profileTabs

fun setShowMoreMenus(value: Boolean) {
showMoreMenus = value
Expand All @@ -1606,15 +1609,15 @@ private fun profilePresenter(
}
}

private enum class ProfileTab {
Timeline,
Media,
}

private val ProfileTab.title: String
private val ProfileState.Tab.title: String
@Composable
get() =
when (this) {
ProfileTab.Timeline -> stringResource(R.string.profile_tab_timeline)
ProfileTab.Media -> stringResource(R.string.profile_tab_media)
is ProfileState.Tab.Timeline ->
when (type) {
ProfileTab.Timeline.Type.Status -> stringResource(R.string.profile_tab_timeline)
ProfileTab.Timeline.Type.StatusWithReplies -> stringResource(R.string.profile_tab_timeline_with_reply)
ProfileTab.Timeline.Type.Likes -> stringResource(R.string.profile_tab_likes)
}
is ProfileState.Tab.Media -> stringResource(R.string.profile_tab_media)
}
4 changes: 3 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,9 @@
<string name="feeds_unsubscribe">Unsubscribe</string>
<string name="feeds_subscribe">Subscribe</string>

<string name="profile_tab_timeline">Timeline</string>
<string name="profile_tab_timeline">Posts</string>
<string name="profile_tab_timeline_with_reply">Posts and replies</string>
<string name="profile_tab_likes">Likes</string>
<string name="profile_tab_media">Media</string>

<string name="tab_settings_title">Tab settings</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import dev.dimension.flare.data.datasource.mastodon.SearchUserPagingSource
import dev.dimension.flare.data.datasource.mastodon.TrendHashtagPagingSource
import dev.dimension.flare.data.datasource.mastodon.TrendsUserPagingSource
import dev.dimension.flare.data.datasource.microblog.MicroblogDataSource
import dev.dimension.flare.data.datasource.microblog.ProfileTab
import dev.dimension.flare.data.network.mastodon.GuestMastodonService
import dev.dimension.flare.model.MicroBlogKey
import dev.dimension.flare.model.PlatformType
Expand All @@ -25,6 +26,8 @@ import dev.dimension.flare.ui.model.UiTimeline
import dev.dimension.flare.ui.model.UiUserV2
import dev.dimension.flare.ui.model.mapper.render
import dev.dimension.flare.ui.model.mapper.renderGuest
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
Expand Down Expand Up @@ -108,7 +111,7 @@ object GuestDataSource : MicroblogDataSource, KoinComponent {
userId = userKey.id,
onlyMedia = mediaOnly,
)
}.flow
}.flow.cachedIn(scope)

override fun context(
statusKey: MicroBlogKey,
Expand Down Expand Up @@ -225,4 +228,34 @@ object GuestDataSource : MicroblogDataSource, KoinComponent {
accountKey = null,
)
}.flow.cachedIn(scope)

override fun profileTabs(
userKey: MicroBlogKey,
scope: CoroutineScope,
pagingSize: Int,
): ImmutableList<ProfileTab> =
persistentListOf(
ProfileTab.Timeline(
type = ProfileTab.Timeline.Type.Status,
flow =
Pager(PagingConfig(pageSize = pagingSize)) {
GuestUserTimelinePagingSource(
host = GuestMastodonService.HOST,
userId = userKey.id,
)
}.flow.cachedIn(scope),
),
ProfileTab.Timeline(
type = ProfileTab.Timeline.Type.StatusWithReplies,
flow =
Pager(PagingConfig(pageSize = pagingSize)) {
GuestUserTimelinePagingSource(
host = GuestMastodonService.HOST,
userId = userKey.id,
withReply = true,
)
}.flow.cachedIn(scope),
),
ProfileTab.Media,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import dev.dimension.flare.ui.model.mapper.renderGuest
internal class GuestUserTimelinePagingSource(
private val host: String,
private val userId: String,
private val withReply: Boolean = false,
private val onlyMedia: Boolean = false,
) : PagingSource<String, UiTimeline>() {
override fun getRefreshKey(state: PagingState<String, UiTimeline>): String? = null
Expand All @@ -23,6 +24,7 @@ internal class GuestUserTimelinePagingSource(
limit = limit,
max_id = maxId,
only_media = onlyMedia,
exclude_replies = !withReply,
)
LoadResult.Page(
data =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@ interface MicroblogDataSource {
fun profileTabs(
userKey: MicroBlogKey,
scope: CoroutineScope,
pagingSize: Int = 20,
): ImmutableList<ProfileTab>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ package dev.dimension.flare.data.datasource.microblog

import androidx.compose.runtime.Immutable
import androidx.paging.PagingData
import dev.dimension.flare.ui.model.UiMedia
import dev.dimension.flare.ui.model.UiTimeline
import dev.dimension.flare.ui.presenter.profile.ProfileMedia
import kotlinx.coroutines.flow.Flow

@Immutable
sealed interface ProfileTab {
@Immutable
data class Timeline(
val type: Type,
val flow: Flow<PagingData<UiTimeline>>,
) : ProfileTab {
@Immutable
enum class Type {
Status,
StatusWithReplies,
Likes,
}
}

data class Media(
val flow: Flow<PagingData<ProfileMedia>>,
) : ProfileTab
}
@Immutable
data object Media : ProfileTab
}
Loading

0 comments on commit 0f8128e

Please sign in to comment.