diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 0b449a955..132d92303 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -490,6 +490,7 @@ "noMessagesInNoteToSelf": "You have no messages in $name$.", "noMessagesInEverythingElse": "You have no messages from $name$. Send a message to start the conversation!", "hideBanner": "Hide", + "someOfYourDeviceUseOutdatedVersion": "Some of your devices are using outdated versions. Syncing may be unreliable until they are updated.", "openMessageRequestInboxDescription": "View your Message Request inbox", "clearAllReactions": "Are you sure you want to clear all $emoji$ ?", "expandedReactionsText": "Show Less", diff --git a/stylesheets/_index.scss b/stylesheets/_index.scss index 377b3f550..44ca0de80 100644 --- a/stylesheets/_index.scss +++ b/stylesheets/_index.scss @@ -6,6 +6,7 @@ .inbox.index { display: flex; + flex-direction: column; background-color: var(--background-primary-color); } @@ -64,9 +65,6 @@ flex-grow: 1; display: flex; } -.conversation.placeholder { - height: 100vh; -} .left-pane-wrapper { flex: 1; } diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index ec5a9788c..fc4bd757e 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -525,7 +525,7 @@ label { .session-settings { width: 100%; - height: 100vh; + height: 100%; display: flex; flex-direction: column; background-color: var(--background-secondary-color); diff --git a/stylesheets/_session_conversation.scss b/stylesheets/_session_conversation.scss index d31334601..867ac787b 100644 --- a/stylesheets/_session_conversation.scss +++ b/stylesheets/_session_conversation.scss @@ -82,6 +82,7 @@ display: flex; flex-direction: column; max-width: calc(100vw - 380px); + height: 100%; .selection-mode { .messages-container > *:not(.message-selected) { diff --git a/stylesheets/_session_left_pane.scss b/stylesheets/_session_left_pane.scss index 2e8cd3b07..8ca3e21b2 100644 --- a/stylesheets/_session_left_pane.scss +++ b/stylesheets/_session_left_pane.scss @@ -70,14 +70,14 @@ $session-compose-margin: 20px; .module-left-pane { position: relative; - height: 100vh; + height: 100%; flex-shrink: 0; border-left: 1px solid var(--border-color); border-right: 1px solid var(--border-color); &-session { display: flex; - height: 100vh; + height: 100%; } &__header { @@ -143,6 +143,8 @@ $session-compose-margin: 20px; .conversation.placeholder { margin: auto; + height: 100%; + .container { display: flex; height: 100%; diff --git a/ts/components/NoticeBanner.tsx b/ts/components/NoticeBanner.tsx new file mode 100644 index 000000000..6c9aeb184 --- /dev/null +++ b/ts/components/NoticeBanner.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import styled from 'styled-components'; +import { Flex } from './basic/Flex'; +import { SessionIconButton } from './icon'; + +const StyledNoticeBanner = styled(Flex)` + position: relative; + background-color: var(--primary-color); + color: var(--background-primary-color); + font-size: var(--font-size-lg); + padding: var(--margins-xs) var(--margins-sm); + text-align: center; + flex-shrink: 0; + .session-icon-button { + position: absolute; + right: var(--margins-sm); + } +`; + +const StyledText = styled.span` + margin-right: var(--margins-lg); +`; + +type NoticeBannerProps = { + text: string; + dismissCallback: () => void; +}; + +export const NoticeBanner = (props: NoticeBannerProps) => { + const { text, dismissCallback } = props; + + return ( + + {text} + { + event?.preventDefault(); + dismissCallback(); + }} + /> + + ); +}; diff --git a/ts/components/SessionInboxView.tsx b/ts/components/SessionInboxView.tsx index 45d70579b..df5126228 100644 --- a/ts/components/SessionInboxView.tsx +++ b/ts/components/SessionInboxView.tsx @@ -32,6 +32,7 @@ import { SessionMainPanel } from './SessionMainPanel'; import moment from 'moment'; import styled from 'styled-components'; import { initialSogsRoomInfoState } from '../state/ducks/sogsRoomInfo'; +import { Storage } from '../util/storage'; // Default to the locale from env. It will be overridden if moment // does not recognize it with what moment knows which is the closest. @@ -42,6 +43,10 @@ moment.locale((window.i18n as any).getLocale()); // Workaround: A react component's required properties are filtering up through connect() // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31363 import useUpdate from 'react-use/lib/useUpdate'; +import useInterval from 'react-use/lib/useInterval'; +import { SettingsKey } from '../data/settings-key'; +import { NoticeBanner } from './NoticeBanner'; +import { Flex } from './basic/Flex'; const StyledGutter = styled.div` width: 380px !important; @@ -89,6 +94,36 @@ function setupLeftPane(forceUpdateInboxComponent: () => void) { forceUpdateInboxComponent(); } +const SomeDeviceOutdatedSyncingNotice = () => { + const forceUpdate = useUpdate(); + const isShown = Boolean(window.getSettingValue(SettingsKey.someDeviceOutdatedSyncing)); + + // it would be nice to get the settings into a redux slice in addition to their Storage location and keep them in sync. + // So we could just use a selector here. + useInterval(() => { + const shouldBeShown = Storage.get(SettingsKey.someDeviceOutdatedSyncing); + + if (!isShown && shouldBeShown) { + forceUpdate(); + } + }, 1000); + + const dismiss = async () => { + await window.setSettingValue(SettingsKey.someDeviceOutdatedSyncing, false); + forceUpdate(); + }; + + if (!isShown) { + return null; + } + return ( + + ); +}; + export const SessionInboxView = () => { const update = useUpdate(); // run only on mount @@ -105,10 +140,13 @@ export const SessionInboxView = () => {
- - - - + + + + + + +
diff --git a/ts/components/leftpane/ActionsPanel.tsx b/ts/components/leftpane/ActionsPanel.tsx index fee386e3d..1a5cebc09 100644 --- a/ts/components/leftpane/ActionsPanel.tsx +++ b/ts/components/leftpane/ActionsPanel.tsx @@ -16,8 +16,8 @@ import useTimeoutFn from 'react-use/lib/useTimeoutFn'; import { clearSearch } from '../../state/ducks/search'; import { resetOverlayMode, SectionType, showLeftPaneSection } from '../../state/ducks/section'; import { - getOurPrimaryConversation, getGlobalUnreadMessageCount, + getOurPrimaryConversation, } from '../../state/selectors/conversations'; import { getFocusedSection } from '../../state/selectors/section'; import { getOurNumber } from '../../state/selectors/user'; diff --git a/ts/data/settings-key.ts b/ts/data/settings-key.ts index de2d43fb7..794cdc65c 100644 --- a/ts/data/settings-key.ts +++ b/ts/data/settings-key.ts @@ -9,6 +9,7 @@ const settingsStartInTray = 'start-in-tray-setting'; const settingsOpengroupPruning = 'prune-setting'; const settingsNotification = 'notification-setting'; const settingsAudioNotification = 'audio-notification-setting'; +const someDeviceOutdatedSyncing = 'some-device-outdated-syncing'; export const SettingsKey = { settingsReadReceipt, @@ -21,6 +22,7 @@ export const SettingsKey = { settingsOpengroupPruning, settingsNotification, settingsAudioNotification, + someDeviceOutdatedSyncing, }; export const KNOWN_BLINDED_KEYS_ITEM = 'KNOWN_BLINDED_KEYS_ITEM'; diff --git a/ts/receiver/configMessage.ts b/ts/receiver/configMessage.ts index ed2e49212..5b0e17ce3 100644 --- a/ts/receiver/configMessage.ts +++ b/ts/receiver/configMessage.ts @@ -41,6 +41,7 @@ import { addKeyPairToCacheAndDBIfNeeded, handleNewClosedGroup } from './closedGr import { HexKeyPair } from './keypairs'; import { queueAllCachedFromSource } from './receiver'; import { EnvelopePlus } from './types'; +import { SettingsKey } from '../data/settings-key'; function groupByVariant( incomingConfigs: Array> @@ -873,6 +874,7 @@ async function handleConfigurationMessageLegacy( window?.log?.info( 'useSharedUtilForUserConfig is set, not handling config messages with "handleConfigurationMessageLegacy()"' ); + window.setSettingValue(SettingsKey.someDeviceOutdatedSyncing, true); await removeFromCache(envelope); return; } diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts index d9f249462..a180e1659 100644 --- a/ts/types/LocalizerKeys.ts +++ b/ts/types/LocalizerKeys.ts @@ -489,6 +489,7 @@ export type LocalizerKeys = | 'noMessagesInNoteToSelf' | 'noMessagesInEverythingElse' | 'hideBanner' + | 'someOfYourDeviceUseOutdatedVersion' | 'openMessageRequestInboxDescription' | 'clearAllReactions' | 'expandedReactionsText'