"Fossies" - the Fresh Open Source Software Archive

Member "deltachat-desktop-1.3.4/src/renderer/components/dialogs/ImportQrCode.tsx" (18 May 2020, 6564 Bytes) of package /linux/misc/deltachat-desktop-1.3.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TSX (TypeScript with React) source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "ImportQrCode.tsx": 1.3.3_vs_1.3.4.

    1 import React, { useContext, useState, useRef } from 'react'
    2 import DeltaDialog, { DeltaDialogBody, DeltaDialogContent } from './DeltaDialog'
    3 import { DeltaButtonDanger } from './SmallDialog'
    4 import { ScreenContext } from '../../contexts'
    5 import { Icon } from '@blueprintjs/core'
    6 import { LocalSettings } from '../../../shared/shared-types'
    7 import { selectChat } from '../../stores/chat'
    8 import QrReader from 'react-qr-reader'
    9 import { Intent, ProgressBar, Card } from '@blueprintjs/core'
   10 import { DeltaBackend } from '../../delta-remote'
   11 
   12 interface QrStates {
   13   [key: number]: string
   14 }
   15 
   16 export const qrStates: QrStates = {
   17   200: 'QrAskVerifyContact', // id = contact
   18   202: 'QrAskVerifyGroup', // text1=groupname
   19   210: 'QrFprOk', // finger print ok for id=contact
   20   220: 'QrFprMissmatch', // finger print not ok for id=contact
   21   230: 'QrFprWithoutAddr',
   22   250: 'QrAccount', // text1=domain
   23   320: 'QrAddr', // id=contact
   24   330: 'QrText', // text1=text
   25   332: 'QrUrl', // text1=URL
   26   400: 'QrError', // text1=error string
   27 }
   28 
   29 export declare type QrCodeResponse = {
   30   state: keyof QrStates
   31   id: number
   32   text1: string
   33 }
   34 
   35 export async function processOPENPGP4FPRUrl(url: string, callback: any = null) {
   36   const tx = window.translate
   37   let error = false
   38   const response: QrCodeResponse = await DeltaBackend.call('checkQrCode', url)
   39   if (response === null) {
   40     error = true
   41   }
   42   const state = response ? qrStates[response.state] : null
   43   if (error || state === 'QrError' || state === 'QrText') {
   44     window.__userFeedback({
   45       type: 'error',
   46       text: tx('import_qr_error'),
   47     })
   48     return
   49   }
   50 
   51   if (state === 'QrAskVerifyContact') {
   52     const contact = await DeltaBackend.call('contacts.getContact', response.id)
   53     window.__openDialog('ConfirmationDialog', {
   54       message: tx('ask_start_chat_with', contact.address),
   55       confirmLabel: tx('ok'),
   56       cb: async (confirmed: boolean) => {
   57         if (confirmed) {
   58           DeltaBackend.call('joinSecurejoin', url).then(callback)
   59         }
   60       },
   61     })
   62   } else if (state === 'QrAskVerifyGroup') {
   63     window.__openDialog('ConfirmationDialog', {
   64       message: tx('qrscan_ask_join_group', response.text1),
   65       confirmLabel: tx('ok'),
   66       cb: (confirmed: boolean) => {
   67         if (confirmed) {
   68           DeltaBackend.call('joinSecurejoin', url).then(callback)
   69         }
   70         return
   71       },
   72     })
   73   } else if (state === 'QrFprOk') {
   74     const contact = await DeltaBackend.call('contacts.getContact', response.id)
   75     window.__openDialog('ConfirmationDialog', {
   76       message: `The fingerprint of ${contact.displayName} is valid!`,
   77       confirmLabel: tx('ok'),
   78       cb: callback,
   79     })
   80   } else {
   81     window.__userFeedback({
   82       type: 'error',
   83       text: "Don't know what to do with this URL :/",
   84     })
   85   }
   86 }
   87 
   88 export function DeltaDialogImportQrInner({
   89   description,
   90   onClose,
   91 }: {
   92   description: string
   93   onClose: () => void
   94 }) {
   95   const tx = window.translate
   96   const [qrCode, setQrCode] = useState('')
   97   const screenContext = useContext(ScreenContext)
   98   const [secureJoinOngoing, setSecureJoinOngoing] = useState(false)
   99 
  100   const handleScanResult = (chatId: number = null) => {
  101     setSecureJoinOngoing(false)
  102     if (chatId) {
  103       selectChat(chatId)
  104     }
  105     onClose()
  106   }
  107 
  108   const handleResponse = async (scannedQrCode: string) => {
  109     setSecureJoinOngoing(true)
  110     processOPENPGP4FPRUrl(scannedQrCode, handleScanResult)
  111   }
  112 
  113   const qrImageReader = useRef<any>()
  114 
  115   const handleScan = (data: string) => {
  116     if (data) {
  117       handleResponse(data)
  118     }
  119   }
  120 
  121   const cancelProcess = () => {
  122     DeltaBackend.call('stopOngoingProcess')
  123     onClose()
  124   }
  125 
  126   const handleError = (err: string) => {
  127     /* ignore-console-log */
  128     console.error(err)
  129   }
  130 
  131   const openImageDialog = () => {
  132     qrImageReader.current.openImageDialog()
  133   }
  134 
  135   return (
  136     <DeltaDialogBody>
  137       <DeltaDialogContent noPadding>
  138         {secureJoinOngoing && (
  139           <div>
  140             <p className='progress-info'>Secure join in progress...</p>
  141             <ProgressBar intent={Intent.PRIMARY} value={100} />
  142             <DeltaButtonDanger onClick={cancelProcess}>
  143               {tx('cancel')}
  144             </DeltaButtonDanger>
  145           </div>
  146         )}
  147         {!secureJoinOngoing && (
  148           <div className='import-qr-code-dialog'>
  149             <div>
  150               <div>
  151                 <QrReader
  152                   delay={300}
  153                   onError={handleError}
  154                   onScan={handleScan}
  155                   style={{ width: '100%' }}
  156                   facingMode='user'
  157                 />
  158               </div>
  159             </div>
  160             <div className='qr-data'>
  161               <div className='content' aria-label={tx('a11y_qr_data')}>
  162                 {qrCode}
  163               </div>
  164               <div
  165                 title={tx('paste_from_clipboard')}
  166                 className='copy-btn'
  167                 role='button'
  168                 onClick={() => {
  169                   navigator.clipboard.readText().then(handleResponse)
  170                 }}
  171               >
  172                 <Icon icon='clipboard' />
  173               </div>
  174             </div>
  175             <button onClick={openImageDialog} className={'bp3-button'}>
  176               {tx('load_qr_code_as_image')}
  177             </button>
  178             <div className='qr-image-loader'>
  179               <QrReader
  180                 delay={300}
  181                 ref={qrImageReader}
  182                 onError={handleError}
  183                 onScan={handleScan}
  184                 style={{ width: '100%' }}
  185                 legacyMode
  186               />
  187             </div>
  188           </div>
  189         )}
  190       </DeltaDialogContent>
  191     </DeltaDialogBody>
  192   )
  193 }
  194 
  195 export default function ImportQrCode({
  196   onClose,
  197   isOpen,
  198 }: {
  199   onClose: () => void
  200   isOpen: boolean
  201   qrCode: string
  202   deltachat: LocalSettings
  203 }) {
  204   const tx = window.translate
  205   const Dialog = DeltaDialog as any // todo remove this cheat.
  206   return (
  207     <Dialog title={tx('qrscan_title')} isOpen={isOpen} onClose={onClose}>
  208       {navigator.onLine && (
  209         <DeltaDialogImportQrInner description='' onClose={onClose} />
  210       )}
  211       {!navigator.onLine && (
  212         <DeltaDialogContent>
  213           <DeltaDialogBody>
  214             <Card>
  215               <p>{tx('qrshow_join_contact_no_connection_hint')}</p>
  216             </Card>
  217             <button onClick={onClose} className={'bp3-button'}>
  218               <span className='bp3-button-text'>{tx('ok')}</span>
  219             </button>
  220             <br />
  221           </DeltaDialogBody>
  222         </DeltaDialogContent>
  223       )}
  224     </Dialog>
  225   )
  226 }