diff --git a/images/session/brand/classic-dark.png b/images/session/brand/classic-dark.png
new file mode 100644
index 000000000..d056c2113
Binary files /dev/null and b/images/session/brand/classic-dark.png differ
diff --git a/images/session/brand/classic-light.png b/images/session/brand/classic-light.png
new file mode 100644
index 000000000..0ee64cbde
Binary files /dev/null and b/images/session/brand/classic-light.png differ
diff --git a/images/session/brand/ocean-dark.png b/images/session/brand/ocean-dark.png
new file mode 100644
index 000000000..193937145
Binary files /dev/null and b/images/session/brand/ocean-dark.png differ
diff --git a/images/session/brand/ocean-light.png b/images/session/brand/ocean-light.png
new file mode 100644
index 000000000..d962f47ef
Binary files /dev/null and b/images/session/brand/ocean-light.png differ
diff --git a/images/session/shield/classic-dark.png b/images/session/shield/classic-dark.png
new file mode 100644
index 000000000..9726ed823
Binary files /dev/null and b/images/session/shield/classic-dark.png differ
diff --git a/images/session/shield/classic-light.png b/images/session/shield/classic-light.png
new file mode 100644
index 000000000..9780c1243
Binary files /dev/null and b/images/session/shield/classic-light.png differ
diff --git a/images/session/shield/ocean-dark.png b/images/session/shield/ocean-dark.png
new file mode 100644
index 000000000..9a6cd6672
Binary files /dev/null and b/images/session/shield/ocean-dark.png differ
diff --git a/images/session/shield/ocean-light.png b/images/session/shield/ocean-light.png
new file mode 100644
index 000000000..5920d96f5
Binary files /dev/null and b/images/session/shield/ocean-light.png differ
diff --git a/ts/components/SessionInboxView.tsx b/ts/components/SessionInboxView.tsx
index 9ac1b9252..660261726 100644
--- a/ts/components/SessionInboxView.tsx
+++ b/ts/components/SessionInboxView.tsx
@@ -8,6 +8,7 @@ import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import styled from 'styled-components';
+import { AnimatePresence } from 'framer-motion';
import { LeftPane } from './leftpane/LeftPane';
// moment does not support es-419 correctly (and cause white screen on app start)
import { getConversationController } from '../session/conversations';
@@ -132,12 +133,14 @@ export const SessionInboxView = () => {
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/ts/components/SessionQRCode.tsx b/ts/components/SessionQRCode.tsx
new file mode 100644
index 000000000..ade25f033
--- /dev/null
+++ b/ts/components/SessionQRCode.tsx
@@ -0,0 +1,69 @@
+import { isEmpty } from 'lodash';
+import { MouseEvent } from 'react';
+import { QRCode } from 'react-qrcode-logo';
+import styled, { CSSProperties } from 'styled-components';
+import { THEME_GLOBALS } from '../themes/globals';
+import { saveQRCode } from '../util/saveQRCode';
+import { AnimatedFlex } from './basic/Flex';
+
+// We fade in the QR code to hide the logo flickering on first render
+const StyledQRView = styled(AnimatedFlex)`
+ cursor: pointer;
+ border-radius: var(--border-radius);
+ overflow: hidden;
+`;
+
+type Props = {
+ id: string;
+ value: string;
+ size: number;
+ backgroundColor?: string;
+ foregroundColor?: string;
+ logoImage?: string;
+ logoWidth?: number;
+ logoHeight?: number;
+ style?: CSSProperties;
+};
+
+export function SessionQRCode(props: Props) {
+ const {
+ id,
+ value,
+ size,
+ backgroundColor = '#FFF',
+ foregroundColor = '#000',
+ logoImage,
+ logoWidth,
+ logoHeight,
+ style,
+ } = props;
+ return (
+ {
+ event.preventDefault();
+ saveQRCode(id);
+ }}
+ initial={{ opacity: 0 }}
+ animate={{ opacity: 1 }}
+ transition={{ duration: THEME_GLOBALS['--default-duration-seconds'] }}
+ style={style}
+ >
+
+
+ );
+}
diff --git a/ts/components/basic/Flex.tsx b/ts/components/basic/Flex.tsx
index 650e66982..3912d82da 100644
--- a/ts/components/basic/Flex.tsx
+++ b/ts/components/basic/Flex.tsx
@@ -1,3 +1,4 @@
+import { motion } from 'framer-motion';
import styled from 'styled-components';
import { HTMLDirection } from '../../util/i18n';
@@ -58,3 +59,21 @@ export const Flex = styled.div`
min-width: ${props => props.minWidth || 'none'};
direction: ${props => props.dir || undefined};
`;
+
+export const AnimatedFlex = styled(motion.div)`
+ display: ${props => (props.container ? 'flex' : 'block')};
+ justify-content: ${props => props.justifyContent || 'flex-start'};
+ flex-direction: ${props => props.flexDirection || 'row'};
+ flex-grow: ${props => (props.flexGrow !== undefined ? props.flexGrow : '0')};
+ flex-basis: ${props => (props.flexBasis !== undefined ? props.flexBasis : 'auto')};
+ flex-shrink: ${props => (props.flexShrink !== undefined ? props.flexShrink : '1')};
+ flex-wrap: ${props => (props.flexWrap !== undefined ? props.flexWrap : 'nowrap')};
+ align-items: ${props => props.alignItems || 'stretch'};
+ margin: ${props => props.margin || '0'};
+ padding: ${props => props.padding || '0'};
+ width: ${props => props.width || 'auto'};
+ height: ${props => props.height || 'auto'};
+ max-width: ${props => props.maxWidth || 'none'};
+ min-width: ${props => props.minWidth || 'none'};
+ direction: ${props => props.dir || undefined};
+`;
diff --git a/ts/components/dialog/EditProfileDialog.tsx b/ts/components/dialog/EditProfileDialog.tsx
index 5e18e5bfb..b28a265a4 100644
--- a/ts/components/dialog/EditProfileDialog.tsx
+++ b/ts/components/dialog/EditProfileDialog.tsx
@@ -1,7 +1,5 @@
-import { ChangeEvent, MouseEvent, useState } from 'react';
-import { QRCode } from 'react-qrcode-logo';
-import { useDispatch } from 'react-redux';
-import styled from 'styled-components';
+import { ChangeEvent, useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
import { Avatar, AvatarSize } from '../avatar/Avatar';
import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils';
@@ -13,35 +11,33 @@ import { MAX_NAME_LENGTH_BYTES } from '../../session/constants';
import { getConversationController } from '../../session/conversations';
import { sanitizeSessionUsername } from '../../session/utils/String';
import { editProfileModal, updateEditProfilePictureModel } from '../../state/ducks/modalDialog';
-import { saveQRCode } from '../../util/saveQRCode';
+import { getTheme } from '../../state/selectors/theme';
+import { getThemeValue } from '../../themes/globals';
import { setLastProfileUpdateTimestamp } from '../../util/storage';
+import { SessionQRCode } from '../SessionQRCode';
import { SessionWrapperModal } from '../SessionWrapperModal';
-import { Flex } from '../basic/Flex';
import { SessionButton, SessionButtonType } from '../basic/SessionButton';
import { SessionIconButton } from '../icon';
import { SessionSpinner } from '../loading';
-const qrCodeId = 'session-account-id';
-const handleSaveQRCode = (event: MouseEvent) => {
- event.preventDefault();
- saveQRCode(qrCodeId);
-};
-
-const StyledQRView = styled(Flex)`
- cursor: pointer;
-`;
-
const QRView = ({ sessionID }: { sessionID: string }) => {
+ const theme = useSelector(getTheme);
+
return (
-
-
-
+
);
};
diff --git a/ts/components/dialog/SessionSeedModal.tsx b/ts/components/dialog/SessionSeedModal.tsx
index d0411ff98..59f25b304 100644
--- a/ts/components/dialog/SessionSeedModal.tsx
+++ b/ts/components/dialog/SessionSeedModal.tsx
@@ -1,9 +1,8 @@
-import { MouseEvent, useState } from 'react';
-import { useDispatch } from 'react-redux';
+import { useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
import useMount from 'react-use/lib/useMount';
import styled from 'styled-components';
-import { QRCode } from 'react-qrcode-logo';
import { Data } from '../../data/data';
import { ToastUtils } from '../../session/utils';
import { matchesHash } from '../../util/passwordUtils';
@@ -12,10 +11,11 @@ import { mnDecode } from '../../session/crypto/mnemonic';
import { recoveryPhraseModal } from '../../state/ducks/modalDialog';
import { SpacerSM } from '../basic/Text';
-import { saveQRCode } from '../../util/saveQRCode';
+import { getTheme } from '../../state/selectors/theme';
+import { getThemeValue } from '../../themes/globals';
import { getCurrentRecoveryPhrase } from '../../util/storage';
+import { SessionQRCode } from '../SessionQRCode';
import { SessionWrapperModal } from '../SessionWrapperModal';
-import { Flex } from '../basic/Flex';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
interface PasswordProps {
@@ -100,21 +100,11 @@ interface SeedProps {
const StyledRecoveryPhrase = styled.i``;
-const StyledQRImage = styled(Flex)`
- margin: 0 auto var(--margins-lg);
- cursor: pointer;
-`;
-
-const qrCodeId = 'session-recovery-password';
-const handleSaveQRCode = (event: MouseEvent) => {
- event.preventDefault();
- saveQRCode(qrCodeId);
-};
-
const Seed = (props: SeedProps) => {
const { recoveryPhrase, onClickCopy } = props;
const i18n = window.i18n;
const dispatch = useDispatch();
+ const theme = useSelector(getTheme);
const hexEncodedSeed = mnDecode(recoveryPhrase, 'english');
@@ -142,15 +132,21 @@ const Seed = (props: SeedProps) => {
{i18n('recoveryPhraseSavePromptMain')}
-
-
-
+
) {
return output;
}
+
+type ThemeKeys = ThemeGlobals & ThemeColorVariables;
+export function getThemeValue(key: keyof ThemeKeys) {
+ return getComputedStyle(document.documentElement).getPropertyValue(key);
+}