Skip to content
Snippets Groups Projects
Verified Commit 7ff0fc97 authored by Mikolai Gütschow's avatar Mikolai Gütschow
Browse files

add SidebarViewModel and thereby keep Briar API calls completely out of composables

parent 82390920
No related branches found
No related tags found
No related merge requests found
Pipeline #7962 passed
......@@ -19,86 +19,77 @@ import androidx.compose.material.icons.filled.Logout
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.WifiTethering
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import org.briarproject.briar.desktop.contact.ProfileCircle
import org.briarproject.briar.desktop.theme.sidebarSurface
import org.briarproject.briar.desktop.ui.IM
import org.briarproject.briar.desktop.ui.UiMode
val SIDEBAR_WIDTH = 56.dp
@Composable
fun BriarSidebar(uiMode: UiMode, setUiMode: (UiMode) -> Unit) {
fun BriarSidebar(
viewModel: SidebarViewModel,
) {
LaunchedEffect(true) {
viewModel.loadAccountInfo()
}
Surface(modifier = Modifier.width(SIDEBAR_WIDTH).fillMaxHeight(), color = MaterialTheme.colors.sidebarSurface) {
Column(verticalArrangement = Arrangement.Top) {
// profile button
IconButton(
modifier = Modifier.align(Alignment.CenterHorizontally).padding(top = 5.dp, bottom = 4.dp),
onClick = {}
) {
val identityManager = IM.current
ProfileCircle(size = 45.dp, identityManager.localAuthor.id.bytes)
viewModel.account.value?.let { ProfileCircle(size = 45.dp, it.id.bytes) }
}
for (
(uiMode, icon) in listOf(
Pair(UiMode.CONTACTS, Icons.Filled.Contacts),
Pair(UiMode.GROUPS, Icons.Filled.Group),
Pair(UiMode.FORUMS, Icons.Filled.Forum),
Pair(UiMode.BLOGS, Icons.Filled.ChromeReaderMode),
)
) {
BriarSidebarButton(
viewModel.uiMode.value == uiMode,
{ viewModel.setUiMode(uiMode) },
icon,
uiMode.toString()
)
}
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.CONTACTS,
Icons.Filled.Contacts
)
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.GROUPS,
Icons.Filled.Group
)
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.FORUMS,
Icons.Filled.Forum
)
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.BLOGS,
Icons.Filled.ChromeReaderMode
)
}
Column(verticalArrangement = Arrangement.Bottom) {
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.TRANSPORTS,
Icons.Filled.WifiTethering
)
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.SETTINGS,
Icons.Filled.Settings
)
BriarSidebarButton(
uiMode = uiMode,
setUiMode = setUiMode,
UiMode.SIGNOUT,
Icons.Filled.Logout
)
for (
(uiMode, icon) in listOf(
Pair(UiMode.TRANSPORTS, Icons.Filled.WifiTethering),
Pair(UiMode.SETTINGS, Icons.Filled.Settings),
Pair(UiMode.SIGNOUT, Icons.Filled.Logout),
)
) {
BriarSidebarButton(
viewModel.uiMode.value == uiMode,
{ viewModel.setUiMode(uiMode) },
icon,
uiMode.toString()
)
}
}
}
}
@Composable
fun BriarSidebarButton(uiMode: UiMode, setUiMode: (UiMode) -> Unit, thisMode: UiMode, icon: ImageVector) {
val tint = if (uiMode == thisMode) MaterialTheme.colors.primary else MaterialTheme.colors.onSurface
Column {
IconButton(
modifier = Modifier.align(Alignment.CenterHorizontally)
.padding(vertical = 4.dp, horizontal = 12.dp),
onClick = { setUiMode(thisMode) }
) {
Icon(icon, thisMode.toString(), tint = tint, modifier = Modifier.size(30.dp))
}
fun BriarSidebarButton(selected: Boolean, onClick: () -> Unit, icon: ImageVector, contentDescription: String?) {
val tint = if (selected) MaterialTheme.colors.primary else MaterialTheme.colors.onSurface
IconButton(
modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp),
onClick = onClick
) {
Icon(icon, contentDescription, tint = tint, modifier = Modifier.size(30.dp))
}
}
package org.briarproject.briar.desktop.navigation
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import org.briarproject.bramble.api.identity.IdentityManager
import org.briarproject.bramble.api.identity.LocalAuthor
import org.briarproject.briar.desktop.ui.UiMode
import javax.inject.Inject
class SidebarViewModel
@Inject
constructor(
private val identityManager: IdentityManager,
) {
private var _uiMode = mutableStateOf(UiMode.CONTACTS)
private var _account = mutableStateOf<LocalAuthor?>(null)
val uiMode: State<UiMode> = _uiMode
val account: State<LocalAuthor?> = _account
fun setUiMode(uiMode: UiMode) {
_uiMode.value = uiMode
}
fun loadAccountInfo() {
_account.value = identityManager.localAuthor
}
}
package org.briarproject.briar.desktop.ui
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
......@@ -9,12 +7,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import org.briarproject.bramble.api.account.AccountManager
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.identity.IdentityManager
import org.briarproject.bramble.api.lifecycle.LifecycleManager
import org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING
import org.briarproject.briar.api.conversation.ConversationManager
import org.briarproject.briar.api.messaging.MessagingManager
import org.briarproject.briar.desktop.contact.ContactListViewModel
import org.briarproject.briar.desktop.contact.add.remote.AddContactViewModel
import org.briarproject.briar.desktop.conversation.ConversationViewModel
......@@ -23,6 +17,7 @@ import org.briarproject.briar.desktop.login.Login
import org.briarproject.briar.desktop.login.LoginViewModel
import org.briarproject.briar.desktop.login.Registration
import org.briarproject.briar.desktop.login.RegistrationViewModel
import org.briarproject.briar.desktop.navigation.SidebarViewModel
import org.briarproject.briar.desktop.theme.BriarTheme
import java.awt.Dimension
import java.util.logging.Logger
......@@ -43,11 +38,6 @@ interface BriarUi {
fun stop()
}
val CVM = compositionLocalOf<ConversationManager> { error("Undefined ConversationManager") }
val CTM = compositionLocalOf<ContactManager> { error("Undefined ContactManager") }
val MM = compositionLocalOf<MessagingManager> { error("Undefined MessagingManager") }
val IM = compositionLocalOf<IdentityManager> { error("Undefined IdentityManager") }
@Immutable
@Singleton
internal class BriarUiImpl
......@@ -59,11 +49,8 @@ constructor(
private val conversationViewModel: ConversationViewModel,
private val addContactViewModel: AddContactViewModel,
private val introductionViewModel: IntroductionViewModel,
private val sidebarViewModel: SidebarViewModel,
private val accountManager: AccountManager,
private val contactManager: ContactManager,
private val conversationManager: ConversationManager,
private val identityManager: IdentityManager,
private val messagingManager: MessagingManager,
private val lifecycleManager: LifecycleManager,
) : BriarUi {
......@@ -114,21 +101,15 @@ constructor(
screenState = Screen.MAIN
}
else ->
CompositionLocalProvider(
CVM provides conversationManager,
CTM provides contactManager,
MM provides messagingManager,
IM provides identityManager,
) {
MainScreen(
contactListViewModel,
conversationViewModel,
addContactViewModel,
introductionViewModel,
isDark,
setDark
)
}
MainScreen(
contactListViewModel,
conversationViewModel,
addContactViewModel,
introductionViewModel,
sidebarViewModel,
isDark,
setDark
)
}
}
}
......
......@@ -2,14 +2,13 @@ package org.briarproject.briar.desktop.ui
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import org.briarproject.briar.desktop.contact.ContactListViewModel
import org.briarproject.briar.desktop.contact.add.remote.AddContactViewModel
import org.briarproject.briar.desktop.conversation.ConversationViewModel
import org.briarproject.briar.desktop.conversation.PrivateMessageView
import org.briarproject.briar.desktop.introduction.IntroductionViewModel
import org.briarproject.briar.desktop.navigation.BriarSidebar
import org.briarproject.briar.desktop.navigation.SidebarViewModel
import org.briarproject.briar.desktop.settings.PlaceHolderSettingsView
/*
......@@ -23,16 +22,14 @@ fun MainScreen(
conversationViewModel: ConversationViewModel,
addContactViewModel: AddContactViewModel,
introductionViewModel: IntroductionViewModel,
sidebarViewModel: SidebarViewModel,
isDark: Boolean,
setDark: (Boolean) -> Unit
) {
// current selected mode, changed using the sidebar buttons
val (uiMode, setUiMode) = remember { mutableStateOf(UiMode.CONTACTS) }
// Other global state that we need to track should go here also
Row {
BriarSidebar(uiMode, setUiMode)
BriarSidebar(sidebarViewModel)
VerticalDivider()
when (uiMode) {
when (sidebarViewModel.uiMode.value) {
UiMode.CONTACTS -> PrivateMessageView(
contactListViewModel,
conversationViewModel,
......
package org.briarproject.briar.desktop.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
fun UiPlaceholder() = Surface(Modifier.fillMaxSize().background(MaterialTheme.colors.background)) {
Text("TBD")
fun UiPlaceholder() = Surface(color = MaterialTheme.colors.background) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Text("TBD")
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment