-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
244 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { useState, type FC, useEffect } from 'react'; | ||
|
||
import Modal, { ModalTransition, ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog'; | ||
import { useRecoilState, useSetRecoilState } from 'recoil'; | ||
import { updateModalOpenState, updateStatusState } from '../state/settings'; | ||
import Button from '@atlaskit/button'; | ||
import useAsyncEffect from 'use-async-effect'; | ||
import { checkUpdate, installUpdate, onUpdaterEvent } from '@tauri-apps/api/updater'; | ||
import { getVersion } from '@tauri-apps/api/app'; | ||
import { css } from '@emotion/react'; | ||
import { relaunch } from '@tauri-apps/api/process'; | ||
|
||
const bodyStyle = css` | ||
pre { | ||
font-family: var(--font-family); | ||
} | ||
`; | ||
|
||
export const UpdateModalRenderer: FC = () => { | ||
const [modalOpen] = useRecoilState(updateModalOpenState); | ||
|
||
return <ModalTransition>{modalOpen && <UpdateModal />}</ModalTransition>; | ||
}; | ||
|
||
export const UpdateModal: FC = () => { | ||
const setModalOpen = useSetRecoilState(updateModalOpenState); | ||
const [isUpdating, setIsUpdating] = useState(false); | ||
const [updateStatus, setUpdateStatus] = useRecoilState(updateStatusState); | ||
|
||
const [currentVersion, setCurrentVersion] = useState(''); | ||
const [latestVersion, setLatestVersion] = useState(''); | ||
const [updateBody, setUpdateBody] = useState(''); | ||
|
||
useAsyncEffect(async () => { | ||
setCurrentVersion(await getVersion()); | ||
const { manifest } = await checkUpdate(); | ||
if (manifest) { | ||
setLatestVersion(manifest.version); | ||
setUpdateBody(manifest.body); | ||
} | ||
}, []); | ||
|
||
const doUpdate = async () => { | ||
try { | ||
setUpdateStatus('Starting update...'); | ||
setIsUpdating(true); | ||
|
||
await installUpdate(); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
}; | ||
|
||
const handleModalClose = () => { | ||
if (isUpdating) { | ||
return; | ||
} | ||
setModalOpen(false); | ||
}; | ||
|
||
useAsyncEffect(async () => { | ||
if (updateStatus === 'Installed.') { | ||
await relaunch(); | ||
} | ||
}, [updateStatus]); | ||
|
||
const skipUpdate = () => {}; | ||
|
||
const canRender = currentVersion && latestVersion && updateBody; | ||
|
||
return ( | ||
canRender && ( | ||
<Modal onClose={handleModalClose}> | ||
<ModalHeader> | ||
<ModalTitle>🎉 Update Available</ModalTitle> | ||
</ModalHeader> | ||
<ModalBody> | ||
<div css={bodyStyle}> | ||
<p> | ||
A new version <strong>{latestVersion}</strong> of Rivet is available. You are on currently on version{' '} | ||
<strong>{currentVersion}</strong>. Would you like to install it now? | ||
</p> | ||
<h4>Update Notes:</h4> | ||
<pre>{updateBody}</pre> | ||
</div> | ||
</ModalBody> | ||
<ModalFooter> | ||
{isUpdating ? ( | ||
<div>{updateStatus}</div> | ||
) : ( | ||
<> | ||
<Button appearance="primary" onClick={doUpdate}> | ||
Update | ||
</Button> | ||
<Button appearance="subtle" onClick={skipUpdate}> | ||
Skip this update | ||
</Button> | ||
<Button onClick={() => setModalOpen(false)}>Cancel</Button> | ||
</> | ||
)} | ||
</ModalFooter> | ||
</Modal> | ||
) | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { useEffect } from 'react'; | ||
import { checkUpdate, installUpdate, onUpdaterEvent } from '@tauri-apps/api/updater'; | ||
import useAsyncEffect from 'use-async-effect'; | ||
import { toast } from 'react-toastify'; | ||
import { css } from '@emotion/react'; | ||
import { isInTauri } from '../utils/tauri'; | ||
import { useSetRecoilState } from 'recoil'; | ||
import { updateModalOpenState } from '../state/settings'; | ||
|
||
const toastStyle = css` | ||
display: flex; | ||
flex-direction: column; | ||
.actions { | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: flex-end; | ||
} | ||
button { | ||
background-color: var(--grey); | ||
color: var(--grey-lightest); | ||
font-family: apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', | ||
'Droid Sans', 'Helvetica Neue', sans-serif; | ||
border: 1px solid var(--grey-lightest); | ||
padding: 8px 12px; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
white-space: nowrap; | ||
font-size: 14px; | ||
cursor: pointer; | ||
&.primary { | ||
background-color: var(--primary); | ||
color: var(--foreground-on-primary); | ||
} | ||
} | ||
`; | ||
|
||
export function useCheckForUpdate() { | ||
const setUpdateModalOpen = useSetRecoilState(updateModalOpenState); | ||
|
||
return async () => { | ||
const { shouldUpdate, manifest } = await checkUpdate(); | ||
|
||
if (shouldUpdate) { | ||
toast.success( | ||
({ closeToast }) => ( | ||
<div css={toastStyle}> | ||
<div className="info">Rivet version {manifest?.version} is now available!</div> | ||
<div className="actions"> | ||
<button className="primary" onClick={() => setUpdateModalOpen(true)}> | ||
Install | ||
</button> | ||
<button onClick={() => installUpdate()}>Skip</button> | ||
<button onClick={() => closeToast?.()}>Not Now</button> | ||
</div> | ||
</div> | ||
), | ||
{ | ||
autoClose: false, | ||
closeButton: false, | ||
}, | ||
); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { useEffect } from 'react'; | ||
import { isInTauri } from '../utils/tauri'; | ||
import { onUpdaterEvent } from '@tauri-apps/api/updater'; | ||
import { useSetRecoilState } from 'recoil'; | ||
import { updateStatusState } from '../state/settings'; | ||
import { match } from 'ts-pattern'; | ||
import useAsyncEffect from 'use-async-effect'; | ||
import { relaunch } from '@tauri-apps/api/process'; | ||
|
||
export function useMonitorUpdateStatus() { | ||
const setUpdateStatus = useSetRecoilState(updateStatusState); | ||
|
||
useAsyncEffect(async () => { | ||
let unlisten: any | undefined = undefined; | ||
|
||
if (isInTauri()) { | ||
unlisten = await onUpdaterEvent(({ error, status }) => { | ||
match(status as typeof status | 'DOWNLOADED') // -.- | ||
.with('PENDING', async () => setUpdateStatus('Downloading...')) | ||
.with('DONE', async () => setUpdateStatus('Installed.')) | ||
.with('ERROR', async () => setUpdateStatus(`Error - ${error}`)) | ||
.with('UPTODATE', async () => setUpdateStatus('Up to date.')) | ||
.with('DOWNLOADED', async () => setUpdateStatus('Installing...')) | ||
.exhaustive(); | ||
}); | ||
} | ||
|
||
return () => { | ||
if (unlisten) { | ||
unlisten(); | ||
} | ||
}; | ||
}, []); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters