diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt index ad5ce8bcc59788dcc32ac56cb4681caa2532789e..debaba99ef997ade1f47a3f989dc9a0e1c68f9ce 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt @@ -26,12 +26,16 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material.Badge import androidx.compose.material.BadgedBox +import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Error import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -39,6 +43,9 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import org.briarproject.bramble.api.identity.LocalAuthor import org.briarproject.briar.desktop.contact.ProfileCircle +import org.briarproject.briar.desktop.navigation.SidebarButtonState.None +import org.briarproject.briar.desktop.navigation.SidebarButtonState.UnreadMessages +import org.briarproject.briar.desktop.navigation.SidebarButtonState.Warning import org.briarproject.briar.desktop.theme.sidebarSurface import org.briarproject.briar.desktop.ui.UiMode import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n @@ -52,17 +59,18 @@ fun BriarSidebar( uiMode: UiMode, setUiMode: (UiMode) -> Unit, messageCount: SidebarViewModel.MessageCount, + hasMailboxProblem: Boolean, ) { @Composable fun BriarSidebarButton( mode: UiMode, messageCount: Int = 0, ) = BriarSidebarButton( - uiMode == mode, - { setUiMode(mode) }, - mode.icon, - i18n(mode.contentDescriptionKey), - messageCount + selected = uiMode == mode, + onClick = { setUiMode(mode) }, + icon = mode.icon, + contentDescription = i18n(mode.contentDescriptionKey), + sideBarButtonState = if (messageCount == 0) None else UnreadMessages(messageCount), ) val configuration = getConfiguration() @@ -87,26 +95,45 @@ fun BriarSidebar( Spacer(Modifier.weight(1f)) if (configuration.shouldEnableTransportSettings()) BriarSidebarButton(UiMode.TRANSPORTS) - if (configuration.shouldEnableMailbox()) BriarSidebarButton(UiMode.MAILBOX) + if (configuration.shouldEnableMailbox()) BriarSidebarButton( + selected = uiMode == UiMode.MAILBOX, + onClick = { setUiMode(UiMode.MAILBOX) }, + icon = UiMode.MAILBOX.icon, + contentDescription = i18n(UiMode.MAILBOX.contentDescriptionKey), + sideBarButtonState = if (hasMailboxProblem) Warning else None, + ) BriarSidebarButton(UiMode.SETTINGS) BriarSidebarButton(UiMode.ABOUT) } } +sealed class SidebarButtonState { + object None : SidebarButtonState() + class UnreadMessages(val messageCount: Int) : SidebarButtonState() + object Warning : SidebarButtonState() +} + @Composable fun BriarSidebarButton( selected: Boolean, onClick: () -> Unit, icon: ImageVector, contentDescription: String, - messageCount: Int, + sideBarButtonState: SidebarButtonState, ) = BadgedBox( badge = { - if (messageCount > 0) { + if (sideBarButtonState is UnreadMessages && sideBarButtonState.messageCount > 0) { Badge( modifier = Modifier.offset((-12).dp, 12.dp), backgroundColor = MaterialTheme.colors.secondary, ) + } else if (sideBarButtonState is Warning) { + Icon( + Icons.Default.Error, + i18n("mailbox.status.problem"), + modifier = Modifier.offset((-12).dp, 12.dp).size(16.dp), + tint = MaterialTheme.colors.error + ) } }, ) { diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt index 539da08caa51d7fa3b762d116a70713046a27f2a..b6b7591a663c2abee9a9872d56d39f89022c6649 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/SidebarViewModel.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -19,8 +19,13 @@ package org.briarproject.briar.desktop.navigation import androidx.compose.runtime.mutableStateOf +import org.briarproject.bramble.api.event.Event +import org.briarproject.bramble.api.event.EventBus +import org.briarproject.bramble.api.event.EventListener import org.briarproject.bramble.api.identity.IdentityManager import org.briarproject.bramble.api.identity.LocalAuthor +import org.briarproject.bramble.api.mailbox.event.MailboxProblemEvent +import org.briarproject.briar.desktop.threading.UiExecutor import org.briarproject.briar.desktop.ui.MessageCounter import org.briarproject.briar.desktop.ui.MessageCounterData import org.briarproject.briar.desktop.ui.MessageCounterDataType.Forum @@ -36,9 +41,16 @@ class SidebarViewModel constructor( private val identityManager: IdentityManager, private val messageCounter: MessageCounter, -) : ViewModel() { + private val eventBus: EventBus, +) : EventListener, ViewModel() { + private var listensToEventBus = false + override fun onInit() { super.onInit() + if (!listensToEventBus) { + eventBus.addListener(this) + listensToEventBus = true + } loadAccountInfo() messageCounter.addListener(this::onMessageCounterUpdated) } @@ -48,6 +60,10 @@ constructor( messageCounter.removeListener(this::onMessageCounterUpdated) } + override fun eventOccurred(e: Event) { + if (e is MailboxProblemEvent) _mailboxProblem.value = true + } + private fun onMessageCounterUpdated(data: MessageCounterData) { val (type, count) = data when (type) { @@ -56,21 +72,25 @@ constructor( } } - private var _uiMode = mutableStateOf(UiMode.CONTACTS) - private var _account = mutableStateOf<LocalAuthor?>(null) + private val _uiMode = mutableStateOf(UiMode.CONTACTS) + private val _account = mutableStateOf<LocalAuthor?>(null) + private val _mailboxProblem = mutableStateOf(false) - private var _messageCount = mutableStateOf(MessageCount()) + private val _messageCount = mutableStateOf(MessageCount()) val uiMode = _uiMode.asState() val account = _account.asState() + val mailboxProblem = _mailboxProblem.asState() val messageCount = _messageCount.asState() + @UiExecutor fun setUiMode(uiMode: UiMode) { _uiMode.value = uiMode + if (uiMode == UiMode.MAILBOX) _mailboxProblem.value = false } - fun loadAccountInfo() { + private fun loadAccountInfo() { _account.value = identityManager.localAuthor } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt index 9923b081a8fc4ec410ba5b8d8c4fcfee5dd9aaba..77a754c684209426c0b6af0863e3e8cc9d91f479 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/MainScreen.kt @@ -1,6 +1,6 @@ /* * Briar Desktop - * Copyright (C) 2021-2022 The Briar Project + * Copyright (C) 2021-2023 The Briar Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -57,6 +57,7 @@ fun MainScreen(viewModel: SidebarViewModel = viewModel()) { viewModel.uiMode.value, viewModel::setUiMode, viewModel.messageCount.value, + viewModel.mailboxProblem.value, ) VerticalDivider() when (viewModel.uiMode.value) {