From 59f9fbbeab24cd03407691d223a4516a7aa0b86e Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Tue, 12 Sep 2023 14:17:33 +0330 Subject: [PATCH 01/10] add video chat instance urls as subtitles --- scss/_global.scss | 38 +++++++ .../dialogs/Settings-ExperimentalFeatures.tsx | 107 ++++++++++++++++-- 2 files changed, 135 insertions(+), 10 deletions(-) diff --git a/scss/_global.scss b/scss/_global.scss index c5398067b5..10f6321dfe 100644 --- a/scss/_global.scss +++ b/scss/_global.scss @@ -219,3 +219,41 @@ kbd, samp { font-family: monospace, $emojifonts; } + +.radiogroup { + border: none; + display: flex; + justify-content: space-around; + flex-direction: column; + & > .radiobutton { + padding-bottom: 2px; + height: 42px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + & > img { + height: 36px; + width: 36px; + } + & > label { + padding-left: 4px; + padding-right: 4px; + height: 36px; + display: inline-flex; + justify-content: space-between; + flex-direction: column; + & > span:nth-child(1) { + // the label + color: var(--bp4InputText); + } + & > span:nth-child(2) { + // the subtitle + color: var(--bp4InputPlaceholder); + } + } + & > label.no-subtitle > span:nth-child(1) { + padding-top: 9px !important; + } + } +} diff --git a/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx b/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx index cc7b77d95a..a483f385ac 100644 --- a/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx +++ b/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx @@ -1,5 +1,6 @@ -import React, { useState, useContext, FormEvent } from 'react' -import { Card, Elevation, Radio, RadioGroup } from '@blueprintjs/core' +import React, { useState, useContext } from 'react' +import classNames from 'classnames' +import { Card, Elevation } from '@blueprintjs/core' import { RenderDTSettingSwitchType, SettingsSelector } from './Settings' import { ScreenContext, useTranslationFunction } from '../../contexts' import { DeltaInput } from '../Login-Styles' @@ -17,6 +18,75 @@ import SettingsStoreInstance, { const VIDEO_CHAT_INSTANCE_SYSTEMLI = 'https://meet.systemli.org/$ROOM' const VIDEO_CHAT_INSTANCE_AUTISTICI = 'https://vc.autistici.org/$ROOM' +type RadioProps = { + onSelect?: () => void + selected?: boolean + label: string + value: string + className?: string + name?: string + subtitle?: string +} + +type RadioGroupProps = { + onChange?: (value: string) => void + children: any + selectedValue: string + name: string +} + +function Radio({ + onSelect, + selected, + label, + value, + className, + name, + subtitle, +}: RadioProps) { + const id: string = Math.floor(Math.random() * 10000).toString() + return ( +
+ onSelect && onSelect()} + value={value} + defaultChecked={Boolean(selected)} + /> + +
+ ) +} + +function RadioGroup({ + onChange, + children, + selectedValue, + name, +}: RadioGroupProps) { + return ( +
+
+ {children.map((radio: any) => { + return ( + onChange && onChange(radio.props.value)} + name={name} + /> + ) + })} +
+
+ ) +} + export function SettingsExperimentalFeatures({ settingsStore, renderDTSettingSwitch, @@ -123,16 +193,15 @@ export function EditVideochatInstanceDialog({ onClose() onOk(configValue.trim()) // the trim is here to not save custom provider if it only contains whitespaces } - const onChangeRadio = (event: FormEvent) => { - const currentRadioValue = event.currentTarget.value as RadioButtonValue + const onChangeRadio = (value: string) => { let newConfigValue = '' - if (currentRadioValue === 'disabled') { + if (value === 'disabled') { newConfigValue = '' setRadioValue('disabled') - } else if (currentRadioValue === 'systemli') { + } else if (value === 'systemli') { newConfigValue = VIDEO_CHAT_INSTANCE_SYSTEMLI setRadioValue('systemli') - } else if (currentRadioValue === 'autistici') { + } else if (value === 'autistici') { newConfigValue = VIDEO_CHAT_INSTANCE_AUTISTICI setRadioValue('autistici') } else { @@ -142,6 +211,10 @@ export function EditVideochatInstanceDialog({ setConfigValue(newConfigValue) } + const subtitle = (value: string) => { + return value.replace('$ROOM', '') + } + return ( - + - - + + Date: Tue, 12 Sep 2023 14:20:23 +0330 Subject: [PATCH 02/10] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0148021b..7a48510b27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added + - Show video chat instance URLs as subtitles #3369 + ### Changed ### Fixed From c692913e70c10ff6b31cfde7a8c43c6774614793 Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Wed, 13 Sep 2023 08:11:06 +0330 Subject: [PATCH 03/10] show an unread badge when there are notifs from other account(s) --- CHANGELOG.md | 1 + scss/_sidebar.scss | 25 +++++++++++ src/renderer/components/Sidebar.tsx | 6 +++ src/renderer/components/UnreadBadge.tsx | 10 +++++ .../components/screens/MainScreen.tsx | 45 ++++++++++++++++++- 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/renderer/components/UnreadBadge.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a48510b27..e275ae1dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Show video chat instance URLs as subtitles #3369 + - Add an unread badge if there are unread notifs from other accounts ### Changed diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index 4b8d623ba1..4e1d1dfd3e 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -165,3 +165,28 @@ -webkit-transform: translateX(-100%); } } +/* + @keyframes unread-badge-bg-anim { + from { + background-color: color-mix(in srgb, var(--colorPrimary), transparent 100%); + } + to { + background-color: color-mix(in srgb, var(--colorPrimary), transparent 20%); + } + } + */ +// TODO: When Electron was upgraded, uncomment these to add animation. +// color-mix has been added in Chrome and other browsers in early 2023 +div.unread-badge { + width: 14px; + height: 14px; + border-radius: 50%; + position: relative; + background-color: var(--colorPrimary); + /* + animation-duration: 1.5s; + animation-name: unread-badge-bg-anim; + animation-iteration-count: infinite; + animation-direction: alternate; + */ +} diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index b50aef1513..c1e3268d22 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -13,6 +13,7 @@ import { VERSION } from '../../shared/build-info' import { ActionEmitter, KeybindAction } from '../keybindings' import SettingsConnectivityDialog from './dialogs/Settings-Connectivity' import { debounceWithInit } from './chat/ChatListHelpers' +import UnreadBadge from './UnreadBadge' import { BackendRemote, EffectfulBackendActions, @@ -25,9 +26,11 @@ const Sidebar = React.memo( ({ sidebarState, setSidebarState, + haveOtherAccountsUnread, }: { sidebarState: SidebarState setSidebarState: React.Dispatch> + haveOtherAccountsUnread: boolean }) => { const screenContext = useContext(ScreenContext) const settings = useSettingsStore()[0] @@ -180,6 +183,9 @@ const Sidebar = React.memo(
{tx('switch_account')} + {haveOtherAccountsUnread && ( + + )}
diff --git a/src/renderer/components/UnreadBadge.tsx b/src/renderer/components/UnreadBadge.tsx new file mode 100644 index 0000000000..6d86ea31b0 --- /dev/null +++ b/src/renderer/components/UnreadBadge.tsx @@ -0,0 +1,10 @@ +import React from 'react' + +type UnreadBadgeProps = { + top: string + left: string +} + +export default function UnreadBadge(props: UnreadBadgeProps) { + return
+} diff --git a/src/renderer/components/screens/MainScreen.tsx b/src/renderer/components/screens/MainScreen.tsx index c1f560ae08..71027a1543 100644 --- a/src/renderer/components/screens/MainScreen.tsx +++ b/src/renderer/components/screens/MainScreen.tsx @@ -19,6 +19,8 @@ import { selectChat, setChatView, } from '../helpers/ChatMethods' +import { BackendRemote, onDCEvent } from '../../backend-com' +import { selectedAccountId } from '../../ScreenController' import { Alignment, @@ -42,6 +44,7 @@ import SettingsStoreInstance, { useSettingsStore } from '../../stores/settings' import { Type } from '../../backend-com' import { InlineVerifiedIcon } from '../VerifiedIcon' import { SettingsProfileDialog } from '../dialogs/Settings-Profile' +import UnreadBadge from '../UnreadBadge' const log = getLogger('renderer/main-screen') @@ -49,7 +52,38 @@ export default function MainScreen() { const [queryStr, setQueryStr] = useState('') const [queryChatId, setQueryChatId] = useState(null) const [sidebarState, setSidebarState] = useState('init') - const [showArchivedChats, setShowArchivedChats] = useState(false) + const [showArchivedChats, setShowArchivedChats] = useState(false) + const [ + haveOtherAccountsUnread, + setHaveOtherAccountsUnread, + ] = useState(false) + + useEffect(() => { + let updating = false + const update = () => { + if (updating) return + updating = true + BackendRemote.rpc.getAllAccountIds().then(accountIds => { + accountIds = accountIds.filter(id => id !== selectedAccountId()) + for (const accountId of accountIds) { + BackendRemote.rpc.getFreshMsgs(accountId).then(ids => { + if (ids.length > 0) setHaveOtherAccountsUnread(true) + }) + } + }) + updating = false + } + update() + + BackendRemote.rpc + .getAllAccountIds() + .then(accountIds => + accountIds.map(id => onDCEvent(id, 'IncomingMsg', update)) + ) + + return update + }) + // Small hack/misuse of keyBindingAction to setShowArchivedChats from other components (especially // ViewProfile when selecting a shared chat/group) useKeyBindingAction(KeybindAction.ChatList_SwitchToArchiveView, () => @@ -202,6 +236,9 @@ export default function MainScreen() { id='hamburger-menu-button' > + {haveOtherAccountsUnread && ( + + )}
{queryStr.length === 0 && showArchivedChats && ( <> @@ -336,7 +373,11 @@ export default function MainScreen() { /> {MessageListView}
- + ) From f35b4a21524255377a36e12d77eb1b68c40c141e Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Wed, 13 Sep 2023 08:15:01 +0330 Subject: [PATCH 04/10] Revert "add video chat instance urls as subtitles" This reverts commit a16e1e87d8dae885e626bcf369c93d4cdeb00b5c. --- scss/_global.scss | 38 ------- .../dialogs/Settings-ExperimentalFeatures.tsx | 107 ++---------------- 2 files changed, 10 insertions(+), 135 deletions(-) diff --git a/scss/_global.scss b/scss/_global.scss index 10f6321dfe..c5398067b5 100644 --- a/scss/_global.scss +++ b/scss/_global.scss @@ -219,41 +219,3 @@ kbd, samp { font-family: monospace, $emojifonts; } - -.radiogroup { - border: none; - display: flex; - justify-content: space-around; - flex-direction: column; - & > .radiobutton { - padding-bottom: 2px; - height: 42px; - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - & > img { - height: 36px; - width: 36px; - } - & > label { - padding-left: 4px; - padding-right: 4px; - height: 36px; - display: inline-flex; - justify-content: space-between; - flex-direction: column; - & > span:nth-child(1) { - // the label - color: var(--bp4InputText); - } - & > span:nth-child(2) { - // the subtitle - color: var(--bp4InputPlaceholder); - } - } - & > label.no-subtitle > span:nth-child(1) { - padding-top: 9px !important; - } - } -} diff --git a/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx b/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx index a483f385ac..cc7b77d95a 100644 --- a/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx +++ b/src/renderer/components/dialogs/Settings-ExperimentalFeatures.tsx @@ -1,6 +1,5 @@ -import React, { useState, useContext } from 'react' -import classNames from 'classnames' -import { Card, Elevation } from '@blueprintjs/core' +import React, { useState, useContext, FormEvent } from 'react' +import { Card, Elevation, Radio, RadioGroup } from '@blueprintjs/core' import { RenderDTSettingSwitchType, SettingsSelector } from './Settings' import { ScreenContext, useTranslationFunction } from '../../contexts' import { DeltaInput } from '../Login-Styles' @@ -18,75 +17,6 @@ import SettingsStoreInstance, { const VIDEO_CHAT_INSTANCE_SYSTEMLI = 'https://meet.systemli.org/$ROOM' const VIDEO_CHAT_INSTANCE_AUTISTICI = 'https://vc.autistici.org/$ROOM' -type RadioProps = { - onSelect?: () => void - selected?: boolean - label: string - value: string - className?: string - name?: string - subtitle?: string -} - -type RadioGroupProps = { - onChange?: (value: string) => void - children: any - selectedValue: string - name: string -} - -function Radio({ - onSelect, - selected, - label, - value, - className, - name, - subtitle, -}: RadioProps) { - const id: string = Math.floor(Math.random() * 10000).toString() - return ( -
- onSelect && onSelect()} - value={value} - defaultChecked={Boolean(selected)} - /> - -
- ) -} - -function RadioGroup({ - onChange, - children, - selectedValue, - name, -}: RadioGroupProps) { - return ( -
-
- {children.map((radio: any) => { - return ( - onChange && onChange(radio.props.value)} - name={name} - /> - ) - })} -
-
- ) -} - export function SettingsExperimentalFeatures({ settingsStore, renderDTSettingSwitch, @@ -193,15 +123,16 @@ export function EditVideochatInstanceDialog({ onClose() onOk(configValue.trim()) // the trim is here to not save custom provider if it only contains whitespaces } - const onChangeRadio = (value: string) => { + const onChangeRadio = (event: FormEvent) => { + const currentRadioValue = event.currentTarget.value as RadioButtonValue let newConfigValue = '' - if (value === 'disabled') { + if (currentRadioValue === 'disabled') { newConfigValue = '' setRadioValue('disabled') - } else if (value === 'systemli') { + } else if (currentRadioValue === 'systemli') { newConfigValue = VIDEO_CHAT_INSTANCE_SYSTEMLI setRadioValue('systemli') - } else if (value === 'autistici') { + } else if (currentRadioValue === 'autistici') { newConfigValue = VIDEO_CHAT_INSTANCE_AUTISTICI setRadioValue('autistici') } else { @@ -211,10 +142,6 @@ export function EditVideochatInstanceDialog({ setConfigValue(newConfigValue) } - const subtitle = (value: string) => { - return value.replace('$ROOM', '') - } - return ( - + - - + + Date: Thu, 14 Sep 2023 12:59:12 +0330 Subject: [PATCH 05/10] clean changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e275ae1dd8..b5f4acf205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ ### Added - - Show video chat instance URLs as subtitles #3369 - Add an unread badge if there are unread notifs from other accounts ### Changed From d22933d884e92fb34ea76d8f95ed6a78fd47c0be Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Thu, 14 Sep 2023 16:22:01 +0330 Subject: [PATCH 06/10] dedicated unread badge component --- scss/_sidebar.scss | 33 +++++----- .../components/OtherAccountsUnreadBadge.tsx | 62 +++++++++++++++++++ src/renderer/components/Sidebar.tsx | 8 +-- src/renderer/components/UnreadBadge.tsx | 10 --- .../components/screens/MainScreen.tsx | 44 +------------ themes/_themebase.scss | 3 + 6 files changed, 84 insertions(+), 76 deletions(-) create mode 100644 src/renderer/components/OtherAccountsUnreadBadge.tsx delete mode 100644 src/renderer/components/UnreadBadge.tsx diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index 4e1d1dfd3e..353a597229 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -165,28 +165,23 @@ -webkit-transform: translateX(-100%); } } -/* - @keyframes unread-badge-bg-anim { - from { - background-color: color-mix(in srgb, var(--colorPrimary), transparent 100%); - } - to { - background-color: color-mix(in srgb, var(--colorPrimary), transparent 20%); - } - } - */ -// TODO: When Electron was upgraded, uncomment these to add animation. -// color-mix has been added in Chrome and other browsers in early 2023 + +@keyframes unread-badge-bg-anim { + from { + background-color: var(--unreadBadgeColor1); + } + to { + background-color: var(--unreadBadgeColor2); + } +} div.unread-badge { width: 14px; height: 14px; border-radius: 50%; position: relative; - background-color: var(--colorPrimary); - /* - animation-duration: 1.5s; - animation-name: unread-badge-bg-anim; - animation-iteration-count: infinite; - animation-direction: alternate; - */ + animation-duration: 1.5s; + animation-name: unread-badge-bg-anim; + animation-iteration-count: infinite; + animation-direction: alternate; + background-color: var(--unreadBadgeColor1); } diff --git a/src/renderer/components/OtherAccountsUnreadBadge.tsx b/src/renderer/components/OtherAccountsUnreadBadge.tsx new file mode 100644 index 0000000000..52f789d24e --- /dev/null +++ b/src/renderer/components/OtherAccountsUnreadBadge.tsx @@ -0,0 +1,62 @@ +import React, { useEffect, useState } from 'react' +import { BackendRemote, onDCEvent } from '../backend-com' +import { selectedAccountId } from '../ScreenController' +import { runtime } from '../runtime' +import { DesktopSettingsType } from '../../shared/shared-types' + +// Tip of the Day: Keep as many ice creams as you can in your fridge +// for the ice cream outage days. FREE ICE CREAM FOR EVERY1! --Farooq + +type ComponentProps = { + top: string + left: string +} + +export default function OtherAccountsUnreadBadge(props: ComponentProps) { + const [ + haveOtherAccountsUnread, + setHaveOtherAccountsUnread, + ] = useState(false) + const [isSyncAllEnabled, setIsSyncAllEnabled] = useState(false) + + useEffect(() => { + runtime + .getDesktopSettings() + .then((settings: DesktopSettingsType) => + setIsSyncAllEnabled(settings.syncAllAccounts) + ) + }) + + useEffect(() => { + if (!isSyncAllEnabled) return + let updating = false + const update = () => { + if (updating) return + updating = true + BackendRemote.rpc.getAllAccountIds().then(accountIds => { + accountIds = accountIds.filter(id => id !== selectedAccountId()) + for (const accountId of accountIds) { + BackendRemote.rpc.getFreshMsgs(accountId).then(ids => { + if (ids.length > 0) setHaveOtherAccountsUnread(true) + }) + } + }) + updating = false + } + update() + + BackendRemote.rpc + .getAllAccountIds() + .then(accountIds => + accountIds.map(id => onDCEvent(id, 'IncomingMsg', update)) + ) + + return update + }, [isSyncAllEnabled]) + + if (haveOtherAccountsUnread) { + return
+ } else { + return null + } +} diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index c1e3268d22..9b31ec84c3 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -13,12 +13,12 @@ import { VERSION } from '../../shared/build-info' import { ActionEmitter, KeybindAction } from '../keybindings' import SettingsConnectivityDialog from './dialogs/Settings-Connectivity' import { debounceWithInit } from './chat/ChatListHelpers' -import UnreadBadge from './UnreadBadge' import { BackendRemote, EffectfulBackendActions, onDCEvent, } from '../backend-com' +import OtherAccountsUnreadBadge from './OtherAccountsUnreadBadge' export type SidebarState = 'init' | 'visible' | 'invisible' @@ -26,11 +26,9 @@ const Sidebar = React.memo( ({ sidebarState, setSidebarState, - haveOtherAccountsUnread, }: { sidebarState: SidebarState setSidebarState: React.Dispatch> - haveOtherAccountsUnread: boolean }) => { const screenContext = useContext(ScreenContext) const settings = useSettingsStore()[0] @@ -183,9 +181,7 @@ const Sidebar = React.memo(
{tx('switch_account')} - {haveOtherAccountsUnread && ( - - )} +
diff --git a/src/renderer/components/UnreadBadge.tsx b/src/renderer/components/UnreadBadge.tsx deleted file mode 100644 index 6d86ea31b0..0000000000 --- a/src/renderer/components/UnreadBadge.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' - -type UnreadBadgeProps = { - top: string - left: string -} - -export default function UnreadBadge(props: UnreadBadgeProps) { - return
-} diff --git a/src/renderer/components/screens/MainScreen.tsx b/src/renderer/components/screens/MainScreen.tsx index 71027a1543..08cab29112 100644 --- a/src/renderer/components/screens/MainScreen.tsx +++ b/src/renderer/components/screens/MainScreen.tsx @@ -19,8 +19,6 @@ import { selectChat, setChatView, } from '../helpers/ChatMethods' -import { BackendRemote, onDCEvent } from '../../backend-com' -import { selectedAccountId } from '../../ScreenController' import { Alignment, @@ -44,7 +42,7 @@ import SettingsStoreInstance, { useSettingsStore } from '../../stores/settings' import { Type } from '../../backend-com' import { InlineVerifiedIcon } from '../VerifiedIcon' import { SettingsProfileDialog } from '../dialogs/Settings-Profile' -import UnreadBadge from '../UnreadBadge' +import OtherAccountsUnreadBadge from '../OtherAccountsUnreadBadge' const log = getLogger('renderer/main-screen') @@ -53,36 +51,6 @@ export default function MainScreen() { const [queryChatId, setQueryChatId] = useState(null) const [sidebarState, setSidebarState] = useState('init') const [showArchivedChats, setShowArchivedChats] = useState(false) - const [ - haveOtherAccountsUnread, - setHaveOtherAccountsUnread, - ] = useState(false) - - useEffect(() => { - let updating = false - const update = () => { - if (updating) return - updating = true - BackendRemote.rpc.getAllAccountIds().then(accountIds => { - accountIds = accountIds.filter(id => id !== selectedAccountId()) - for (const accountId of accountIds) { - BackendRemote.rpc.getFreshMsgs(accountId).then(ids => { - if (ids.length > 0) setHaveOtherAccountsUnread(true) - }) - } - }) - updating = false - } - update() - - BackendRemote.rpc - .getAllAccountIds() - .then(accountIds => - accountIds.map(id => onDCEvent(id, 'IncomingMsg', update)) - ) - - return update - }) // Small hack/misuse of keyBindingAction to setShowArchivedChats from other components (especially // ViewProfile when selecting a shared chat/group) @@ -236,9 +204,7 @@ export default function MainScreen() { id='hamburger-menu-button' > - {haveOtherAccountsUnread && ( - - )} +
{queryStr.length === 0 && showArchivedChats && ( <> @@ -373,11 +339,7 @@ export default function MainScreen() { /> {MessageListView}
- + ) diff --git a/themes/_themebase.scss b/themes/_themebase.scss index 4fb81f23b1..474c9694d0 100644 --- a/themes/_themebase.scss +++ b/themes/_themebase.scss @@ -21,6 +21,9 @@ $hover-contrast-change: 2%; --ovalButtonBgHover: #{changeContrast($ovalButtonBg, 70%)}; --ovalButtonText: #{$ovalButtonText}; --ovalButtonTextHover: #{desaturate(invert($ovalButtonText), 1)}; + /* UnreadBadge */ + --unreadBadgeColor1: #{$colorPrimary}; + --unreadBadgeColor2: mix(#{$colorPrimary}, transparent, 20%); /* NavBar */ --navBarBackground: #{$bgNavBar}; --navBarText: #{$textNavBar}; From be8a71d4fe315e441d864f3a7baf628dbcd3ed99 Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Thu, 14 Sep 2023 16:59:12 +0330 Subject: [PATCH 07/10] use useSettingsStore instead of useEffect + getDesktopSettings --- .../components/OtherAccountsUnreadBadge.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/renderer/components/OtherAccountsUnreadBadge.tsx b/src/renderer/components/OtherAccountsUnreadBadge.tsx index 52f789d24e..ff4f337bf9 100644 --- a/src/renderer/components/OtherAccountsUnreadBadge.tsx +++ b/src/renderer/components/OtherAccountsUnreadBadge.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react' import { BackendRemote, onDCEvent } from '../backend-com' import { selectedAccountId } from '../ScreenController' import { runtime } from '../runtime' +import { useSettingsStore } from '../stores/settings' import { DesktopSettingsType } from '../../shared/shared-types' // Tip of the Day: Keep as many ice creams as you can in your fridge @@ -17,18 +18,11 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { haveOtherAccountsUnread, setHaveOtherAccountsUnread, ] = useState(false) - const [isSyncAllEnabled, setIsSyncAllEnabled] = useState(false) - useEffect(() => { - runtime - .getDesktopSettings() - .then((settings: DesktopSettingsType) => - setIsSyncAllEnabled(settings.syncAllAccounts) - ) - }) + const settings = useSettingsStore()[0] + if (settings === null) return null useEffect(() => { - if (!isSyncAllEnabled) return let updating = false const update = () => { if (updating) return @@ -52,9 +46,9 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { ) return update - }, [isSyncAllEnabled]) + }, [settings.desktopSettings.syncAllAccounts]) - if (haveOtherAccountsUnread) { + if (settings.desktopSettings.syncAllAccounts && haveOtherAccountsUnread) { return
} else { return null From 2ebc6d6d6dd4e14f7bb6f91dd204c14b73ee6c8f Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Thu, 14 Sep 2023 17:53:15 +0330 Subject: [PATCH 08/10] complying to rule of hooks --- src/renderer/components/OtherAccountsUnreadBadge.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/OtherAccountsUnreadBadge.tsx b/src/renderer/components/OtherAccountsUnreadBadge.tsx index ff4f337bf9..d6a831e6cf 100644 --- a/src/renderer/components/OtherAccountsUnreadBadge.tsx +++ b/src/renderer/components/OtherAccountsUnreadBadge.tsx @@ -20,9 +20,10 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { ] = useState(false) const settings = useSettingsStore()[0] - if (settings === null) return null useEffect(() => { + if (settings === null) return + if (settings.desktopSettings.syncAllAccounts === false) return let updating = false const update = () => { if (updating) return @@ -46,9 +47,9 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { ) return update - }, [settings.desktopSettings.syncAllAccounts]) + }, [settings]) - if (settings.desktopSettings.syncAllAccounts && haveOtherAccountsUnread) { + if (settings && settings.desktopSettings.syncAllAccounts && haveOtherAccountsUnread) { return
} else { return null From cb52dae9aa88810873a26a733535e24a8c900200 Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Wed, 20 Sep 2023 18:45:06 +0330 Subject: [PATCH 09/10] move upate code into unread badge, two variants, on the right in sidebar --- scss/_sidebar.scss | 44 +++++++++++++++---- .../components/OtherAccountsUnreadBadge.tsx | 38 +++++++++++----- src/renderer/components/Sidebar.tsx | 5 ++- .../components/screens/MainScreen.tsx | 4 +- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index 353a597229..414a3f97fb 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -166,7 +166,38 @@ } } -@keyframes unread-badge-bg-anim { +.unread-badge { + border-radius: 50%; + position: relative; + background-color: var(--unreadBadgeColor1); + animation-duration: 1.5s; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +@keyframes unread-badge-big-anim { + from { + background-color: var(--unreadBadgeColor1); + color: white; + } + to { + background-color: white; + color: var(--unreadBadgeColor1); + } +} +div.unread-badge-big { + @extend .unread-badge; + width: 24px; + height: 24px; + color: white; + display: flex; + justify-content: center; + align-items: center; + animation-name: unread-badge-big-anim; + animation-timing-function: ease-in; +} + +@keyframes unread-badge-small-anim { from { background-color: var(--unreadBadgeColor1); } @@ -174,14 +205,9 @@ background-color: var(--unreadBadgeColor2); } } -div.unread-badge { +div.unread-badge-small { + @extend .unread-badge; width: 14px; height: 14px; - border-radius: 50%; - position: relative; - animation-duration: 1.5s; - animation-name: unread-badge-bg-anim; - animation-iteration-count: infinite; - animation-direction: alternate; - background-color: var(--unreadBadgeColor1); + animation-name: unread-badge-small-anim; } diff --git a/src/renderer/components/OtherAccountsUnreadBadge.tsx b/src/renderer/components/OtherAccountsUnreadBadge.tsx index d6a831e6cf..c65d71fa83 100644 --- a/src/renderer/components/OtherAccountsUnreadBadge.tsx +++ b/src/renderer/components/OtherAccountsUnreadBadge.tsx @@ -1,23 +1,24 @@ import React, { useEffect, useState } from 'react' import { BackendRemote, onDCEvent } from '../backend-com' import { selectedAccountId } from '../ScreenController' -import { runtime } from '../runtime' import { useSettingsStore } from '../stores/settings' -import { DesktopSettingsType } from '../../shared/shared-types' // Tip of the Day: Keep as many ice creams as you can in your fridge // for the ice cream outage days. FREE ICE CREAM FOR EVERY1! --Farooq type ComponentProps = { - top: string - left: string + style: any + big?: boolean } -export default function OtherAccountsUnreadBadge(props: ComponentProps) { +export default function OtherAccountsUnreadBadge({ + style, + big, +}: ComponentProps) { const [ - haveOtherAccountsUnread, - setHaveOtherAccountsUnread, - ] = useState(false) + otherAccountsUnreadCount, + setOtherAccountsUnreadCount, + ] = useState(0) const settings = useSettingsStore()[0] @@ -29,16 +30,20 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { if (updating) return updating = true BackendRemote.rpc.getAllAccountIds().then(accountIds => { + try { + selectedAccountId() + } catch { + return + } accountIds = accountIds.filter(id => id !== selectedAccountId()) for (const accountId of accountIds) { BackendRemote.rpc.getFreshMsgs(accountId).then(ids => { - if (ids.length > 0) setHaveOtherAccountsUnread(true) + setOtherAccountsUnreadCount(otherAccountsUnreadCount + ids.length) }) } }) updating = false } - update() BackendRemote.rpc .getAllAccountIds() @@ -46,11 +51,20 @@ export default function OtherAccountsUnreadBadge(props: ComponentProps) { accountIds.map(id => onDCEvent(id, 'IncomingMsg', update)) ) + update() return update }, [settings]) - if (settings && settings.desktopSettings.syncAllAccounts && haveOtherAccountsUnread) { - return
+ if (settings?.desktopSettings.syncAllAccounts && otherAccountsUnreadCount) { + if (big) { + return ( +
+ {otherAccountsUnreadCount} +
+ ) + } else { + return
+ } } else { return null } diff --git a/src/renderer/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx index 9b31ec84c3..a9d702be21 100644 --- a/src/renderer/components/Sidebar.tsx +++ b/src/renderer/components/Sidebar.tsx @@ -181,7 +181,10 @@ const Sidebar = React.memo(
{tx('switch_account')} - +
diff --git a/src/renderer/components/screens/MainScreen.tsx b/src/renderer/components/screens/MainScreen.tsx index 08cab29112..711debb6bc 100644 --- a/src/renderer/components/screens/MainScreen.tsx +++ b/src/renderer/components/screens/MainScreen.tsx @@ -204,7 +204,9 @@ export default function MainScreen() { id='hamburger-menu-button' > - +
{queryStr.length === 0 && showArchivedChats && ( <> From 9158bbec7eef0f716ded46d078c3d85725f3bb4b Mon Sep 17 00:00:00 2001 From: Farooq Karimi Zadeh Date: Wed, 20 Sep 2023 18:46:02 +0330 Subject: [PATCH 10/10] per Simon's suggestion --- src/renderer/components/OtherAccountsUnreadBadge.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/components/OtherAccountsUnreadBadge.tsx b/src/renderer/components/OtherAccountsUnreadBadge.tsx index c65d71fa83..2540ac462f 100644 --- a/src/renderer/components/OtherAccountsUnreadBadge.tsx +++ b/src/renderer/components/OtherAccountsUnreadBadge.tsx @@ -53,7 +53,7 @@ export default function OtherAccountsUnreadBadge({ update() return update - }, [settings]) + }, [settings?.desktopSettings.syncAllAccounts]) if (settings?.desktopSettings.syncAllAccounts && otherAccountsUnreadCount) { if (big) {