From e5f1e6519466b15baf23c2a20ca5ab5603d465f9 Mon Sep 17 00:00:00 2001
From: William Grant
Date: Fri, 17 Feb 2023 10:47:55 +1100
Subject: [PATCH] feat: added ability to save qr codes on click
recovery phrase modal ui layout is now the same as edit profile modal, fixes for yarn ready
---
ts/components/dialog/EditProfileDialog.tsx | 38 +++++++++++++------
ts/components/dialog/SessionSeedModal.tsx | 33 ++++++++++++----
.../conversation-list-item/HeaderItem.tsx | 4 +-
ts/util/saveQRCode.ts | 29 ++++++++++++++
4 files changed, 84 insertions(+), 20 deletions(-)
create mode 100644 ts/util/saveQRCode.ts
diff --git a/ts/components/dialog/EditProfileDialog.tsx b/ts/components/dialog/EditProfileDialog.tsx
index 788eb2964..1521729da 100644
--- a/ts/components/dialog/EditProfileDialog.tsx
+++ b/ts/components/dialog/EditProfileDialog.tsx
@@ -1,4 +1,4 @@
-import React, { ChangeEvent } from 'react';
+import React, { ChangeEvent, MouseEvent } from 'react';
import { QRCode } from 'react-qr-svg';
import { Avatar, AvatarSize } from '../avatar/Avatar';
@@ -21,29 +21,45 @@ import { sanitizeSessionUsername } from '../../session/utils/String';
import { setLastProfileUpdateTimestamp } from '../../util/storage';
import { ConversationTypeEnum } from '../../models/conversationAttributes';
import { MAX_USERNAME_BYTES } from '../../session/constants';
+import styled from 'styled-components';
+import { saveQRCode } from '../../util/saveQRCode';
-interface State {
- profileName: string;
- updatedProfileName: string;
- oldAvatarPath: string;
- newAvatarObjectUrl: string | null;
- mode: 'default' | 'edit' | 'qr';
- loading: boolean;
-}
+const handleSaveQRCode = (event: MouseEvent) => {
+ event.preventDefault();
+ saveQRCode('session-id', '220px', '220px', 'var(--white-color)', 'var(--black-color)');
+};
+
+const StyledQRView = styled.div`
+ cursor: pointer;
+`;
const QRView = ({ sessionID }: { sessionID: string }) => {
return (
-
+
-
+
);
};
+interface State {
+ profileName: string;
+ updatedProfileName: string;
+ oldAvatarPath: string;
+ newAvatarObjectUrl: string | null;
+ mode: 'default' | 'edit' | 'qr';
+ loading: boolean;
+}
+
export class EditProfileDialog extends React.Component<{}, State> {
private readonly convo: ConversationModel;
diff --git a/ts/components/dialog/SessionSeedModal.tsx b/ts/components/dialog/SessionSeedModal.tsx
index 8487bda6c..1b78900db 100644
--- a/ts/components/dialog/SessionSeedModal.tsx
+++ b/ts/components/dialog/SessionSeedModal.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { MouseEvent, useEffect, useState } from 'react';
import { ToastUtils } from '../../session/utils';
import { matchesHash } from '../../util/passwordUtils';
@@ -12,6 +12,7 @@ import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/S
import { SessionWrapperModal } from '../SessionWrapperModal';
import { getCurrentRecoveryPhrase } from '../../util/storage';
import styled from 'styled-components';
+import { saveQRCode } from '../../util/saveQRCode';
interface PasswordProps {
setPasswordValid: (val: boolean) => any;
@@ -90,15 +91,25 @@ interface SeedProps {
onClickCopy?: () => any;
}
-const StyledRecoveryPhrase = styled.i`
- margin-bottom: var(--margins-md);
-`;
+const StyledRecoveryPhrase = styled.i``;
const StyledQRImage = styled.div`
width: fit-content;
- margin: 0 auto;
+ margin: 0 auto var(--margins-lg);
+ cursor: pointer;
`;
+const handleSaveQRCode = (event: MouseEvent) => {
+ event.preventDefault();
+ saveQRCode(
+ 'session-recovery-phrase',
+ '220px',
+ '220px',
+ 'var(--white-color)',
+ 'var(--black-color)'
+ );
+};
+
const Seed = (props: SeedProps) => {
const { recoveryPhrase, onClickCopy } = props;
const i18n = window.i18n;
@@ -132,6 +143,15 @@ const Seed = (props: SeedProps) => {
{i18n('recoveryPhraseSavePromptMain')}
+
+
+
+
{
{recoveryPhrase}
-
-
-
{
) : null;
unreadCountDiv = (
- {unreadCount > CONVERSATION.MAX_UNREAD_COUNT ? `${CONVERSATION.MAX_UNREAD_COUNT}+` : unreadCount}
+ {unreadCount > CONVERSATION.MAX_UNREAD_COUNT
+ ? `${CONVERSATION.MAX_UNREAD_COUNT}+`
+ : unreadCount}
);
}
diff --git a/ts/util/saveQRCode.ts b/ts/util/saveQRCode.ts
new file mode 100644
index 000000000..785a9f315
--- /dev/null
+++ b/ts/util/saveQRCode.ts
@@ -0,0 +1,29 @@
+import { saveURLAsFile } from './saveURLAsFile';
+
+export function saveQRCode(
+ filename: string,
+ width: string,
+ height: string,
+ backgroundColor: string,
+ foregroundColor: string
+): void {
+ const qrSVG = document.querySelector('.qr-image svg');
+ if (qrSVG) {
+ // tslint:disable-next-line: no-http-string
+ qrSVG.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+ qrSVG.setAttribute('width', width);
+ qrSVG.setAttribute('height', height);
+ let content = qrSVG.outerHTML;
+ content = content.replaceAll(backgroundColor, 'white');
+ content = content.replaceAll(foregroundColor, 'black');
+ const file = new Blob([content], { type: 'text/plain' });
+ const url = URL.createObjectURL(file);
+ saveURLAsFile({
+ filename: `${filename}-${new Date().toISOString()}.svg`,
+ url,
+ document,
+ });
+ } else {
+ window.log.info('[saveQRCode] QR code not found');
+ }
+}