commit
a207845a67
18
src/components/DialogBox/DialogIcon.tsx
Normal file
18
src/components/DialogBox/DialogIcon.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { Box } from '@mui/material';
|
||||
import React from 'react';
|
||||
|
||||
export default function DialogIcon({ icon }: { icon: React.ReactNode }) {
|
||||
return (
|
||||
<Box
|
||||
className="DialogIcon"
|
||||
sx={{
|
||||
svg: {
|
||||
width: '48px',
|
||||
height: '48px',
|
||||
},
|
||||
color: 'stroke.secondary',
|
||||
}}>
|
||||
{icon}
|
||||
</Box>
|
||||
);
|
||||
}
|
|
@ -5,6 +5,12 @@ const DialogBoxBase = styled(Dialog)(({ theme }) => ({
|
|||
padding: theme.spacing(1, 1.5),
|
||||
maxWidth: '346px',
|
||||
},
|
||||
|
||||
'& .DialogIcon': {
|
||||
padding: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(1),
|
||||
},
|
||||
|
||||
'& .MuiDialogTitle-root': {
|
||||
padding: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(1),
|
||||
|
@ -12,6 +18,11 @@ const DialogBoxBase = styled(Dialog)(({ theme }) => ({
|
|||
'& .MuiDialogContent-root': {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
|
||||
'.DialogIcon + .MuiDialogTitle-root': {
|
||||
paddingTop: 0,
|
||||
},
|
||||
|
||||
'.MuiDialogTitle-root + .MuiDialogContent-root': {
|
||||
paddingTop: 0,
|
||||
},
|
||||
|
|
|
@ -13,6 +13,7 @@ import DialogTitleWithCloseButton, {
|
|||
} from './TitleWithCloseButton';
|
||||
import DialogBoxBase from './base';
|
||||
import { DialogBoxAttributes } from 'types/dialogBox';
|
||||
import DialogIcon from './DialogIcon';
|
||||
|
||||
type IProps = React.PropsWithChildren<
|
||||
Omit<DialogProps, 'onClose' | 'maxSize'> & {
|
||||
|
@ -48,6 +49,7 @@ export default function DialogBox({
|
|||
maxWidth={size}
|
||||
onClose={handleClose}
|
||||
{...props}>
|
||||
{attributes.icon && <DialogIcon icon={attributes.icon} />}
|
||||
{attributes.title && (
|
||||
<DialogTitleWithCloseButton
|
||||
onClose={
|
||||
|
|
|
@ -120,13 +120,15 @@ export default function SingleInputForm(props: SingleInputFormProps) {
|
|||
onClick={props.secondaryButtonAction}
|
||||
size="large"
|
||||
color="secondary"
|
||||
sx={{ mt: 2, mb: 4, mr: 1, ...buttonSx }}
|
||||
sx={{
|
||||
'&&&': { mt: 2, mb: 4, mr: 1, ...buttonSx },
|
||||
}}
|
||||
{...restSubmitButtonProps}>
|
||||
{constants.CANCEL}
|
||||
</Button>
|
||||
)}
|
||||
<SubmitButton
|
||||
sx={{ mt: 2, ...buttonSx }}
|
||||
sx={{ '&&&': { mt: 2, ...buttonSx } }}
|
||||
buttonText={props.buttonText}
|
||||
loading={loading}
|
||||
{...restSubmitButtonProps}
|
||||
|
|
|
@ -28,6 +28,8 @@ import {
|
|||
import { CustomError } from 'utils/error';
|
||||
import { clearLogsIfLocalStorageLimitExceeded } from 'utils/logging';
|
||||
import isElectron from 'is-electron';
|
||||
import ElectronUpdateService from 'services/electron/update';
|
||||
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
|
||||
|
||||
export const MessageContainer = styled('div')`
|
||||
background-color: #111;
|
||||
|
@ -138,6 +140,27 @@ export default function App({ Component, err }) {
|
|||
clearLogsIfLocalStorageLimitExceeded();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isElectron()) {
|
||||
const showUpdateDialog = () =>
|
||||
setDialogMessage({
|
||||
icon: <AutoAwesomeIcon />,
|
||||
title: constants.UPDATE_AVAILABLE,
|
||||
content: constants.UPDATE_AVAILABLE_MESSAGE,
|
||||
close: {
|
||||
text: constants.INSTALL_ON_NEXT_LAUNCH,
|
||||
variant: 'secondary',
|
||||
},
|
||||
proceed: {
|
||||
action: () => ElectronUpdateService.updateAndRestart(),
|
||||
text: constants.INSTALL_NOW,
|
||||
variant: 'accent',
|
||||
},
|
||||
});
|
||||
ElectronUpdateService.registerUpdateEventListener(showUpdateDialog);
|
||||
}
|
||||
});
|
||||
|
||||
const setUserOnline = () => setOffline(false);
|
||||
const setUserOffline = () => setOffline(true);
|
||||
const resetSharedFiles = () => setSharedFiles(null);
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ElectronAPIs } from 'types/electron';
|
|||
|
||||
class ElectronService {
|
||||
private electronAPIs: ElectronAPIs;
|
||||
private isBundledApp: boolean = false;
|
||||
|
||||
constructor() {
|
||||
this.electronAPIs = globalThis['ElectronAPIs'];
|
||||
|
|
23
src/services/electron/update.ts
Normal file
23
src/services/electron/update.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { ElectronAPIs } from 'types/electron';
|
||||
|
||||
class ElectronUpdateService {
|
||||
private electronAPIs: ElectronAPIs;
|
||||
|
||||
constructor() {
|
||||
this.electronAPIs = globalThis['ElectronAPIs'];
|
||||
}
|
||||
|
||||
registerUpdateEventListener(showUpdateDialog: () => void) {
|
||||
if (this.electronAPIs?.registerUpdateEventListener) {
|
||||
this.electronAPIs.registerUpdateEventListener(showUpdateDialog);
|
||||
}
|
||||
}
|
||||
|
||||
updateAndRestart() {
|
||||
if (this.electronAPIs?.updateAndRestart) {
|
||||
this.electronAPIs.updateAndRestart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ElectronUpdateService();
|
|
@ -1,6 +1,7 @@
|
|||
import { ButtonProps } from '@mui/material';
|
||||
|
||||
export interface DialogBoxAttributes {
|
||||
icon?: React.ReactNode;
|
||||
title?: string;
|
||||
staticBackdrop?: boolean;
|
||||
nonClosable?: boolean;
|
||||
|
|
|
@ -65,4 +65,6 @@ export interface ElectronAPIs {
|
|||
logToDisk: (msg: string) => void;
|
||||
convertHEIC(fileData: Uint8Array): Promise<Uint8Array>;
|
||||
openLogDirectory: () => void;
|
||||
registerUpdateEventListener: (showUpdateDialog: () => void) => void;
|
||||
updateAndRestart: () => void;
|
||||
}
|
||||
|
|
|
@ -825,6 +825,10 @@ const englishConstants = {
|
|||
UPLOADED_TO_SINGLE_COLLECTION: 'Uploaded to single collection',
|
||||
UPLOADED_TO_SEPARATE_COLLECTIONS: 'Uploaded to separate collections',
|
||||
NEVERMIND: 'Nevermind',
|
||||
UPDATE_AVAILABLE: 'Update available',
|
||||
UPDATE_AVAILABLE_MESSAGE: 'A new version of ente is ready to be installed.',
|
||||
INSTALL_NOW: `Install now`,
|
||||
INSTALL_ON_NEXT_LAUNCH: 'Install on next launch',
|
||||
};
|
||||
|
||||
export default englishConstants;
|
||||
|
|
Loading…
Reference in a new issue