Skip to content

Commit

Permalink
react fix
Browse files Browse the repository at this point in the history
  • Loading branch information
JasminDreasond committed Aug 14, 2023
1 parent d9453d7 commit 3fb8c35
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 143 deletions.
80 changes: 39 additions & 41 deletions src/components/update/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import React, { ReactNode } from 'react'
import { createPortal } from 'react-dom'
import styles from './modal.module.scss'
import React, { ReactNode } from 'react';
import { createPortal } from 'react-dom';
import './modal.module.scss';

const ModalTemplate: React.FC<React.PropsWithChildren<{
title?: ReactNode
footer?: ReactNode
cancelText?: string
okText?: string
onCancel?: () => void
onOk?: () => void
width?: number
}>> = props => {
const ModalTemplate: React.FC<
React.PropsWithChildren<{
title?: ReactNode;
footer?: ReactNode;
cancelText?: string;
okText?: string;
onCancel?: () => void;
onOk?: () => void;
width?: number;
}>
> = (props) => {
const {
title,
children,
Expand All @@ -20,48 +22,44 @@ const ModalTemplate: React.FC<React.PropsWithChildren<{
onCancel,
onOk,
width = 530,
} = props
} = props;

return (
<div className={styles.modal}>
<div className='modal-mask' />
<div className='modal-warp'>
<div className='modal-content' style={{ width }}>
<div className='modal-header'>
<div className='modal-header-text'>{title}</div>
<span
className='modal-close'
onClick={onCancel}
>
<svg
viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg"
>
<path d="M557.312 513.248l265.28-263.904c12.544-12.48 12.608-32.704 0.128-45.248-12.512-12.576-32.704-12.608-45.248-0.128l-265.344 263.936-263.04-263.84C236.64 191.584 216.384 191.52 203.84 204 191.328 216.48 191.296 236.736 203.776 249.28l262.976 263.776L201.6 776.8c-12.544 12.48-12.608 32.704-0.128 45.248 6.24 6.272 14.464 9.44 22.688 9.44 8.16 0 16.32-3.104 22.56-9.312l265.216-263.808 265.44 266.24c6.24 6.272 14.432 9.408 22.656 9.408 8.192 0 16.352-3.136 22.592-9.344 12.512-12.48 12.544-32.704 0.064-45.248L557.312 513.248z" p-id="2764" fill="currentColor">
</path>
<div>
<div className="modal-mask" />
<div className="modal-warp">
<div className="modal-content" style={{ width }}>
<div className="modal-header">
<div className="modal-header-text">{title}</div>
<span className="modal-close" onClick={onCancel}>
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path
d="M557.312 513.248l265.28-263.904c12.544-12.48 12.608-32.704 0.128-45.248-12.512-12.576-32.704-12.608-45.248-0.128l-265.344 263.936-263.04-263.84C236.64 191.584 216.384 191.52 203.84 204 191.328 216.48 191.296 236.736 203.776 249.28l262.976 263.776L201.6 776.8c-12.544 12.48-12.608 32.704-0.128 45.248 6.24 6.272 14.464 9.44 22.688 9.44 8.16 0 16.32-3.104 22.56-9.312l265.216-263.808 265.44 266.24c6.24 6.272 14.432 9.408 22.656 9.408 8.192 0 16.352-3.136 22.592-9.344 12.512-12.48 12.544-32.704 0.064-45.248L557.312 513.248z"
p-id="2764"
fill="currentColor"
></path>
</svg>
</span>
</div>
<div className='modal-body'>{children}</div>
<div className="modal-body">{children}</div>
{typeof footer !== 'undefined' ? (
<div className='modal-footer'>
<div className="modal-footer">
<button onClick={onCancel}>{cancelText}</button>
<button onClick={onOk}>{okText}</button>
</div>
) : footer}
) : (
footer
)}
</div>
</div>
</div>
)
}
);
};

const Modal = (props: Parameters<typeof ModalTemplate>[0] & { open: boolean }) => {
const { open, ...omit } = props
const { open, ...omit } = props;

return createPortal(
open ? ModalTemplate(omit) : null,
document.body,
)
}
return createPortal(open ? ModalTemplate(omit) : null, document.body);
};

export default Modal
export default Modal;
31 changes: 15 additions & 16 deletions src/components/update/Progress/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import React from 'react'
import styles from './progress.module.scss'
import React from 'react';
import './progress.module.scss';

const Progress: React.FC<React.PropsWithChildren<{
percent?: number
}>> = props => {
const { percent = 0 } = props
const Progress: React.FC<
React.PropsWithChildren<{
percent?: number;
}>
> = (props) => {
const { percent = 0 } = props;

return (
<div className={styles.progress}>
<div className='progress-pr'>
<div
className='progress-rate'
style={{ width: `${percent}%` }}
/>
<div>
<div className="progress-pr">
<div className="progress-rate" style={{ width: `${percent}%` }} />
</div>
<span className='progress-num'>{(percent ?? 0).toString().substring(0,4)}%</span>
<span className="progress-num">{(percent ?? 0).toString().substring(0, 4)}%</span>
</div>
)
}
);
};

export default Progress
export default Progress;
177 changes: 91 additions & 86 deletions src/components/update/index.tsx
Original file line number Diff line number Diff line change
@@ -1,92 +1,98 @@
import { ipcRenderer } from 'electron'
import type { ProgressInfo } from 'electron-updater'
import { useCallback, useEffect, useState } from 'react'
import Modal from '@/components/update/Modal'
import Progress from '@/components/update/Progress'
import styles from './update.module.scss'
import { ipcRenderer } from 'electron';
import type { ProgressInfo } from 'electron-updater';
import React, { useCallback, useEffect, useState } from 'react';
import Modal from '@/components/update/Modal';
import Progress from '@/components/update/Progress';
import './update.module.scss';

const Update = () => {
const [checking, setChecking] = useState(false)
const [updateAvailable, setUpdateAvailable] = useState(false)
const [versionInfo, setVersionInfo] = useState<VersionInfo>()
const [updateError, setUpdateError] = useState<ErrorType>()
const [progressInfo, setProgressInfo] = useState<Partial<ProgressInfo>>()
const [modalOpen, setModalOpen] = useState<boolean>(false)
const [checking, setChecking] = useState(false);
const [updateAvailable, setUpdateAvailable] = useState(false);
const [versionInfo, setVersionInfo] = useState<VersionInfo>();
const [updateError, setUpdateError] = useState<ErrorType>();
const [progressInfo, setProgressInfo] = useState<Partial<ProgressInfo>>();
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [modalBtn, setModalBtn] = useState<{
cancelText?: string
okText?: string
onCancel?: () => void
onOk?: () => void
cancelText?: string;
okText?: string;
onCancel?: () => void;
onOk?: () => void;
}>({
onCancel: () => setModalOpen(false),
onOk: () => ipcRenderer.invoke('start-download'),
})
});

const checkUpdate = async () => {
setChecking(true)
setChecking(true);
/**
* @type {import('electron-updater').UpdateCheckResult | null | { message: string, error: Error }}
*/
const result = await ipcRenderer.invoke('check-update')
setProgressInfo({ percent: 0 })
setChecking(false)
setModalOpen(true)
const result = await ipcRenderer.invoke('check-update');
setProgressInfo({ percent: 0 });
setChecking(false);
setModalOpen(true);
if (result?.error) {
setUpdateAvailable(false)
setUpdateError(result?.error)
setUpdateAvailable(false);
setUpdateError(result?.error);
}
}
};

const onUpdateCanAvailable = useCallback((_event: Electron.IpcRendererEvent, arg1: VersionInfo) => {
setVersionInfo(arg1)
setUpdateError(undefined)
// Can be update
if (arg1.update) {
setModalBtn(state => ({
...state,
cancelText: 'Cancel',
okText: 'Update',
onOk: () => ipcRenderer.invoke('start-download'),
}))
setUpdateAvailable(true)
} else {
setUpdateAvailable(false)
}
}, [])
const onUpdateCanAvailable = useCallback(
(_event: Electron.IpcRendererEvent, arg1: VersionInfo) => {
setVersionInfo(arg1);
setUpdateError(undefined);
// Can be update
if (arg1.update) {
setModalBtn((state) => ({
...state,
cancelText: 'Cancel',
okText: 'Update',
onOk: () => ipcRenderer.invoke('start-download'),
}));
setUpdateAvailable(true);
} else {
setUpdateAvailable(false);
}
},
[],
);

const onUpdateError = useCallback((_event: Electron.IpcRendererEvent, arg1: ErrorType) => {
setUpdateAvailable(false)
setUpdateError(arg1)
}, [])
setUpdateAvailable(false);
setUpdateError(arg1);
}, []);

const onDownloadProgress = useCallback((_event: Electron.IpcRendererEvent, arg1: ProgressInfo) => {
setProgressInfo(arg1)
}, [])
const onDownloadProgress = useCallback(
(_event: Electron.IpcRendererEvent, arg1: ProgressInfo) => {
setProgressInfo(arg1);
},
[],
);

const onUpdateDownloaded = useCallback((_event: Electron.IpcRendererEvent, ...args: any[]) => {
setProgressInfo({ percent: 100 })
setModalBtn(state => ({
setProgressInfo({ percent: 100 });
setModalBtn((state) => ({
...state,
cancelText: 'Later',
okText: 'Install now',
onOk: () => ipcRenderer.invoke('quit-and-install'),
}))
}, [])
}));
}, []);

useEffect(() => {
// Get version information and whether to update
ipcRenderer.on('update-can-available', onUpdateCanAvailable)
ipcRenderer.on('update-error', onUpdateError)
ipcRenderer.on('download-progress', onDownloadProgress)
ipcRenderer.on('update-downloaded', onUpdateDownloaded)
ipcRenderer.on('update-can-available', onUpdateCanAvailable);
ipcRenderer.on('update-error', onUpdateError);
ipcRenderer.on('download-progress', onDownloadProgress);
ipcRenderer.on('update-downloaded', onUpdateDownloaded);

return () => {
ipcRenderer.off('update-can-available', onUpdateCanAvailable)
ipcRenderer.off('update-error', onUpdateError)
ipcRenderer.off('download-progress', onDownloadProgress)
ipcRenderer.off('update-downloaded', onUpdateDownloaded)
}
}, [])
ipcRenderer.off('update-can-available', onUpdateCanAvailable);
ipcRenderer.off('update-error', onUpdateError);
ipcRenderer.off('download-progress', onDownloadProgress);
ipcRenderer.off('update-downloaded', onUpdateDownloaded);
};
}, []);

return (
<>
Expand All @@ -96,38 +102,37 @@ const Update = () => {
okText={modalBtn?.okText}
onCancel={modalBtn?.onCancel}
onOk={modalBtn?.onOk}
footer={updateAvailable ? /* hide footer */null : undefined}
footer={updateAvailable ? /* hide footer */ null : undefined}
>
<div className={styles.modalslot}>
{updateError
? (
<div className='update-error'>
<p>Error downloading the latest version.</p>
<p>{updateError.message}</p>
<div>
{updateError ? (
<div className="update-error">
<p>Error downloading the latest version.</p>
<p>{updateError.message}</p>
</div>
) : updateAvailable ? (
<div className="can-available">
<div>The last version is: v{versionInfo?.newVersion}</div>
<div className="new-version-target">
v{versionInfo?.version} -&gt; v{versionInfo?.newVersion}
</div>
) : updateAvailable
? (
<div className='can-available'>
<div>The last version is: v{versionInfo?.newVersion}</div>
<div className='new-version-target'>v{versionInfo?.version} -&gt; v{versionInfo?.newVersion}</div>
<div className='update-progress'>
<div className='progress-title'>Update progress:</div>
<div className='progress-bar'>
<Progress percent={progressInfo?.percent} ></Progress>
</div>
</div>
<div className="update-progress">
<div className="progress-title">Update progress:</div>
<div className="progress-bar">
<Progress percent={progressInfo?.percent}></Progress>
</div>
)
: (
<div className='can-not-available'>{JSON.stringify(versionInfo ?? {}, null, 2)}</div>
)}
</div>
</div>
) : (
<div className="can-not-available">{JSON.stringify(versionInfo ?? {}, null, 2)}</div>
)}
</div>
</Modal>
<button disabled={checking} onClick={checkUpdate}>
{checking ? 'Checking...' : 'Check update'}
</button>
</>
)
}
);
};

export default Update
export default Update;

0 comments on commit 3fb8c35

Please sign in to comment.