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'