mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 12:48:42 +01:00
chore: screen model and navigator optimizations (#103)
This commit is contained in:
parent
a4a8722b02
commit
e007426b37
@ -1,11 +1,13 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
interface ThemeRepository {
|
||||
|
||||
val uiTheme: StateFlow<UiTheme>
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme
|
||||
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
|
||||
|
||||
@Stable
|
||||
interface ColorSchemeProvider {
|
||||
|
||||
val supportsDynamicColors: Boolean
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PrivateMessageModel
|
||||
|
||||
@Stable
|
||||
interface InboxChatMviModel :
|
||||
MviModel<InboxChatMviModel.Intent, InboxChatMviModel.UiState, InboxChatMviModel.SideEffect>,
|
||||
ScreenModel {
|
||||
|
@ -67,7 +67,7 @@ class InboxChatScreen(
|
||||
val model = rememberScreenModel { getInboxChatViewModel(otherUserId) }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val focusManager = LocalFocusManager.current
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
DisposableEffect(key) {
|
||||
@ -112,7 +112,7 @@ class InboxChatScreen(
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
|
@ -31,9 +31,11 @@ class InboxChatViewModel(
|
||||
private var currentPage: Int = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
|
||||
@Stable
|
||||
interface CommunityInfoMviModel :
|
||||
MviModel<CommunityInfoMviModel.Intent, CommunityInfoMviModel.UiState, CommunityInfoMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
@ -7,6 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
|
||||
@Stable
|
||||
interface CommunityDetailMviModel :
|
||||
MviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -15,16 +17,16 @@ interface CommunityDetailMviModel :
|
||||
data object Refresh : Intent
|
||||
data object LoadNextPage : Intent
|
||||
data class ChangeSort(val value: SortType) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data object Subscribe : Intent
|
||||
data object Unsubscribe : Intent
|
||||
data class DeletePost(val id: Int) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class MarkAsRead(val index: Int) : Intent
|
||||
data class Hide(val index: Int) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data class MarkAsRead(val id: Int) : Intent
|
||||
data class Hide(val id: Int) : Intent
|
||||
data object Block : Intent
|
||||
data object BlockInstance : Intent
|
||||
data object ClearRead : Intent
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -60,7 +60,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
@ -88,6 +87,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateRepor
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
@ -123,14 +123,13 @@ class CommunityDetailScreen(
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val successMessage = stringResource(MR.strings.message_operation_successful)
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val isOnOtherInstance = otherInstance.isNotEmpty()
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val fabNestedScrollConnection = remember { getFabNestedScrollConnection() }
|
||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
val downvoteColor by themeRepository.downvoteColor.collectAsState()
|
||||
@ -138,6 +137,8 @@ class CommunityDetailScreen(
|
||||
val defaultDownVoteColor = MaterialTheme.colorScheme.tertiary
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
@ -146,7 +147,38 @@ class CommunityDetailScreen(
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
}, key, NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
@ -170,8 +202,6 @@ class CommunityDetailScreen(
|
||||
val stateCommunity = uiState.community
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(Spacing.xs),
|
||||
topBar = {
|
||||
@ -216,16 +246,7 @@ class CommunityDetailScreen(
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -234,6 +255,7 @@ class CommunityDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
@ -264,7 +286,7 @@ class CommunityDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -275,7 +297,7 @@ class CommunityDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(CommunityDetailMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -286,14 +308,11 @@ class CommunityDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.Create,
|
||||
text = stringResource(MR.strings.action_create_post),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
val screen = CreatePostScreen(
|
||||
communityId = stateCommunity.id,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
}, key, NotificationCenterContractKeys.PostCreated)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -312,6 +331,14 @@ class CommunityDetailScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -328,7 +355,8 @@ class CommunityDetailScreen(
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
),
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
@ -336,7 +364,7 @@ class CommunityDetailScreen(
|
||||
2 -> model.reduce(CommunityDetailMviModel.Intent.Block)
|
||||
|
||||
1 -> {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
InstanceInfoScreen(
|
||||
url = stateCommunity.instanceUrl,
|
||||
),
|
||||
@ -344,7 +372,7 @@ class CommunityDetailScreen(
|
||||
}
|
||||
|
||||
else -> {
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CommunityInfoScreen(stateCommunity),
|
||||
)
|
||||
}
|
||||
@ -367,7 +395,7 @@ class CommunityDetailScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled && !isOnOtherInstance,
|
||||
@ -398,12 +426,12 @@ class CommunityDetailScreen(
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.UpVotePost(idx),
|
||||
CommunityDetailMviModel.Intent.UpVotePost(post.id),
|
||||
)
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.DownVotePost(idx),
|
||||
CommunityDetailMviModel.Intent.DownVotePost(post.id),
|
||||
)
|
||||
},
|
||||
content = {
|
||||
@ -420,10 +448,10 @@ class CommunityDetailScreen(
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.MarkAsRead(
|
||||
idx
|
||||
post.id
|
||||
)
|
||||
)
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
otherInstance = otherInstance,
|
||||
@ -431,7 +459,7 @@ class CommunityDetailScreen(
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstance,
|
||||
@ -442,7 +470,7 @@ class CommunityDetailScreen(
|
||||
if (!isOnOtherInstance) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -452,7 +480,7 @@ class CommunityDetailScreen(
|
||||
if (!isOnOtherInstance) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -462,7 +490,7 @@ class CommunityDetailScreen(
|
||||
if (!isOnOtherInstance) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -473,23 +501,17 @@ class CommunityDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs(model) { url ->
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.MarkAsRead(
|
||||
idx
|
||||
post.id
|
||||
)
|
||||
)
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -512,26 +534,21 @@ class CommunityDetailScreen(
|
||||
)
|
||||
|
||||
4 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
@ -540,12 +557,12 @@ class CommunityDetailScreen(
|
||||
|
||||
1 -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.Hide(
|
||||
idx
|
||||
post.id
|
||||
)
|
||||
)
|
||||
|
||||
else -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.SharePost(idx)
|
||||
CommunityDetailMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -33,8 +33,8 @@ class CommunityDetailViewModel(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val shareHelper: ShareHelper,
|
||||
private val hapticFeedback: HapticFeedback,
|
||||
) : MviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect> by mvi,
|
||||
CommunityDetailMviModel {
|
||||
) : CommunityDetailMviModel,
|
||||
MviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect> by mvi {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
private var pageCursor: String? = null
|
||||
@ -85,17 +85,17 @@ class CommunityDetailViewModel(
|
||||
CommunityDetailMviModel.Intent.Refresh -> refresh()
|
||||
|
||||
is CommunityDetailMviModel.Intent.DownVotePost -> toggleDownVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is CommunityDetailMviModel.Intent.SavePost -> toggleSavePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is CommunityDetailMviModel.Intent.UpVotePost -> toggleUpVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
@ -105,17 +105,17 @@ class CommunityDetailViewModel(
|
||||
CommunityDetailMviModel.Intent.Unsubscribe -> unsubscribe()
|
||||
is CommunityDetailMviModel.Intent.DeletePost -> handlePostDelete(intent.id)
|
||||
is CommunityDetailMviModel.Intent.SharePost -> share(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
)
|
||||
|
||||
CommunityDetailMviModel.Intent.Block -> blockCommunity()
|
||||
CommunityDetailMviModel.Intent.BlockInstance -> blockInstance()
|
||||
is CommunityDetailMviModel.Intent.MarkAsRead -> {
|
||||
markAsRead(uiState.value.posts[intent.index])
|
||||
markAsRead(uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
|
||||
CommunityDetailMviModel.Intent.ClearRead -> clearRead()
|
||||
is CommunityDetailMviModel.Intent.Hide -> hide(post = uiState.value.posts[intent.index])
|
||||
is CommunityDetailMviModel.Intent.Hide -> hide(post = uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
@ -13,6 +14,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
private const val THRESHOLD = 5f
|
||||
|
||||
@Stable
|
||||
interface FabNestedScrollConnection : NestedScrollConnection {
|
||||
val isFabVisible: StateFlow<Boolean>
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ fun PostCardBody(
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
if (text.isNotEmpty()) {
|
||||
@ -31,11 +31,11 @@ fun PostCardBody(
|
||||
url = url,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator
|
||||
navigator = navigationCoordinator.getRootNavigator()
|
||||
)
|
||||
},
|
||||
onOpenImage = { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.getRootNavigator()?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onClick = onClick,
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ fun PostCardTitle(
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
CustomMarkdown(
|
||||
@ -29,11 +29,11 @@ fun PostCardTitle(
|
||||
url = url,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
onOpenImage = { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.getRootNavigator()?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onClick = onClick,
|
||||
)
|
||||
|
@ -30,7 +30,7 @@ fun PostLinkBanner(
|
||||
url: String,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
if (url.isNotEmpty()) {
|
||||
@ -44,7 +44,7 @@ fun PostLinkBanner(
|
||||
if (settingsRepository.currentSettings.value.openUrlsInExternalBrowser) {
|
||||
uriHandler.openUri(url)
|
||||
} else {
|
||||
navigator?.push(WebViewScreen(url))
|
||||
navigationCoordinator.getRootNavigator()?.push(WebViewScreen(url))
|
||||
}
|
||||
},
|
||||
).padding(
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostSection
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
interface CreateCommentMviModel :
|
||||
MviModel<CreateCommentMviModel.Intent, CreateCommentMviModel.UiState, CreateCommentMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -45,7 +45,6 @@ import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
@ -57,6 +56,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.TextFormattingBar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.RawContentDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
@ -88,7 +88,7 @@ class CreateCommentScreen(
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val galleryHelper = remember { getGalleryHelper() }
|
||||
var openImagePicker by remember { mutableStateOf(false) }
|
||||
@ -109,7 +109,7 @@ class CreateCommentScreen(
|
||||
CreateCommentMviModel.Effect.Success -> {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.CommentCreated)
|
||||
?.also { o -> o.invoke(Unit) }
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
|
||||
is CreateCommentMviModel.Effect.AddImageToText -> {
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
interface CreatePostMviModel :
|
||||
MviModel<CreatePostMviModel.Intent, CreatePostMviModel.UiState, CreatePostMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -51,7 +51,6 @@ import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
@ -60,6 +59,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Progres
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.TextFormattingBar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCreatePostViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.getGalleryHelper
|
||||
@ -89,7 +89,6 @@ class CreatePostScreen(
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val galleryHelper = remember { getGalleryHelper() }
|
||||
var bodyTextFieldValue by remember {
|
||||
@ -98,6 +97,7 @@ class CreatePostScreen(
|
||||
val bodyFocusRequester = remember { FocusRequester() }
|
||||
val urlFocusRequester = remember { FocusRequester() }
|
||||
val focusManager = LocalFocusManager.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.reduce(CreatePostMviModel.Intent.SetTitle(editedPost?.title.orEmpty()))
|
||||
@ -112,7 +112,7 @@ class CreatePostScreen(
|
||||
CreatePostMviModel.Effect.Success -> {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.PostCreated)
|
||||
?.also { o -> o.invoke(Unit) }
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
|
||||
is CreatePostMviModel.Effect.AddImageToBody -> {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.drawer
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.MultiCommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
@ -13,6 +14,7 @@ sealed interface DrawerEvent {
|
||||
data object OpenBookmarks : DrawerEvent
|
||||
}
|
||||
|
||||
@Stable
|
||||
interface DrawerCoordinator {
|
||||
|
||||
val gesturesEnabled: StateFlow<Boolean>
|
||||
|
@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
@ -179,7 +179,7 @@ object ModalDrawerContent : Tab {
|
||||
}
|
||||
}
|
||||
|
||||
itemsIndexed(uiState.multiCommunities) { _, community ->
|
||||
items(uiState.multiCommunities) { community ->
|
||||
MultiCommunityItem(
|
||||
modifier = Modifier.fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
@ -196,7 +196,7 @@ object ModalDrawerContent : Tab {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
)
|
||||
}
|
||||
itemsIndexed(uiState.communities) { _, community ->
|
||||
items(uiState.communities) { community ->
|
||||
CommunityItem(
|
||||
modifier = Modifier.fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.drawer
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.MultiCommunityModel
|
||||
@ -7,6 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
interface ModalDrawerMviModel :
|
||||
MviModel<ModalDrawerMviModel.Intent, ModalDrawerMviModel.UiState, ModalDrawerMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.image
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
|
||||
@Stable
|
||||
interface ZoomableImageMviModel :
|
||||
MviModel<ZoomableImageMviModel.Intent, ZoomableImageMviModel.UiState, ZoomableImageMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -55,7 +55,7 @@ class ZoomableImageScreen(
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val successMessage = stringResource(MR.strings.message_operation_successful)
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
@ -82,7 +82,7 @@ class ZoomableImageScreen(
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
|
||||
@Stable
|
||||
interface InstanceInfoMviModel :
|
||||
MviModel<InstanceInfoMviModel.Intent, InstanceInfoMviModel.UiState, InstanceInfoMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -43,6 +43,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Communi
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ScaledContent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getInstanceInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
@ -61,9 +62,11 @@ class InstanceInfoScreen(
|
||||
val model = rememberScreenModel { getInstanceInfoViewModel(url) }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val instanceName = url.replace("https://", "")
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background)
|
||||
@ -75,7 +78,7 @@ class InstanceInfoScreen(
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -101,7 +104,13 @@ class InstanceInfoScreen(
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.padding(paddingValues)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
@ -143,7 +152,7 @@ class InstanceInfoScreen(
|
||||
CommunityItem(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(
|
||||
community = it,
|
||||
otherInstance = instanceName,
|
||||
|
@ -28,9 +28,9 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
@ -43,7 +43,7 @@ class ColorBottomSheet : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
var customPickerDialogOpened by remember { mutableStateOf(false) }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
@ -101,7 +101,7 @@ class ColorBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(value.first ?: Unit)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
} else {
|
||||
customPickerDialogOpened = true
|
||||
}
|
||||
@ -149,7 +149,7 @@ class ColorBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(color)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -39,7 +39,7 @@ class FontFamilyBottomSheet(
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -80,7 +80,7 @@ class FontFamilyBottomSheet(
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -14,12 +14,12 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.scaleFactor
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -41,7 +41,7 @@ class FontScaleBottomSheet(
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -82,7 +82,7 @@ class FontScaleBottomSheet(
|
||||
?.also {
|
||||
it.invoke(value.scaleFactor)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -14,9 +14,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -27,7 +27,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
class InboxTypeSheet : Screen {
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
|
||||
Column(
|
||||
@ -66,7 +66,7 @@ class InboxTypeSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(true)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
@ -88,7 +88,7 @@ class InboxTypeSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(false)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -14,9 +14,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -29,7 +29,7 @@ class LanguageBottomSheet : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -80,7 +80,7 @@ class LanguageBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -17,9 +17,9 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -35,8 +35,9 @@ class ListingTypeBottomSheet(
|
||||
) : Screen {
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
@ -81,7 +82,7 @@ class ListingTypeBottomSheet(
|
||||
NotificationCenterContractKeys.ChangeFeedType
|
||||
)
|
||||
?.invoke(value)
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -14,11 +14,11 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -30,8 +30,9 @@ class PostLayoutBottomSheet : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(
|
||||
top = Spacing.s,
|
||||
@ -71,7 +72,7 @@ class PostLayoutBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -43,7 +43,7 @@ fun RawContentDialog(
|
||||
onDismiss: (() -> Unit)? = null,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val onSearchLambda = {
|
||||
@ -53,7 +53,7 @@ fun RawContentDialog(
|
||||
url = url,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator
|
||||
navigator = navigationCoordinator.getRootNavigator()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,10 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -83,7 +83,7 @@ internal class SortBottomSheetMain(
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
@ -118,7 +118,7 @@ internal class SortBottomSheetMain(
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -163,7 +163,7 @@ internal class SortBottomSheetTop(
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
|
||||
Column {
|
||||
@ -205,7 +205,7 @@ internal class SortBottomSheetTop(
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -17,12 +17,12 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toIcon
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
@ -34,7 +34,7 @@ class ThemeBottomSheet : Screen {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -80,7 +80,7 @@ class ThemeBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation
|
||||
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -17,6 +18,7 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
|
||||
private var connection: NestedScrollConnection? = null
|
||||
private var navigator: Navigator? = null
|
||||
private var bottomNavigator: BottomSheetNavigator? = null
|
||||
private var currentTab: Tab? = null
|
||||
private val scope = CoroutineScope(SupervisorJob())
|
||||
private var canGoBackCallback: (() -> Boolean)? = null
|
||||
@ -60,4 +62,12 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
override fun setInboxUnread(count: Int) {
|
||||
inboxUnread.value = count
|
||||
}
|
||||
|
||||
override fun setBottomNavigator(value: BottomSheetNavigator?) {
|
||||
bottomNavigator = value
|
||||
}
|
||||
|
||||
override fun getBottomNavigator(): BottomSheetNavigator? {
|
||||
return bottomNavigator
|
||||
}
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
interface NavigationCoordinator {
|
||||
|
||||
val onDoubleTabSelection: Flow<Tab>
|
||||
@ -29,4 +32,8 @@ interface NavigationCoordinator {
|
||||
fun getBottomBarScrollConnection(): NestedScrollConnection?
|
||||
|
||||
fun setInboxUnread(count: Int)
|
||||
|
||||
fun setBottomNavigator(value: BottomSheetNavigator?)
|
||||
|
||||
fun getBottomNavigator(): BottomSheetNavigator?
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
@ -7,6 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
|
||||
@Stable
|
||||
interface PostDetailMviModel :
|
||||
MviModel<PostDetailMviModel.Intent, PostDetailMviModel.UiState, PostDetailMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -22,7 +22,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -71,7 +71,6 @@ import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
@ -97,6 +96,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateRepor
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
@ -136,21 +136,12 @@ class PostDetailScreen(
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val isOnOtherInstance = otherInstance.isNotEmpty()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val fabNestedScrollConnection = remember { getFabNestedScrollConnection() }
|
||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
DisposableEffect(key) {
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
val downvoteColor by themeRepository.downvoteColor.collectAsState()
|
||||
@ -159,12 +150,91 @@ class PostDetailScreen(
|
||||
val lazyListState = rememberLazyListState()
|
||||
val scope = rememberCoroutineScope()
|
||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.Refresh
|
||||
)
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.RefreshPost
|
||||
)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.Refresh
|
||||
)
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.RefreshPost
|
||||
)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach { evt ->
|
||||
when (evt) {
|
||||
PostDetailMviModel.Effect.Close -> {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
}
|
||||
|
||||
is PostDetailMviModel.Effect.ScrollToComment -> {
|
||||
@ -183,8 +253,6 @@ class PostDetailScreen(
|
||||
val statePost = uiState.post
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.padding(Spacing.xs),
|
||||
topBar = {
|
||||
@ -211,16 +279,7 @@ class PostDetailScreen(
|
||||
SortType.Controversial,
|
||||
),
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -229,6 +288,7 @@ class PostDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
@ -258,7 +318,7 @@ class PostDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -270,15 +330,11 @@ class PostDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.Reply,
|
||||
text = stringResource(MR.strings.action_reply),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = statePost,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.CommentCreated)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -295,6 +351,14 @@ class PostDetailScreen(
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.padding(padding)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -310,12 +374,12 @@ class PostDetailScreen(
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = false,
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community = community)
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user = user)
|
||||
)
|
||||
},
|
||||
@ -350,11 +414,7 @@ class PostDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = statePost,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.CommentCreated)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
@ -371,12 +431,7 @@ class PostDetailScreen(
|
||||
4 -> model.reduce(PostDetailMviModel.Intent.DeletePost)
|
||||
|
||||
3 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
}, key, NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = statePost,
|
||||
)
|
||||
@ -384,7 +439,9 @@ class PostDetailScreen(
|
||||
}
|
||||
|
||||
2 -> {
|
||||
bottomSheetNavigator.show(CreateReportScreen(postId = statePost.id))
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(postId = statePost.id)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
@ -395,7 +452,7 @@ class PostDetailScreen(
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -441,11 +498,12 @@ class PostDetailScreen(
|
||||
id = crossPost.id,
|
||||
community = community,
|
||||
)
|
||||
navigator?.push(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
),
|
||||
text = string,
|
||||
@ -465,7 +523,7 @@ class PostDetailScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments, key = { _, c -> c.id }) { _, comment ->
|
||||
items(uiState.comments, key = { c -> c.id }) { comment ->
|
||||
val commentId = comment.id
|
||||
AnimatedVisibility(
|
||||
visible = comment.visible,
|
||||
@ -586,41 +644,34 @@ class PostDetailScreen(
|
||||
originalPost = statePost,
|
||||
originalComment = comment,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.Refresh
|
||||
)
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.RefreshPost
|
||||
)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
screen
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
val user = comment.creator
|
||||
if (user != null) {
|
||||
navigator?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs {
|
||||
val community = comment.community
|
||||
if (community != null) {
|
||||
navigator?.push(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
@ -642,31 +693,21 @@ class PostDetailScreen(
|
||||
)
|
||||
|
||||
2 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.Refresh
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.RefreshPost
|
||||
)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
@ -723,26 +764,20 @@ class PostDetailScreen(
|
||||
originalPost = statePost,
|
||||
originalComment = comment,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
}
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
val user = comment.creator
|
||||
if (user != null) {
|
||||
navigator?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstance,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
@ -762,27 +797,21 @@ class PostDetailScreen(
|
||||
)
|
||||
|
||||
2 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
model.reduce(PostDetailMviModel.Intent.RefreshPost)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -37,19 +37,21 @@ class PostDetailViewModel(
|
||||
private val shareHelper: ShareHelper,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
private val hapticFeedback: HapticFeedback,
|
||||
) : MviModel<PostDetailMviModel.Intent, PostDetailMviModel.UiState, PostDetailMviModel.Effect> by mvi,
|
||||
PostDetailMviModel {
|
||||
) : PostDetailMviModel,
|
||||
MviModel<PostDetailMviModel.Intent, PostDetailMviModel.UiState, PostDetailMviModel.Effect> by mvi {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
private var highlightCommentPath: String? = null
|
||||
private var commentWasHighlighted = false
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.report
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
interface CreateReportMviModel :
|
||||
MviModel<CreateReportMviModel.Intent, CreateReportMviModel.UiState, CreateReportMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -34,13 +34,12 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCreateReportViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.localized
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
@ -64,8 +63,7 @@ class CreateReportScreen(
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
@ -75,7 +73,7 @@ class CreateReportScreen(
|
||||
}
|
||||
|
||||
CreateReportMviModel.Effect.Success -> {
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
@ -8,6 +9,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
|
||||
@Stable
|
||||
interface SavedItemsMviModel :
|
||||
MviModel<SavedItemsMviModel.Intent, SavedItemsMviModel.UiState, SavedItemsMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -17,13 +19,13 @@ interface SavedItemsMviModel :
|
||||
data object LoadNextPage : Intent
|
||||
data class ChangeSort(val value: SortType) : Intent
|
||||
data class ChangeSection(val section: SavedItemsSection) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class UpVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data class UpVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
@ -33,6 +33,7 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -47,7 +48,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
@ -70,6 +70,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateRepor
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
@ -88,8 +89,7 @@ class SavedItemsScreen : Screen {
|
||||
val model = rememberScreenModel { getSavedItemsViewModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigatorCoordinator = remember { getNavigationCoordinator() }
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
@ -99,18 +99,31 @@ class SavedItemsScreen : Screen {
|
||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
notificationCenter.removeObserver(key)
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
onDispose {
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection),
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
scrollBehavior = scrollBehavior,
|
||||
@ -131,16 +144,7 @@ class SavedItemsScreen : Screen {
|
||||
SortType.Old,
|
||||
),
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -152,7 +156,7 @@ class SavedItemsScreen : Screen {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigatorCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -177,7 +181,7 @@ class SavedItemsScreen : Screen {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -191,7 +195,15 @@ class SavedItemsScreen : Screen {
|
||||
},
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
) {
|
||||
SectionSelector(
|
||||
@ -227,7 +239,7 @@ class SavedItemsScreen : Screen {
|
||||
modifier = Modifier.padding(horizontal = Spacing.xxxs),
|
||||
) {
|
||||
if (uiState.section == SavedItemsSection.Posts) {
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
PostCard(
|
||||
post = post,
|
||||
postLayout = uiState.postLayout,
|
||||
@ -236,24 +248,25 @@ class SavedItemsScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = {
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = { community ->
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = { u ->
|
||||
if (u.id != uiState.user?.id) {
|
||||
navigator?.push(UserDetailScreen(u))
|
||||
navigatorCoordinator.getRootNavigator()
|
||||
?.push(UserDetailScreen(u))
|
||||
}
|
||||
},
|
||||
onUpVote = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -261,7 +274,7 @@ class SavedItemsScreen : Screen {
|
||||
onDownVote = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -269,7 +282,7 @@ class SavedItemsScreen : Screen {
|
||||
onSave = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -278,10 +291,10 @@ class SavedItemsScreen : Screen {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onImageClick = { url ->
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -293,7 +306,7 @@ class SavedItemsScreen : Screen {
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
2 -> {
|
||||
bottomSheetNavigator.show(
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
@ -305,7 +318,11 @@ class SavedItemsScreen : Screen {
|
||||
}
|
||||
|
||||
else -> {
|
||||
model.reduce(SavedItemsMviModel.Intent.SharePost(idx))
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.SharePost(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -330,14 +347,14 @@ class SavedItemsScreen : Screen {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
items(uiState.comments) { comment ->
|
||||
CommentCard(
|
||||
comment = comment,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
hideIndent = true,
|
||||
onClick = {
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
@ -347,7 +364,7 @@ class SavedItemsScreen : Screen {
|
||||
onUpVote = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.UpVoteComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -355,7 +372,7 @@ class SavedItemsScreen : Screen {
|
||||
onDownVote = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.DownVoteComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -363,7 +380,7 @@ class SavedItemsScreen : Screen {
|
||||
onSave = {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.SaveComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -373,7 +390,7 @@ class SavedItemsScreen : Screen {
|
||||
originalPost = PostModel(id = comment.postId),
|
||||
originalComment = comment,
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
@ -382,7 +399,7 @@ class SavedItemsScreen : Screen {
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
1 -> {
|
||||
bottomSheetNavigator.show(
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
|
@ -41,11 +41,13 @@ class SavedItemsViewModel(
|
||||
private var currentPage: Int = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -80,37 +82,39 @@ class SavedItemsViewModel(
|
||||
SavedItemsMviModel.Intent.Refresh -> refresh()
|
||||
is SavedItemsMviModel.Intent.ChangeSection -> changeSection(intent.section)
|
||||
is SavedItemsMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.DownVotePost -> toggleDownVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.SaveComment -> toggleSaveComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.SavePost -> toggleSavePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.UpVotePost -> toggleUpVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is SavedItemsMviModel.Intent.ChangeSort -> applySortType(intent.value)
|
||||
is SavedItemsMviModel.Intent.SharePost -> share(post = uiState.value.posts[intent.index])
|
||||
is SavedItemsMviModel.Intent.SharePost -> share(
|
||||
post = uiState.value.posts.first { it.id == intent.id }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
@ -8,6 +9,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
|
||||
@Stable
|
||||
interface UserDetailMviModel :
|
||||
MviModel<UserDetailMviModel.Intent, UserDetailMviModel.UiState, UserDetailMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -17,14 +19,14 @@ interface UserDetailMviModel :
|
||||
data object Refresh : Intent
|
||||
data object LoadNextPage : Intent
|
||||
data class ChangeSection(val section: UserDetailSection) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data object Block : Intent
|
||||
data object BlockInstance : Intent
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -59,7 +59,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
@ -88,6 +87,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateReportScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
@ -121,8 +121,6 @@ class UserDetailScreen(
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val successMessage = stringResource(MR.strings.message_operation_successful)
|
||||
val isOnOtherInstance = otherInstance.isNotEmpty()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
@ -133,8 +131,11 @@ class UserDetailScreen(
|
||||
val downvoteColor by themeRepository.downvoteColor.collectAsState()
|
||||
val defaultUpvoteColor = MaterialTheme.colorScheme.primary
|
||||
val defaultDownVoteColor = MaterialTheme.colorScheme.tertiary
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
@ -143,6 +144,33 @@ class UserDetailScreen(
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(UserDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(UserDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
@ -166,8 +194,6 @@ class UserDetailScreen(
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.padding(Spacing.xs),
|
||||
topBar = {
|
||||
val userName = user.name
|
||||
@ -194,16 +220,7 @@ class UserDetailScreen(
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -212,6 +229,7 @@ class UserDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
@ -242,7 +260,7 @@ class UserDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -254,9 +272,9 @@ class UserDetailScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.Chat,
|
||||
text = stringResource(MR.strings.action_chat),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
val screen = InboxChatScreen(otherUserId = user.id)
|
||||
navigator?.push(screen)
|
||||
navigationCoordinator.getRootNavigator()?.push(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -277,6 +295,14 @@ class UserDetailScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -295,7 +321,8 @@ class UserDetailScreen(
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
),
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
@ -337,7 +364,7 @@ class UserDetailScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
@ -377,12 +404,12 @@ class UserDetailScreen(
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVotePost(idx),
|
||||
UserDetailMviModel.Intent.UpVotePost(post.id),
|
||||
)
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.DownVotePost(idx),
|
||||
UserDetailMviModel.Intent.DownVotePost(post.id),
|
||||
)
|
||||
},
|
||||
content = {
|
||||
@ -395,7 +422,8 @@ class UserDetailScreen(
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(PostDetailScreen(post = post))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(PostDetailScreen(post = post))
|
||||
},
|
||||
onUpVote = if (isOnOtherInstance) {
|
||||
null
|
||||
@ -403,7 +431,7 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -415,7 +443,7 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -427,14 +455,15 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(CommunityDetailScreen(community))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(CommunityDetailScreen(community))
|
||||
},
|
||||
onReply = if (isOnOtherInstance) {
|
||||
null
|
||||
@ -443,18 +472,12 @@ class UserDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(UserDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -466,11 +489,12 @@ class UserDetailScreen(
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
@ -478,7 +502,7 @@ class UserDetailScreen(
|
||||
}
|
||||
|
||||
else -> model.reduce(
|
||||
UserDetailMviModel.Intent.SharePost(idx)
|
||||
UserDetailMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
}
|
||||
})
|
||||
@ -512,7 +536,7 @@ class UserDetailScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
items(uiState.comments) { comment ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
@ -551,12 +575,12 @@ class UserDetailScreen(
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVoteComment(idx),
|
||||
UserDetailMviModel.Intent.UpVoteComment(comment.id),
|
||||
)
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.DownVoteComment(idx),
|
||||
UserDetailMviModel.Intent.DownVoteComment(comment.id),
|
||||
)
|
||||
},
|
||||
content = {
|
||||
@ -569,7 +593,7 @@ class UserDetailScreen(
|
||||
hideAuthor = true,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
@ -582,7 +606,7 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.SaveComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -594,7 +618,7 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVoteComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -606,7 +630,7 @@ class UserDetailScreen(
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.DownVoteComment(
|
||||
index = idx,
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -620,18 +644,13 @@ class UserDetailScreen(
|
||||
originalPost = PostModel(id = comment.postId),
|
||||
originalComment = comment,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(UserDetailMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(CommunityDetailScreen(community))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(CommunityDetailScreen(community))
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
@ -640,11 +659,12 @@ class UserDetailScreen(
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
1 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -45,11 +45,13 @@ class UserDetailViewModel(
|
||||
private var currentPage = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -92,13 +94,13 @@ class UserDetailViewModel(
|
||||
is UserDetailMviModel.Intent.ChangeSort -> applySortType(intent.value)
|
||||
is UserDetailMviModel.Intent.ChangeSection -> changeSection(intent.section)
|
||||
is UserDetailMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is UserDetailMviModel.Intent.DownVotePost -> {
|
||||
toggleDownVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
}
|
||||
@ -107,27 +109,27 @@ class UserDetailViewModel(
|
||||
UserDetailMviModel.Intent.LoadNextPage -> loadNextPage()
|
||||
UserDetailMviModel.Intent.Refresh -> refresh()
|
||||
is UserDetailMviModel.Intent.SaveComment -> toggleSaveComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is UserDetailMviModel.Intent.SavePost -> toggleSave(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is UserDetailMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is UserDetailMviModel.Intent.UpVotePost -> toggleUpVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is UserDetailMviModel.Intent.SharePost -> share(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
)
|
||||
|
||||
UserDetailMviModel.Intent.Block -> blockUser()
|
||||
|
@ -33,7 +33,7 @@ class WebViewScreen(
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
var shareHelper = remember { getShareHelper() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
@ -54,7 +54,7 @@ class WebViewScreen(
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.notifications
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
|
||||
/**
|
||||
* Utility to publish and subscribe for broadcast notifications.
|
||||
*/
|
||||
@Stable
|
||||
interface NotificationCenter {
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.home.postlist
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
@ -7,6 +8,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
|
||||
@Stable
|
||||
interface PostListMviModel :
|
||||
MviModel<PostListMviModel.Intent, PostListMviModel.UiState, PostListMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -16,15 +18,15 @@ interface PostListMviModel :
|
||||
data object LoadNextPage : Intent
|
||||
data class ChangeSort(val value: SortType) : Intent
|
||||
data class ChangeListing(val value: ListingType) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class HandlePostUpdate(val post: PostModel) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class DeletePost(val id: Int) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class MarkAsRead(val index: Int) : Intent
|
||||
data class Hide(val index: Int) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data class MarkAsRead(val id: Int) : Intent
|
||||
data class Hide(val id: Int) : Intent
|
||||
data object ClearRead : Intent
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -49,7 +49,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Dimensions
|
||||
@ -61,7 +60,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Floatin
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getFabNestedScrollConnection
|
||||
@ -97,13 +95,11 @@ class PostListScreen : Screen {
|
||||
val model = rememberScreenModel { getHomeScreenModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val fabNestedScrollConnection = remember { getFabNestedScrollConnection() }
|
||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
@ -122,7 +118,7 @@ class PostListScreen : Screen {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(navigator) {
|
||||
LaunchedEffect(Unit) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach { tab ->
|
||||
if (tab == HomeTab) {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -140,20 +136,41 @@ class PostListScreen : Screen {
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(PostListMviModel.Intent.ChangeListing(it))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.ChangeSort(sortType)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostListMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostListMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.padding(Spacing.xxs)
|
||||
.let {
|
||||
val connection = navigationCoordinator.getBottomBarScrollConnection()
|
||||
if (connection != null && settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(connection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
modifier = Modifier.padding(Spacing.xxs),
|
||||
topBar = {
|
||||
PostsTopBar(
|
||||
currentInstance = uiState.instance,
|
||||
@ -169,25 +186,13 @@ class PostListScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(PostListMviModel.Intent.ChangeListing(it))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
onSelectSortType = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.ChangeSort(sortType)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
},
|
||||
@ -207,7 +212,7 @@ class PostListScreen : Screen {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -218,7 +223,7 @@ class PostListScreen : Screen {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(PostListMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -241,6 +246,22 @@ class PostListScreen : Screen {
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.fillMaxWidth()
|
||||
.let {
|
||||
val connection = navigationCoordinator.getBottomBarScrollConnection()
|
||||
if (connection != null && settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(connection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -258,7 +279,7 @@ class PostListScreen : Screen {
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
@ -273,14 +294,14 @@ class PostListScreen : Screen {
|
||||
DismissValue.Default -> Color.Transparent
|
||||
}
|
||||
},
|
||||
onGestureBegin = rememberCallback(model) {
|
||||
onGestureBegin = {
|
||||
model.reduce(PostListMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(PostListMviModel.Intent.UpVotePost(idx))
|
||||
model.reduce(PostListMviModel.Intent.UpVotePost(post.id))
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(PostListMviModel.Intent.DownVotePost(idx))
|
||||
model.reduce(PostListMviModel.Intent.DownVotePost(post.id))
|
||||
},
|
||||
swipeContent = { direction ->
|
||||
val icon = when (direction) {
|
||||
@ -302,25 +323,25 @@ class PostListScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(idx))
|
||||
navigator?.push(
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -328,7 +349,7 @@ class PostListScreen : Screen {
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -336,27 +357,22 @@ class PostListScreen : Screen {
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = rememberCallback(model) {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostListMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
},
|
||||
// onReply = rememberCallback(model) {
|
||||
// val screen = CreateCommentScreen(
|
||||
// originalPost = post,
|
||||
// )
|
||||
// bottomSheetNavigator.show(screen)
|
||||
// },
|
||||
onImageClick = rememberCallbackArgs(model) { url ->
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(idx))
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url)
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
@ -375,32 +391,27 @@ class PostListScreen : Screen {
|
||||
)
|
||||
|
||||
4 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(PostListMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
bottomSheetNavigator.show(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
1 -> model.reduce(PostListMviModel.Intent.Hide(idx))
|
||||
1 -> model.reduce(PostListMviModel.Intent.Hide(post.id))
|
||||
|
||||
else -> model.reduce(
|
||||
PostListMviModel.Intent.SharePost(idx)
|
||||
PostListMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -45,23 +45,31 @@ class PostListViewModel(
|
||||
private var hideReadPosts = false
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated)
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostDelete(post.id)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostDeleted)
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver({
|
||||
// apply new feed and sort type
|
||||
firstLoad = true
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.ResetContents)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostDelete(post.id)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostDeleted
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
// apply new feed and sort type
|
||||
firstLoad = true
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.ResetContents
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -134,17 +142,17 @@ class PostListViewModel(
|
||||
is PostListMviModel.Intent.ChangeSort -> applySortType(intent.value)
|
||||
is PostListMviModel.Intent.ChangeListing -> applyListingType(intent.value)
|
||||
is PostListMviModel.Intent.DownVotePost -> toggleDownVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is PostListMviModel.Intent.SavePost -> toggleSave(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is PostListMviModel.Intent.UpVotePost -> toggleUpVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
@ -152,15 +160,15 @@ class PostListViewModel(
|
||||
is PostListMviModel.Intent.HandlePostUpdate -> handlePostUpdate(intent.post)
|
||||
is PostListMviModel.Intent.DeletePost -> handlePostDelete(intent.id)
|
||||
is PostListMviModel.Intent.SharePost -> {
|
||||
share(post = uiState.value.posts[intent.index])
|
||||
share(post = uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
|
||||
is PostListMviModel.Intent.MarkAsRead -> {
|
||||
markAsRead(post = uiState.value.posts[intent.index])
|
||||
markAsRead(post = uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
|
||||
PostListMviModel.Intent.ClearRead -> clearRead()
|
||||
is PostListMviModel.Intent.Hide -> hide(post = uiState.value.posts[intent.index])
|
||||
is PostListMviModel.Intent.Hide -> hide(post = uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.CurrentScreen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||
@ -35,9 +34,11 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.InboxTypeSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxViewModel
|
||||
@ -66,16 +67,30 @@ object InboxScreen : Tab {
|
||||
val model = rememberScreenModel { getInboxViewModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? Boolean)?.also { value ->
|
||||
model.reduce(
|
||||
InboxMviModel.Intent.ChangeUnreadOnly(value)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeInboxType
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.padding(Spacing.xxs),
|
||||
@ -115,14 +130,7 @@ object InboxScreen : Tab {
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
val sheet = InboxTypeSheet()
|
||||
notificationCenter.addObserver({
|
||||
(it as? Boolean)?.also { value ->
|
||||
model.reduce(
|
||||
InboxMviModel.Intent.ChangeUnreadOnly(value)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeInboxType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
text = text,
|
||||
@ -162,7 +170,13 @@ object InboxScreen : Tab {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
},
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
) {
|
||||
SectionSelector(
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.mentions
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionModel
|
||||
|
||||
@Stable
|
||||
interface InboxMentionsMviModel :
|
||||
MviModel<InboxMentionsMviModel.Intent, InboxMentionsMviModel.UiState, InboxMentionsMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -12,10 +14,10 @@ interface InboxMentionsMviModel :
|
||||
sealed interface Intent {
|
||||
data object Refresh : Intent
|
||||
data object LoadNextPage : Intent
|
||||
data class MarkAsRead(val read: Boolean, val index: Int) : Intent
|
||||
data class MarkAsRead(val read: Boolean, val id: Int) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class UpVoteComment(val index: Int) : Intent
|
||||
data class DownVoteComment(val index: Int) : Intent
|
||||
data class UpVoteComment(val id: Int) : Intent
|
||||
data class DownVoteComment(val id: Int) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -73,8 +73,8 @@ class InboxMentionsScreen : Tab {
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
LaunchedEffect(navigationCoordinator) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach {
|
||||
if (it == InboxTab) {
|
||||
@ -129,7 +129,7 @@ class InboxMentionsScreen : Tab {
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.mentions) { idx, mention ->
|
||||
items(uiState.mentions) { mention ->
|
||||
val endColor = MaterialTheme.colorScheme.secondary
|
||||
val startColor = MaterialTheme.colorScheme.tertiary
|
||||
SwipeableCard(
|
||||
@ -149,7 +149,7 @@ class InboxMentionsScreen : Tab {
|
||||
model.reduce(
|
||||
InboxMentionsMviModel.Intent.MarkAsRead(
|
||||
read = true,
|
||||
index = idx,
|
||||
id = mention.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -157,7 +157,7 @@ class InboxMentionsScreen : Tab {
|
||||
model.reduce(
|
||||
InboxMentionsMviModel.Intent.MarkAsRead(
|
||||
read = false,
|
||||
index = idx,
|
||||
id = mention.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -181,7 +181,7 @@ class InboxMentionsScreen : Tab {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
onOpenPost = rememberCallbackArgs { post ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
highlightCommentId = mention.comment.id,
|
||||
@ -189,20 +189,24 @@ class InboxMentionsScreen : Tab {
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallbackArgs(model) {
|
||||
model.reduce(InboxMentionsMviModel.Intent.UpVoteComment(idx))
|
||||
model.reduce(InboxMentionsMviModel.Intent.UpVoteComment(mention.id))
|
||||
},
|
||||
onDownVote = rememberCallbackArgs(model) {
|
||||
model.reduce(InboxMentionsMviModel.Intent.DownVoteComment(idx))
|
||||
model.reduce(
|
||||
InboxMentionsMviModel.Intent.DownVoteComment(
|
||||
mention.id
|
||||
)
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -36,9 +36,11 @@ class InboxMentionsViewModel(
|
||||
private var currentPage: Int = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -81,18 +83,18 @@ class InboxMentionsViewModel(
|
||||
is InboxMentionsMviModel.Intent.MarkAsRead -> {
|
||||
markAsRead(
|
||||
read = intent.read,
|
||||
mention = mvi.uiState.value.mentions[intent.index],
|
||||
mention = uiState.value.mentions.first { it.id == intent.id },
|
||||
)
|
||||
}
|
||||
|
||||
InboxMentionsMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||
is InboxMentionsMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
mention = mvi.uiState.value.mentions[intent.index],
|
||||
mention = uiState.value.mentions.first { it.id == intent.id },
|
||||
feedback = true,
|
||||
)
|
||||
|
||||
is InboxMentionsMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
mention = mvi.uiState.value.mentions[intent.index],
|
||||
mention = uiState.value.mentions.first { it.id == intent.id },
|
||||
feedback = true,
|
||||
)
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PrivateMessageModel
|
||||
|
||||
@Stable
|
||||
interface InboxMessagesMviModel :
|
||||
MviModel<InboxMessagesMviModel.Intent, InboxMessagesMviModel.UiState, InboxMessagesMviModel.Effect>,
|
||||
ScreenModel {
|
||||
|
@ -36,6 +36,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.chat.InboxChatScre
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.di.getInboxMessagesViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.ui.InboxTab
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
@ -57,7 +58,6 @@ class InboxMessagesScreen : Tab {
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val lazyListState = rememberLazyListState()
|
||||
LaunchedEffect(navigationCoordinator) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach {
|
||||
@ -117,15 +117,15 @@ class InboxMessagesScreen : Tab {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
lastMessage = chat.content.orEmpty(),
|
||||
lastMessageDate = chat.publishDate,
|
||||
onOpenUser = { user ->
|
||||
navigator?.push(
|
||||
onOpenUser = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user)
|
||||
)
|
||||
},
|
||||
onOpen = {
|
||||
onOpen = rememberCallback {
|
||||
val userId = otherUser?.id
|
||||
if (userId != null) {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
InboxChatScreen(userId)
|
||||
)
|
||||
}
|
||||
|
@ -32,9 +32,11 @@ class InboxMessagesViewModel(
|
||||
private var currentPage: Int = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.replies
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionModel
|
||||
|
||||
@Stable
|
||||
interface InboxRepliesMviModel :
|
||||
MviModel<InboxRepliesMviModel.Intent, InboxRepliesMviModel.UiState, InboxRepliesMviModel.Effect>,
|
||||
ScreenModel {
|
||||
@ -12,10 +14,10 @@ interface InboxRepliesMviModel :
|
||||
sealed interface Intent {
|
||||
data object Refresh : Intent
|
||||
data object LoadNextPage : Intent
|
||||
data class MarkAsRead(val read: Boolean, val index: Int) : Intent
|
||||
data class MarkAsRead(val read: Boolean, val id: Int) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class UpVoteComment(val index: Int) : Intent
|
||||
data class DownVoteComment(val index: Int) : Intent
|
||||
data class UpVoteComment(val id: Int) : Intent
|
||||
data class DownVoteComment(val id: Int) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -9,7 +9,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -72,8 +72,8 @@ class InboxRepliesScreen : Tab {
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val lazyListState = rememberLazyListState()
|
||||
|
||||
LaunchedEffect(navigationCoordinator) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach {
|
||||
if (it == InboxTab) {
|
||||
@ -128,7 +128,7 @@ class InboxRepliesScreen : Tab {
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.replies) { idx, mention ->
|
||||
items(uiState.replies) { reply ->
|
||||
val endColor = MaterialTheme.colorScheme.secondary
|
||||
val startColor = MaterialTheme.colorScheme.tertiary
|
||||
SwipeableCard(
|
||||
@ -148,7 +148,7 @@ class InboxRepliesScreen : Tab {
|
||||
model.reduce(
|
||||
InboxRepliesMviModel.Intent.MarkAsRead(
|
||||
read = true,
|
||||
index = idx,
|
||||
id = reply.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -156,7 +156,7 @@ class InboxRepliesScreen : Tab {
|
||||
model.reduce(
|
||||
InboxRepliesMviModel.Intent.MarkAsRead(
|
||||
read = false,
|
||||
index = idx,
|
||||
id = reply.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -174,34 +174,34 @@ class InboxRepliesScreen : Tab {
|
||||
},
|
||||
content = {
|
||||
InboxCard(
|
||||
mention = mention,
|
||||
mention = reply,
|
||||
postLayout = uiState.postLayout,
|
||||
type = InboxCardType.Reply,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
onOpenPost = rememberCallbackArgs { post ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
highlightCommentId = mention.comment.id,
|
||||
highlightCommentId = reply.comment.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallbackArgs(model) {
|
||||
model.reduce(InboxRepliesMviModel.Intent.UpVoteComment(idx))
|
||||
model.reduce(InboxRepliesMviModel.Intent.UpVoteComment(reply.id))
|
||||
},
|
||||
onDownVote = rememberCallbackArgs(model) {
|
||||
model.reduce(InboxRepliesMviModel.Intent.DownVoteComment(idx))
|
||||
model.reduce(InboxRepliesMviModel.Intent.DownVoteComment(reply.id))
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -39,9 +39,11 @@ class InboxRepliesViewModel(
|
||||
private var currentUserId: Int? = null
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -85,19 +87,19 @@ class InboxRepliesViewModel(
|
||||
is InboxRepliesMviModel.Intent.MarkAsRead -> {
|
||||
markAsRead(
|
||||
read = intent.read,
|
||||
mention = mvi.uiState.value.replies[intent.index]
|
||||
mention = uiState.value.replies.first { it.id == intent.id },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
InboxRepliesMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||
is InboxRepliesMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
mention = mvi.uiState.value.replies[intent.index],
|
||||
mention = uiState.value.replies.first { it.id == intent.id },
|
||||
feedback = true,
|
||||
)
|
||||
|
||||
is InboxRepliesMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
mention = mvi.uiState.value.replies[intent.index],
|
||||
mention = uiState.value.replies.first { it.id == intent.id },
|
||||
feedback = true,
|
||||
)
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ interface ProfileLoggedMviModel :
|
||||
data object LoadNextPage : Intent
|
||||
data class DeletePost(val id: Int) : Intent
|
||||
data class DeleteComment(val id: Int) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
|
||||
data class SaveComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Text
|
||||
@ -34,7 +34,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
@ -82,12 +81,10 @@ internal object ProfileLoggedScreen : Tab {
|
||||
val user = uiState.user
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val lazyListState = rememberLazyListState()
|
||||
var rawContent by remember { mutableStateOf<Any?>(null) }
|
||||
|
||||
LaunchedEffect(navigator) {
|
||||
LaunchedEffect(Unit) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach { tab ->
|
||||
if (tab == ProfileTab) {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -99,6 +96,22 @@ internal object ProfileLoggedScreen : Tab {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ProfileLoggedMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ProfileLoggedMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
|
||||
if (user != null) {
|
||||
Column(
|
||||
@ -127,7 +140,8 @@ internal object ProfileLoggedScreen : Tab {
|
||||
user = user,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigator?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
)
|
||||
SectionSelector(
|
||||
@ -167,7 +181,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
PostCard(
|
||||
post = post,
|
||||
postLayout = uiState.postLayout,
|
||||
@ -177,41 +191,41 @@ internal object ProfileLoggedScreen : Tab {
|
||||
hideAuthor = true,
|
||||
blurNsfw = false,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.UpVotePost(
|
||||
idx,
|
||||
true
|
||||
id = post.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.DownVotePost(
|
||||
idx,
|
||||
true
|
||||
id = post.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.SavePost(
|
||||
idx,
|
||||
true
|
||||
id = post.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -228,14 +242,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
|
||||
2 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ProfileLoggedMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.PostCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
)
|
||||
@ -247,7 +254,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
|
||||
else -> model.reduce(
|
||||
ProfileLoggedMviModel.Intent.SharePost(idx)
|
||||
ProfileLoggedMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -281,7 +288,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.comments) { idx, comment ->
|
||||
items(uiState.comments) { comment ->
|
||||
CommentCard(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
comment = comment,
|
||||
@ -291,7 +298,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
hideAuthor = true,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
@ -301,24 +308,24 @@ internal object ProfileLoggedScreen : Tab {
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.UpVoteComment(
|
||||
idx,
|
||||
true
|
||||
id = comment.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.DownVoteComment(
|
||||
idx,
|
||||
true
|
||||
id = comment.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.SaveComment(
|
||||
idx,
|
||||
true
|
||||
id = comment.id,
|
||||
feedback = true
|
||||
)
|
||||
)
|
||||
},
|
||||
@ -338,14 +345,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
|
||||
1 -> {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ProfileLoggedMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
|
@ -46,16 +46,20 @@ class ProfileLoggedViewModel(
|
||||
private var currentPage = 1
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated)
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostDelete(post.id)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostDeleted)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdated
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostDelete(post.id)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostDeleted
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -112,36 +116,36 @@ class ProfileLoggedViewModel(
|
||||
}
|
||||
|
||||
is ProfileLoggedMviModel.Intent.SharePost -> share(
|
||||
post = uiState.value.posts[intent.index]
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.DownVotePost -> toggleDownVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.SaveComment -> toggleSaveComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.SavePost -> toggleSavePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
comment = uiState.value.comments[intent.index],
|
||||
comment = uiState.value.comments.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ProfileLoggedMviModel.Intent.UpVotePost -> toggleUpVotePost(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
@ -74,7 +73,7 @@ class LoginBottomSheet : Screen {
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
@ -86,14 +85,13 @@ class LoginBottomSheet : Screen {
|
||||
}
|
||||
|
||||
LoginBottomSheetMviModel.Effect.LoginSuccess -> {
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
Box(
|
||||
@ -125,12 +123,12 @@ class LoginBottomSheet : Screen {
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
onClick = {
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
handleUrl(
|
||||
url = HELP_URL,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
) {
|
||||
|
@ -28,7 +28,6 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.CurrentScreen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||
@ -36,6 +35,8 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.profile.di.getProfileScreenModel
|
||||
@ -66,9 +67,11 @@ internal object ProfileMainScreen : Tab {
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.padding(Spacing.xxs),
|
||||
@ -106,7 +109,8 @@ internal object ProfileMainScreen : Tab {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
bottomSheetNavigator.show(ManageAccountsScreen())
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(ManageAccountsScreen())
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ManageAccounts,
|
||||
@ -130,11 +134,17 @@ internal object ProfileMainScreen : Tab {
|
||||
},
|
||||
)
|
||||
},
|
||||
) {
|
||||
) { paddinValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.padding(it),
|
||||
.padding(paddinValues)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
// wait until logging status is determined
|
||||
|
@ -28,6 +28,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@ -36,11 +37,11 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.profile.di.getManageAccountsViewModel
|
||||
@ -57,13 +58,13 @@ class ManageAccountsScreen : Screen {
|
||||
val model = rememberScreenModel { getManageAccountsViewModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
ManageAccountsMviModel.Effect.Close -> {
|
||||
bottomSheetNavigator.hide()
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -151,7 +152,7 @@ class ManageAccountsScreen : Screen {
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
Button(
|
||||
onClick = {
|
||||
bottomSheetNavigator.show(LoginBottomSheet())
|
||||
navigationCoordinator.getBottomNavigator()?.show(LoginBottomSheet())
|
||||
},
|
||||
) {
|
||||
Row(
|
||||
|
@ -9,12 +9,13 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.profile.login.LoginBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
@ -28,7 +29,8 @@ internal object ProfileNotLoggedScreen : Tab {
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.m),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
@ -40,7 +42,7 @@ internal object ProfileNotLoggedScreen : Tab {
|
||||
Button(
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
onClick = {
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
LoginBottomSheet(),
|
||||
)
|
||||
},
|
||||
|
@ -16,12 +16,12 @@ interface ExploreMviModel :
|
||||
data class SetListingType(val value: ListingType) : Intent
|
||||
data class SetSortType(val value: SortType) : Intent
|
||||
data class SetResultType(val value: SearchResultType) : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class UpVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVoteComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SaveComment(val id: Int, val feedback: Boolean = false) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
@ -51,7 +51,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
@ -71,6 +70,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
@ -98,8 +98,6 @@ class ExploreScreen : Screen {
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
@ -114,13 +112,40 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
}
|
||||
}
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(ExploreMviModel.Intent.SetListingType(it))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SetSortType(sortType)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ExploreMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
val lazyListState = rememberLazyListState()
|
||||
LaunchedEffect(navigator) {
|
||||
LaunchedEffect(Unit) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach { tab ->
|
||||
if (tab == ExploreTab) {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -140,10 +165,7 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.padding(Spacing.xxs)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(keyboardScrollConnection),
|
||||
modifier = Modifier.padding(Spacing.xxs),
|
||||
topBar = {
|
||||
ExploreTopBar(
|
||||
scrollBehavior = scrollBehavior,
|
||||
@ -154,26 +176,14 @@ class ExploreScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(ExploreMviModel.Intent.SetListingType(it))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
onSelectSortType = rememberCallback {
|
||||
focusManager.clearFocus()
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SetSortType(sortType)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
onHamburgerTapped = rememberCallback {
|
||||
scope.launch {
|
||||
@ -265,7 +275,16 @@ class ExploreScreen : Screen {
|
||||
{ model.reduce(ExploreMviModel.Intent.Refresh) },
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.padding(Spacing.xxs).pullRefresh(pullRefreshState),
|
||||
modifier = Modifier.padding(Spacing.xxs)
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(keyboardScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
state = lazyListState,
|
||||
@ -282,7 +301,7 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.results) { idx, result ->
|
||||
items(uiState.results) { result ->
|
||||
when (result) {
|
||||
is CommunityModel -> {
|
||||
CommunityItem(
|
||||
@ -290,7 +309,7 @@ class ExploreScreen : Screen {
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(result),
|
||||
)
|
||||
},
|
||||
@ -309,24 +328,24 @@ class ExploreScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(result),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -334,7 +353,7 @@ class ExploreScreen : Screen {
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -342,7 +361,7 @@ class ExploreScreen : Screen {
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -351,17 +370,10 @@ class ExploreScreen : Screen {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = result,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ExploreMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -381,7 +393,7 @@ class ExploreScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = result.postId),
|
||||
highlightCommentId = result.id,
|
||||
@ -391,7 +403,7 @@ class ExploreScreen : Screen {
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVoteComment(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -399,7 +411,7 @@ class ExploreScreen : Screen {
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVoteComment(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -407,7 +419,7 @@ class ExploreScreen : Screen {
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SaveComment(
|
||||
index = idx,
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -417,22 +429,15 @@ class ExploreScreen : Screen {
|
||||
originalPost = PostModel(id = result.postId),
|
||||
originalComment = result,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(ExploreMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(it)
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(it)
|
||||
)
|
||||
},
|
||||
@ -449,7 +454,7 @@ class ExploreScreen : Screen {
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(result),
|
||||
)
|
||||
},
|
||||
|
@ -49,13 +49,17 @@ class ExploreViewModel(
|
||||
private var firstLoad = true
|
||||
|
||||
init {
|
||||
notificationCenter.addObserver({
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout)
|
||||
notificationCenter.addObserver({
|
||||
// apply new feed and sort type
|
||||
firstLoad = true
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.ResetContents)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
handleLogout()
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.Logout
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
// apply new feed and sort type
|
||||
firstLoad = true
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.ResetContents
|
||||
)
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
@ -127,32 +131,32 @@ class ExploreViewModel(
|
||||
is ExploreMviModel.Intent.SetSortType -> changeSortType(intent.value)
|
||||
is ExploreMviModel.Intent.SetResultType -> changeResultType(intent.value)
|
||||
is ExploreMviModel.Intent.DownVotePost -> toggleDownVote(
|
||||
post = uiState.value.results[intent.index] as PostModel,
|
||||
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ExploreMviModel.Intent.SavePost -> toggleSave(
|
||||
post = uiState.value.results[intent.index] as PostModel,
|
||||
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ExploreMviModel.Intent.UpVotePost -> toggleUpVote(
|
||||
post = uiState.value.results[intent.index] as PostModel,
|
||||
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ExploreMviModel.Intent.DownVoteComment -> toggleDownVoteComment(
|
||||
comment = uiState.value.results[intent.index] as CommentModel,
|
||||
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ExploreMviModel.Intent.SaveComment -> toggleSaveComment(
|
||||
comment = uiState.value.results[intent.index] as CommentModel,
|
||||
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is ExploreMviModel.Intent.UpVoteComment -> toggleUpVoteComment(
|
||||
comment = uiState.value.results[intent.index] as CommentModel,
|
||||
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel,
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ interface ManageSubscriptionsMviModel :
|
||||
sealed interface Intent {
|
||||
data object Refresh : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class Unsubscribe(val index: Int) : Intent
|
||||
data class DeleteMultiCommunity(val index: Int) : Intent
|
||||
data class Unsubscribe(val id: Int) : Intent
|
||||
data class DeleteMultiCommunity(val id: Int) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -78,7 +78,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
val model = rememberScreenModel { getManageSubscriptionsViewModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigatorCoordinator = remember { getNavigationCoordinator() }
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val lazyListState = rememberLazyListState()
|
||||
@ -94,9 +94,6 @@ class ManageSubscriptionsScreen : Screen {
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection),
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
@ -111,7 +108,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigatorCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -136,7 +133,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -156,7 +153,10 @@ class ManageSubscriptionsScreen : Screen {
|
||||
},
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -178,7 +178,9 @@ class ManageSubscriptionsScreen : Screen {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(MultiCommunityEditorScreen())
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
MultiCommunityEditorScreen()
|
||||
)
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.AddCircle,
|
||||
@ -187,7 +189,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.multiCommunities) { idx, community ->
|
||||
items(uiState.multiCommunities) { community ->
|
||||
val endColor = MaterialTheme.colorScheme.secondary
|
||||
val startColor = MaterialTheme.colorScheme.tertiary
|
||||
SwipeableCard(
|
||||
@ -203,13 +205,15 @@ class ManageSubscriptionsScreen : Screen {
|
||||
model.reduce(ManageSubscriptionsMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = rememberCallback {
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
MultiCommunityEditorScreen(community),
|
||||
)
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ManageSubscriptionsMviModel.Intent.DeleteMultiCommunity(idx),
|
||||
ManageSubscriptionsMviModel.Intent.DeleteMultiCommunity(
|
||||
(community.id ?: 0).toInt()
|
||||
),
|
||||
)
|
||||
},
|
||||
swipeContent = { direction ->
|
||||
@ -229,7 +233,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.background).onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
MultiCommunityScreen(community),
|
||||
)
|
||||
},
|
||||
@ -252,7 +256,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.communities) { idx, community ->
|
||||
items(uiState.communities) { community ->
|
||||
val endColor = MaterialTheme.colorScheme.secondary
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -268,7 +272,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ManageSubscriptionsMviModel.Intent.Unsubscribe(idx),
|
||||
ManageSubscriptionsMviModel.Intent.Unsubscribe(community.id),
|
||||
)
|
||||
},
|
||||
swipeContent = { _ ->
|
||||
@ -285,7 +289,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigator?.push(
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
|
@ -63,11 +63,13 @@ class ManageSubscriptionsViewModel(
|
||||
ManageSubscriptionsMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||
ManageSubscriptionsMviModel.Intent.Refresh -> refresh()
|
||||
is ManageSubscriptionsMviModel.Intent.Unsubscribe -> handleUnsubscription(
|
||||
community = uiState.value.communities[intent.index],
|
||||
community = uiState.value.communities.first { it.id == intent.id },
|
||||
)
|
||||
|
||||
is ManageSubscriptionsMviModel.Intent.DeleteMultiCommunity -> deleteMultiCommunity(
|
||||
community = uiState.value.multiCommunities[intent.index],
|
||||
community = uiState.value.multiCommunities.first {
|
||||
(it.id ?: 0).toInt() == intent.id
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ interface MultiCommunityMviModel :
|
||||
data object LoadNextPage : Intent
|
||||
data class ChangeSort(val value: SortType) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SharePost(val index: Int) : Intent
|
||||
data class MarkAsRead(val index: Int) : Intent
|
||||
data class Hide(val index: Int) : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SharePost(val id: Int) : Intent
|
||||
data class MarkAsRead(val id: Int) : Intent
|
||||
data class Hide(val id: Int) : Intent
|
||||
data object ClearRead : Intent
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
@ -39,6 +39,7 @@ import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
@ -53,7 +54,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
@ -76,6 +76,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.MultiCommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
@ -95,11 +96,9 @@ class MultiCommunityScreen(
|
||||
val model = rememberScreenModel { getMultiCommunityViewModel(community) }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val bottomNavCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { bottomNavCoordinator.getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
@ -111,6 +110,9 @@ class MultiCommunityScreen(
|
||||
val fabNestedScrollConnection = remember { getFabNestedScrollConnection() }
|
||||
val isFabVisible by fabNestedScrollConnection.isFabVisible.collectAsState()
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
|
||||
DisposableEffect(key) {
|
||||
drawerCoordinator.setGesturesEnabled(false)
|
||||
onDispose {
|
||||
@ -118,12 +120,28 @@ class MultiCommunityScreen(
|
||||
drawerCoordinator.setGesturesEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(MultiCommunityMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
.nestedScroll(fabNestedScrollConnection),
|
||||
topBar = {
|
||||
val sortType = uiState.sortType
|
||||
TopAppBar(
|
||||
@ -139,7 +157,7 @@ class MultiCommunityScreen(
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -176,16 +194,7 @@ class MultiCommunityScreen(
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.ChangeSort(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = sortType.toIcon(),
|
||||
@ -212,7 +221,7 @@ class MultiCommunityScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ExpandLess,
|
||||
text = stringResource(MR.strings.action_back_to_top),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
@ -223,7 +232,7 @@ class MultiCommunityScreen(
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = {
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(MultiCommunityMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
@ -245,6 +254,14 @@ class MultiCommunityScreen(
|
||||
modifier = Modifier
|
||||
.padding(padding)
|
||||
.fillMaxWidth()
|
||||
.let {
|
||||
if (settings.hideNavigationBarWhileScrolling) {
|
||||
it.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.nestedScroll(fabNestedScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
@ -262,7 +279,7 @@ class MultiCommunityScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
itemsIndexed(uiState.posts) { idx, post ->
|
||||
items(uiState.posts) { post ->
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
@ -281,10 +298,10 @@ class MultiCommunityScreen(
|
||||
model.reduce(MultiCommunityMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = {
|
||||
model.reduce(MultiCommunityMviModel.Intent.UpVotePost(idx))
|
||||
model.reduce(MultiCommunityMviModel.Intent.UpVotePost(post.id))
|
||||
},
|
||||
onDismissToEnd = {
|
||||
model.reduce(MultiCommunityMviModel.Intent.DownVotePost(idx))
|
||||
model.reduce(MultiCommunityMviModel.Intent.DownVotePost(post.id))
|
||||
},
|
||||
swipeContent = { direction ->
|
||||
val icon = when (direction) {
|
||||
@ -306,25 +323,25 @@ class MultiCommunityScreen(
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = {
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(idx))
|
||||
navigator?.push(
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = { community ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = { user ->
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = {
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.UpVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -332,7 +349,7 @@ class MultiCommunityScreen(
|
||||
onDownVote = {
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.DownVotePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -340,7 +357,7 @@ class MultiCommunityScreen(
|
||||
onSave = {
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.SavePost(
|
||||
index = idx,
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
@ -349,18 +366,11 @@ class MultiCommunityScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
model.reduce(MultiCommunityMviModel.Intent.Refresh)
|
||||
},
|
||||
key,
|
||||
NotificationCenterContractKeys.CommentCreated
|
||||
)
|
||||
bottomSheetNavigator.show(screen)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onImageClick = { url ->
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(idx))
|
||||
navigator?.push(
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -372,16 +382,21 @@ class MultiCommunityScreen(
|
||||
onOptionSelected = { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
bottomSheetNavigator.show(
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> model.reduce(MultiCommunityMviModel.Intent.Hide(idx))
|
||||
1 -> model.reduce(
|
||||
MultiCommunityMviModel.Intent.Hide(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
|
||||
else -> model.reduce(
|
||||
MultiCommunityMviModel.Intent.SharePost(idx)
|
||||
MultiCommunityMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class MultiCommunityViewModel(
|
||||
when (intent) {
|
||||
is MultiCommunityMviModel.Intent.ChangeSort -> applySortType(intent.value)
|
||||
is MultiCommunityMviModel.Intent.DownVotePost -> toggleDownVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
@ -97,19 +97,25 @@ class MultiCommunityViewModel(
|
||||
MultiCommunityMviModel.Intent.LoadNextPage -> loadNextPage()
|
||||
MultiCommunityMviModel.Intent.Refresh -> refresh()
|
||||
is MultiCommunityMviModel.Intent.SavePost -> toggleSave(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
is MultiCommunityMviModel.Intent.SharePost -> share(post = uiState.value.posts[intent.index])
|
||||
is MultiCommunityMviModel.Intent.SharePost -> share(
|
||||
post = uiState.value.posts.first { it.id == intent.id }
|
||||
)
|
||||
|
||||
is MultiCommunityMviModel.Intent.UpVotePost -> toggleUpVote(
|
||||
post = uiState.value.posts[intent.index],
|
||||
post = uiState.value.posts.first { it.id == intent.id },
|
||||
feedback = intent.feedback,
|
||||
)
|
||||
|
||||
MultiCommunityMviModel.Intent.ClearRead -> clearRead()
|
||||
is MultiCommunityMviModel.Intent.MarkAsRead -> markAsRead(post = uiState.value.posts[intent.index])
|
||||
is MultiCommunityMviModel.Intent.Hide -> hide(post = uiState.value.posts[intent.index])
|
||||
is MultiCommunityMviModel.Intent.MarkAsRead -> markAsRead(
|
||||
post = uiState.value.posts.first { it.id == intent.id })
|
||||
|
||||
is MultiCommunityMviModel.Intent.Hide -> hide(
|
||||
post = uiState.value.posts.first { it.id == intent.id })
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +146,7 @@ class MultiCommunityViewModel(
|
||||
currentIds = if (refreshing) emptyList() else currentState.posts.map { it.id }
|
||||
)
|
||||
val canFetchMore = paginator.canFetchMore
|
||||
val itemsToAdd = itemList.orEmpty().filter { post ->
|
||||
val itemsToAdd = itemList.filter { post ->
|
||||
if (includeNsfw) {
|
||||
true
|
||||
} else {
|
||||
|
@ -12,7 +12,7 @@ interface MultiCommunityEditorMviModel :
|
||||
data class SetName(val value: String) : Intent
|
||||
data class SetSearch(val value: String) : Intent
|
||||
data class SelectImage(val index: Int?) : Intent
|
||||
data class ToggleCommunity(val index: Int) : Intent
|
||||
data class ToggleCommunity(val id: Int) : Intent
|
||||
data object Submit : Intent
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@ -81,13 +82,13 @@ class MultiCommunityEditorScreen(
|
||||
val model = rememberScreenModel { getMultiCommunityEditorViewModel(editedCommunity) }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
MultiCommunityEditorMviModel.Effect.Close -> {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -114,7 +115,7 @@ class MultiCommunityEditorScreen(
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator?.pop()
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -326,7 +327,7 @@ class MultiCommunityEditorScreen(
|
||||
.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
) {
|
||||
itemsIndexed(uiState.communities) { idx, communityItem ->
|
||||
items(uiState.communities) { communityItem ->
|
||||
val community = communityItem.first
|
||||
val selected = communityItem.second
|
||||
Row(
|
||||
@ -342,7 +343,7 @@ class MultiCommunityEditorScreen(
|
||||
onCheckedChange = {
|
||||
model.reduce(
|
||||
MultiCommunityEditorMviModel.Intent.ToggleCommunity(
|
||||
idx
|
||||
community.id
|
||||
)
|
||||
)
|
||||
},
|
||||
|
@ -52,7 +52,7 @@ class MultiCommunityEditorViewModel(
|
||||
when (intent) {
|
||||
is MultiCommunityEditorMviModel.Intent.SelectImage -> selectImage(intent.index)
|
||||
is MultiCommunityEditorMviModel.Intent.SetName -> mvi.updateState { it.copy(name = intent.value) }
|
||||
is MultiCommunityEditorMviModel.Intent.ToggleCommunity -> toggleCommunity(intent.index)
|
||||
is MultiCommunityEditorMviModel.Intent.ToggleCommunity -> toggleCommunity(intent.id)
|
||||
is MultiCommunityEditorMviModel.Intent.SetSearch -> setSearch(intent.value)
|
||||
MultiCommunityEditorMviModel.Intent.Submit -> submit()
|
||||
}
|
||||
@ -109,10 +109,9 @@ class MultiCommunityEditorViewModel(
|
||||
mvi.updateState { it.copy(icon = image) }
|
||||
}
|
||||
|
||||
private fun toggleCommunity(index: Int) {
|
||||
val toggledCommunity = uiState.value.communities[index]
|
||||
private fun toggleCommunity(communityId: Int) {
|
||||
val newCommunities = communities.map { item ->
|
||||
if (item.first.id == toggledCommunity.first.id) {
|
||||
if (item.first.id == communityId) {
|
||||
item.first to !item.second
|
||||
} else {
|
||||
item
|
||||
|
@ -65,7 +65,7 @@ class AboutDialog : Screen {
|
||||
viewModel.bindToLifecycle(key)
|
||||
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigator = remember { getNavigationCoordinator().getRootNavigator() }
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
@ -75,7 +75,7 @@ class AboutDialog : Screen {
|
||||
viewModel.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
is AboutDialogMviModel.Effect.OpenCommunity -> {
|
||||
navigator?.push(
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(
|
||||
community = effect.community,
|
||||
otherInstance = effect.instance,
|
||||
@ -126,7 +126,7 @@ class AboutDialog : Screen {
|
||||
url = CHANGELOG_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -138,7 +138,7 @@ class AboutDialog : Screen {
|
||||
url = REPORT_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
) {
|
||||
@ -170,7 +170,7 @@ class AboutDialog : Screen {
|
||||
url = WEBSITE_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigator,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -39,7 +39,6 @@ import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
|
||||
@ -95,36 +94,20 @@ class SettingsScreen : Screen {
|
||||
val model = rememberScreenModel { getSettingsViewModel() }
|
||||
model.bindToLifecycle(SettingsTab.key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
val topAppBarState = rememberTopAppBarState()
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val navigator = remember { navigationCoordinator.getRootNavigator() }
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
LaunchedEffect(navigator) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach { tab ->
|
||||
if (tab == SettingsTab) {
|
||||
scrollState.scrollTo(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
topAppBarState.contentOffset = 0f
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
val languageRepository = remember { getLanguageRepository() }
|
||||
val lang by languageRepository.currentLanguage.collectAsState()
|
||||
|
||||
var uiFontSizeWorkaround by remember { mutableStateOf(true) }
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
var upvoteColorDialogOpened by remember { mutableStateOf(false) }
|
||||
var downvoteColorDialogOpened by remember { mutableStateOf(false) }
|
||||
var infoDialogOpened by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(themeRepository) {
|
||||
themeRepository.uiFontScale.drop(1).onEach {
|
||||
@ -133,12 +116,131 @@ class SettingsScreen : Screen {
|
||||
uiFontSizeWorkaround = true
|
||||
}.launchIn(this)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
navigationCoordinator.onDoubleTabSelection.onEach { tab ->
|
||||
if (tab == SettingsTab) {
|
||||
scrollState.scrollTo(0)
|
||||
topAppBarState.heightOffset = 0f
|
||||
topAppBarState.contentOffset = 0f
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? String)?.also { lang ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeLanguage(lang))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeLanguage
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? UiTheme)?.also { value ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeUiTheme(value))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeTheme
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeCustomSeedColor(
|
||||
result as? Color?
|
||||
)
|
||||
)
|
||||
}, key, NotificationCenterContractKeys.ChangeColor
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? UiFontFamily)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeUiFontFamily(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontFamily
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? Float)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeUiFontSize(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontSize
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? Float)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeContentFontSize(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontSize
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? PostLayout)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangePostLayout(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangePostLayout
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultListingType(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultPostSortType(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultCommentSortType(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType
|
||||
)
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
infoDialogOpened = false
|
||||
}, key, NotificationCenterContractKeys.CloseDialog
|
||||
)
|
||||
}
|
||||
|
||||
if (!uiFontSizeWorkaround) {
|
||||
return
|
||||
}
|
||||
var upvoteColorDialogOpened by remember { mutableStateOf(false) }
|
||||
var downvoteColorDialogOpened by remember { mutableStateOf(false) }
|
||||
var infoDialogOpened by remember { mutableStateOf(false) }
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.padding(Spacing.xxs),
|
||||
@ -194,12 +296,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.lang.toLanguageName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = LanguageBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? String)?.also { lang ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeLanguage(lang))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeLanguage)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -209,12 +306,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.uiTheme.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = ThemeBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? UiTheme)?.also { value ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeUiTheme(value))
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeTheme)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -243,14 +335,7 @@ class SettingsScreen : Screen {
|
||||
).primary,
|
||||
onTap = rememberCallback {
|
||||
val sheet = ColorBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeCustomSeedColor(
|
||||
result as? Color?
|
||||
)
|
||||
)
|
||||
}, key, NotificationCenterContractKeys.ChangeColor)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
// upvote and downvote colors
|
||||
@ -275,16 +360,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.uiFontFamily.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = FontFamilyBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? UiFontFamily)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeUiFontFamily(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontFamily)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
// font scale
|
||||
@ -299,16 +375,7 @@ class SettingsScreen : Screen {
|
||||
FontScale.Small,
|
||||
),
|
||||
)
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? Float)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeUiFontSize(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontSize)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
SettingsRow(
|
||||
@ -316,16 +383,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.contentFontScale.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = FontScaleBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? Float)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeContentFontSize(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFontSize)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -335,16 +393,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.postLayout.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = PostLayoutBottomSheet()
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? PostLayout)?.also { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangePostLayout(
|
||||
value
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangePostLayout)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -400,16 +449,7 @@ class SettingsScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
notificationCenter.addObserver({ result ->
|
||||
(result as? ListingType)?.also {
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultListingType(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeFeedType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -421,16 +461,7 @@ class SettingsScreen : Screen {
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultPostSortType(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -448,16 +479,7 @@ class SettingsScreen : Screen {
|
||||
SortType.Controversial,
|
||||
),
|
||||
)
|
||||
notificationCenter.addObserver({
|
||||
(it as? SortType)?.also { sortType ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeDefaultCommentSortType(
|
||||
sortType
|
||||
)
|
||||
)
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.ChangeSortType)
|
||||
bottomSheetNavigator.show(sheet)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -623,9 +645,6 @@ class SettingsScreen : Screen {
|
||||
}
|
||||
|
||||
if (infoDialogOpened) {
|
||||
notificationCenter.addObserver({
|
||||
infoDialogOpened = false
|
||||
}, key, NotificationCenterContractKeys.CloseDialog)
|
||||
AboutDialog().Content()
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,6 @@
|
||||
<string name="settings_ui_font_scale">Dimensione testo UI</string>
|
||||
<string name="settings_ui_theme">Tema interfaccia</string>
|
||||
<string name="settings_upvote_color">Colore voti positivi</string>
|
||||
<string name="settings_hide_navigation_bar">Nascondi barra di navigation durante lo scroll
|
||||
<string name="settings_hide_navigation_bar">Nascondi barra di navigazione durante lo scroll
|
||||
</string>
|
||||
</resources>
|
@ -227,7 +227,9 @@ fun App() {
|
||||
topEnd = CornerSize.xl
|
||||
),
|
||||
sheetBackgroundColor = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
) { bottomNavigator ->
|
||||
navigationCoordinator.setBottomNavigator(bottomNavigator)
|
||||
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
gesturesEnabled = drawerGestureEnabled,
|
||||
|
@ -84,8 +84,8 @@ internal object MainScreen : Screen {
|
||||
}
|
||||
}
|
||||
|
||||
TabNavigator(HomeTab) {
|
||||
LaunchedEffect(it.current) {
|
||||
TabNavigator(HomeTab) { tabNavigator ->
|
||||
LaunchedEffect(tabNavigator.current) {
|
||||
// when the current tab chanes, reset the bottom bar offset to the default value
|
||||
model.reduce(MainScreenMviModel.Intent.SetBottomBarOffsetHeightPx(0f))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user