-
Notifications
You must be signed in to change notification settings - Fork 4
Web: have a way to let people know that a newer version of OpenCOR is available #402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import fs from 'node:fs'; | ||
| import path from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
|
|
||
| // Retrieve the version from the package.json file. | ||
|
|
||
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | ||
| const packageJsonPath = path.join(__dirname, '../package.json'); | ||
| const packageJson = JSON.parse(fs.readFileSync(packageJsonPath)); | ||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const { version } = packageJson; | ||
|
|
||
| // Make sure that the dist/assets folder exists. | ||
|
|
||
| const distAssetsPath = path.join(__dirname, '../dist/assets'); | ||
|
|
||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (!fs.existsSync(distAssetsPath)) { | ||
| fs.mkdirSync(distAssetsPath, { recursive: true }); | ||
| } | ||
|
|
||
| // Write the version file. | ||
|
|
||
| fs.writeFileSync(path.join(distAssetsPath, 'version.json'), JSON.stringify({ version }, null, 2)); | ||
|
|
||
| // Log the generated version. | ||
|
|
||
| console.log(`Generated version.json with version ${version}.`); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| import * as vue from 'vue'; | ||
|
|
||
| import packageJson from '../../package.json' with { type: 'json' }; | ||
|
|
||
|
Comment on lines
+1
to
+4
|
||
| import { electronApi } from './electronApi.ts'; | ||
|
|
||
| const { version } = packageJson; | ||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // State to track whether an update is available and the latest version. | ||
|
|
||
| const updateAvailable = vue.ref(false); | ||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const latestVersion = vue.ref<string>(''); | ||
|
|
||
| // Check if a new version is available. | ||
|
|
||
| interface IVersionInfo { | ||
| version: string; | ||
| } | ||
|
|
||
| const checkForUpdates = async (): Promise<boolean> => { | ||
| // Make sure that we are not running the desktop version of OpenCOR. | ||
|
|
||
| if (electronApi) { | ||
| return false; | ||
| } | ||
|
|
||
| // Get the latest version information from the server and compare it with the current version. | ||
|
|
||
| try { | ||
| // Fetch the version.json file from the server with cache busting (i.e. by adding a timestamp query parameter to the | ||
| // URL so that the browser doesn't serve a cached version). | ||
|
|
||
| const response = await fetch(`./assets/version.json?t=${Date.now()}`); | ||
|
|
||
| if (!response.ok) { | ||
| console.warn('Failed to fetch the version information.'); | ||
|
|
||
| updateAvailable.value = false; | ||
| latestVersion.value = ''; | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| const versionInfo: IVersionInfo = await response.json(); | ||
|
|
||
| latestVersion.value = versionInfo.version; | ||
|
|
||
| // Compare versions. | ||
|
|
||
| const isNewer = isNewerVersion(latestVersion.value, version); | ||
|
|
||
| updateAvailable.value = isNewer; | ||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| return isNewer; | ||
| } catch (error) { | ||
| console.error('Failed to check for updates:', error); | ||
|
|
||
| updateAvailable.value = false; | ||
| latestVersion.value = ''; | ||
|
|
||
| return false; | ||
| } | ||
| }; | ||
|
|
||
| // Return whether the first version is newer than the second version. | ||
|
|
||
| const isNewerVersion = (versionA: string, versionB: string): boolean => { | ||
| const partsA = versionA.split('.').map(Number); | ||
| const partsB = versionB.split('.').map(Number); | ||
|
|
||
| for (let i = 0; i < Math.max(partsA.length, partsB.length); ++i) { | ||
| const partA = partsA[i] || 0; | ||
| const partB = partsB[i] || 0; | ||
|
|
||
| if (partA > partB) { | ||
| return true; | ||
| } | ||
|
|
||
| if (partA < partB) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| }; | ||
|
|
||
| // Start periodic version checking (every 5 minutes). | ||
|
|
||
| let checkInterval: number | null = null; | ||
|
|
||
| const startCheck = (): void => { | ||
| // Make sure that we are not running the desktop version of OpenCOR. | ||
|
|
||
| if (electronApi) { | ||
| return; | ||
| } | ||
|
|
||
| // Check immediately on start. | ||
|
|
||
| checkForUpdates(); | ||
|
|
||
| // Then check every 5 minutes. | ||
|
|
||
| if (!checkInterval) { | ||
| checkInterval = window.setInterval( | ||
| () => { | ||
| checkForUpdates(); | ||
| }, | ||
| 5 * 60 * 1000 // Every 5 minutes. | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| // Reload the Web app to get the latest version (force cache bypass). | ||
|
|
||
| const reloadApp = (): void => { | ||
| window.location.replace(window.location.href); | ||
| }; | ||
agarny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // Export the version checking functions and state. | ||
|
|
||
| export { latestVersion, reloadApp, startCheck, updateAvailable }; | ||
Uh oh!
There was an error while loading. Please reload this page.