diff --git a/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt index 60c1614b7b0c251f6f188414a64a0bf6cef005c4..023bb259c15940254515a723e39a59f4231f5958 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt @@ -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)) } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..e7b560ce95b67ad6b0cb615635e7ba0362de4a86 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt @@ -0,0 +1,29 @@ +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 + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt index d28cf156198dd2b55b346e8a91c35717a50d45dd..76c607b4402f510e41e39042c662147bc862f4f8 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt @@ -1,7 +1,5 @@ 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 + ) } } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt index 69a036fd273eeddaae837ee47bd443d2cfe75ee2..e6f11c87dc9ac664921810bb8c125d39f8ab4339 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt @@ -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, diff --git a/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt b/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt index 5b44eea15691334a7dc6b95ac749e889aaa0f730..d5845fbb80d0f54f2ca5bbdfbf954f6119019b7f 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/ui/UiPlaceholder.kt @@ -1,14 +1,20 @@ 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") + } }