feat: account switch from bottom bar profile item (#1053)

This commit is contained in:
Diego Beraldin 2024-06-28 14:03:53 +02:00 committed by GitHub
parent 6906a3ccc5
commit 4139e2d397
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 82 additions and 30 deletions

View File

@ -82,6 +82,7 @@ kotlin {
implementation(projects.unit.drawer)
implementation(projects.unit.editcommunity)
implementation(projects.unit.instanceinfo)
implementation(projects.unit.manageaccounts)
implementation(projects.unit.manageban)
implementation(projects.unit.medialist)
implementation(projects.unit.managesubscriptions)
@ -124,9 +125,15 @@ kotlin {
android {
namespace = "com.github.diegoberaldin.raccoonforlemmy"
compileSdk = libs.versions.android.targetSdk.get().toInt()
compileSdk =
libs.versions.android.targetSdk
.get()
.toInt()
defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
minSdk =
libs.versions.android.minSdk
.get()
.toInt()
}
}
dependencies {

View File

@ -41,12 +41,14 @@ import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getDrawerCoor
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
import com.github.diegoberaldin.raccoonforlemmy.feature.home.ui.HomeTab
import com.github.diegoberaldin.raccoonforlemmy.feature.inbox.ui.InboxTab
import com.github.diegoberaldin.raccoonforlemmy.feature.profile.ui.ProfileTab
import com.github.diegoberaldin.raccoonforlemmy.feature.search.ui.ExploreTab
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.SettingsTab
import com.github.diegoberaldin.raccoonforlemmy.ui.navigation.TabNavigationItem
import com.github.diegoberaldin.raccoonforlemmy.unit.manageaccounts.ManageAccountsScreen
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
@ -246,6 +248,15 @@ internal object MainScreen : Screen {
tab = ProfileTab,
withText = titleVisible,
customIconUrl = uiState.customProfileUrl,
onLongPress =
if (uiState.isLogged) {
rememberCallback {
val screen = ManageAccountsScreen()
navigationCoordinator.showBottomSheet(screen)
}
} else {
null
},
)
TabNavigationItem(
tab = InboxTab,

View File

@ -15,6 +15,7 @@ interface MainScreenMviModel :
data class UiState(
val bottomBarOffsetHeightPx: Float = 0f,
val customProfileUrl: String? = null,
val isLogged: Boolean = false,
)
sealed interface Effect {

View File

@ -50,7 +50,8 @@ class MainViewModel(
}.launchIn(this)
identityRepository.isLogged
.onEach {
.onEach { isLogged ->
updateState { it.copy(isLogged = isLogged ?: false) }
updateCustomProfileIcon()
}.launchIn(this)
}

View File

@ -1,5 +1,8 @@
package com.github.diegoberaldin.raccoonforlemmy.ui.navigation
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@ -19,6 +22,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.style.TextOverflow
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
import cafe.adriel.voyager.navigator.tab.Tab
@ -38,6 +42,7 @@ internal fun RowScope.TabNavigationItem(
tab: Tab,
withText: Boolean = true,
customIconUrl: String? = null,
onLongPress: (() -> Unit)? = null,
) {
val tabNavigator = LocalTabNavigator.current
val navigationCoordinator = remember { getNavigationCoordinator() }
@ -49,30 +54,52 @@ internal fun RowScope.TabNavigationItem(
MaterialTheme.colorScheme.outline
}
val interactionSource = remember { MutableInteractionSource() }
fun handleClick() {
tabNavigator.current = tab
val section =
when (tab) {
ExploreTab -> TabNavigationSection.Explore
ProfileTab -> TabNavigationSection.Profile
InboxTab -> TabNavigationSection.Inbox
SettingsTab -> TabNavigationSection.Settings
else -> TabNavigationSection.Home
}
navigationCoordinator.setCurrentSection(section)
}
NavigationBarItem(
onClick = {
tabNavigator.current = tab
val section =
when (tab) {
ExploreTab -> TabNavigationSection.Explore
ProfileTab -> TabNavigationSection.Profile
InboxTab -> TabNavigationSection.Inbox
SettingsTab -> TabNavigationSection.Settings
else -> TabNavigationSection.Home
}
navigationCoordinator.setCurrentSection(section)
},
onClick = ::handleClick,
selected = tabNavigator.current == tab,
interactionSource = interactionSource,
icon = {
val content = @Composable {
if (customIconUrl != null) {
val iconSize = IconSize.m
CustomImage(
url = customIconUrl,
modifier =
Modifier
.size(iconSize)
.clip(RoundedCornerShape(iconSize / 2)),
.clip(RoundedCornerShape(iconSize / 2))
.pointerInput(Unit) {
detectTapGestures(
onPress = { offset ->
val press = PressInteraction.Press(offset)
interactionSource.emit(press)
tryAwaitRelease()
interactionSource.emit(PressInteraction.Release(press))
},
onTap = {
handleClick()
},
onLongPress = {
onLongPress?.invoke()
},
)
},
)
} else {
Icon(

View File

@ -28,6 +28,7 @@ import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpOffset
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
@ -57,13 +58,12 @@ internal fun AccountItem(
Row(
modifier =
modifier
.fillMaxWidth()
.onClick(
onClick = {
onClick?.invoke()
},
).padding(
horizontal = Spacing.m,
horizontal = Spacing.s,
vertical = Spacing.s,
),
horizontalArrangement = Arrangement.spacedBy(Spacing.s),
@ -74,7 +74,6 @@ internal fun AccountItem(
CustomImage(
modifier =
Modifier
.padding(Spacing.xxxs)
.size(IconSize.l)
.clip(RoundedCornerShape(IconSize.l / 2)),
url = avatar,
@ -85,7 +84,10 @@ internal fun AccountItem(
} else {
Box(modifier = Modifier.size(IconSize.l))
}
Text(
modifier = Modifier.fillMaxWidth(0.8f),
maxLines = 1,
text =
buildString {
append(account.username)
@ -93,6 +95,8 @@ internal fun AccountItem(
append(account.instance)
},
color = fullColor,
style = MaterialTheme.typography.bodyMedium,
overflow = TextOverflow.Ellipsis,
)
Spacer(modifier = Modifier.weight(1f))
@ -108,12 +112,12 @@ internal fun AccountItem(
Box {
Icon(
modifier =
Modifier.size(IconSize.m)
Modifier
.size(IconSize.m)
.padding(Spacing.xs)
.onGloballyPositioned {
optionsOffset = it.positionInParent()
}
.onClick(
}.onClick(
onClick = {
optionsMenuOpen = true
},

View File

@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
@ -48,13 +49,14 @@ class ManageAccountsScreen : Screen {
var indexToDelete by remember { mutableStateOf<Int?>(null) }
LaunchedEffect(model) {
model.effects.onEach { effect ->
when (effect) {
ManageAccountsMviModel.Effect.Close -> {
navigationCoordinator.hideBottomSheet()
model.effects
.onEach { effect ->
when (effect) {
ManageAccountsMviModel.Effect.Close -> {
navigationCoordinator.hideBottomSheet()
}
}
}
}.launchIn(this)
}.launchIn(this)
}
Column(
@ -63,8 +65,6 @@ class ManageAccountsScreen : Screen {
.windowInsetsPadding(WindowInsets.navigationBars)
.padding(
top = Spacing.s,
start = Spacing.s,
end = Spacing.s,
bottom = Spacing.m,
),
verticalArrangement = Arrangement.spacedBy(Spacing.s),
@ -78,6 +78,7 @@ class ManageAccountsScreen : Screen {
) {
itemsIndexed(uiState.accounts) { idx, account ->
AccountItem(
modifier = Modifier.fillMaxWidth(),
account = account,
autoLoadImages = uiState.autoLoadImages,
onClick = {