Commit 391aa9f0 authored by Ashu Ghildiyal's avatar Ashu Ghildiyal
Browse files

frontend & desktop: Move releaseNotes,download update to client storage

We were handling release notes, download update in main process of
electron we want to remove this and take the storage at one place.
This patch moves all the logic related to releaseNotes and update
available to client side and uses the client storage.
parent 0376e60f
Showing with 180 additions and 205 deletions
+180 -205
import { Octokit } from '@octokit/core';
import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
import { app, BrowserWindow, ipcMain, Menu, MenuItem, screen, shell } from 'electron';
import { IpcMainEvent, MenuItemConstructorOptions } from 'electron/main';
......@@ -7,7 +6,6 @@ import Store from 'electron-store';
import { i18n as I18n } from 'i18next';
import open from 'open';
import path from 'path';
import semver from 'semver';
import url from 'url';
import yargs from 'yargs';
import i18n from './i18next.config';
......@@ -308,51 +306,7 @@ function startElecron() {
});
mainWindow.webContents.on('dom-ready', () => {
const octokit = new Octokit();
async function fetchRelease() {
const githubReleaseURL = `GET /repos/{owner}/{repo}/releases`;
// get me all the releases -> default decreasing order of releases
const response = await octokit.request(githubReleaseURL, {
owner: 'kinvolk',
repo: 'headlamp',
});
const latestRelease = response.data.find(
release => !release.name.startsWith('headlamp-helm')
);
if (semver.gt(latestRelease.name, appVersion) && !process.env.FLATPAK_ID) {
mainWindow.webContents.send('update_available', {
downloadURL: latestRelease.html_url,
});
}
/*
check if there is already a version in store if it exists don't store the current version
this check will help us later in determining whether we are on the latest release or not
*/
const storedAppVersion = store.get('app_version');
if (!storedAppVersion) {
store.set('app_version', appVersion);
} else if (semver.lt(storedAppVersion as string, appVersion)) {
// get the release notes for the version with which the app was built with
const githubReleaseURL = `GET /repos/{owner}/{repo}/releases/tags/v${appVersion}`;
const response = await octokit.request(githubReleaseURL, {
owner: 'kinvolk',
repo: 'headlamp',
});
const [releaseNotes] = response.data.body.split('<!-- end-release-notes -->');
mainWindow.webContents.send('showReleaseNotes', {
releaseNotes,
appVersion,
});
// set the store version to latest so that we don't show release notes on
// every start of app
store.set('app_version', appVersion);
}
}
const isUpdateCheckingDisabled = store.get('disable_update_check');
if (!isUpdateCheckingDisabled) {
fetchRelease();
}
mainWindow.webContents.send('appVersion', appVersion);
});
mainWindow.on('closed', () => {
......
......@@ -4,23 +4,13 @@ import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('desktopApi', {
send: (channel, data) => {
// allowed channels
const validChannels = [
'updateAvailable',
'locale',
'showReleaseNotes',
'disableUpdateChecking',
];
const validChannels = ['locale', 'appVersion'];
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data);
}
},
receive: (channel, func) => {
const validChannels = [
'updateAvailable',
'locale',
'showReleaseNotes',
'disableUpdateChecking',
];
const validChannels = ['locale', 'appVersion'];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, ({}, ...args) => func(...args));
......
......@@ -1303,98 +1303,6 @@
"upath": "^1.1.1"
}
},
"@octokit/auth-token": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
"dependencies": {
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
}
}
},
"@octokit/graphql": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz",
"integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.3.0.tgz",
"integrity": "sha512-ZFyQ30tNpoATI7o+Z9MWFUzUgWisB8yduhcky7S4UYsRijgIGSnwUKzPBDGzf/Xkx1DuvUtqzvmuFlDSqPJqmQ=="
},
"@octokit/request": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz",
"integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
},
"dependencies": {
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
}
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/types": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.19.0.tgz",
"integrity": "sha512-9wdZFiJfonDyU6DjIgDHxAIn92vdSUBOwAXbO2F9rOFt6DJwuAkyGLu1CvdJPphCbPBoV9iSDMX7y4fu0v6AtA==",
"requires": {
"@octokit/openapi-types": "^8.3.0"
}
},
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
......@@ -1899,11 +1807,6 @@
"dev": true,
"optional": true
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"binary-extensions": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
......@@ -2883,11 +2786,6 @@
}
}
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"detect-node": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
......@@ -4972,11 +4870,6 @@
"dev": true,
"optional": true
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"normalize-package-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.1.tgz",
......@@ -5124,6 +5017,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
......@@ -5750,6 +5644,7 @@
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
......@@ -6476,11 +6371,6 @@
"crypto-random-string": "^2.0.0"
}
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
......@@ -6791,7 +6681,8 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"write-file-atomic": {
"version": "3.0.3",
......
......@@ -106,14 +106,12 @@
},
"dependencies": {
"@babel/runtime": "^7.12.5",
"@octokit/core": "^3.5.1",
"@types/semver": "^7.3.8",
"electron-log": "^4.2.4",
"electron-store": "^8.0.0",
"i18next": "^20.3.2",
"i18next-node-fs-backend": "^2.1.3",
"open": "^7.3.1",
"semver": "^7.3.5",
"yargs": "^16.2.0"
}
}
......@@ -2362,6 +2362,98 @@
}
}
},
"@octokit/auth-token": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
"dependencies": {
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
}
}
},
"@octokit/graphql": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz",
"integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "9.7.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-9.7.0.tgz",
"integrity": "sha512-TUJ16DJU8mekne6+KVcMV5g6g/rJlrnIKn7aALG9QrNpnEipFc1xjoarh0PKaAWf2Hf+HwthRKYt+9mCm5RsRg=="
},
"@octokit/request": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.1.tgz",
"integrity": "sha512-Ls2cfs1OfXaOKzkcxnqw5MR6drMA/zWX/LIS/p8Yjdz7QKTPQLMsB3R+OvoxE6XnXeXEE2X7xe4G4l4X0gRiKQ==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
},
"dependencies": {
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
}
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/types": {
"version": "6.25.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.25.0.tgz",
"integrity": "sha512-bNvyQKfngvAd/08COlYIN54nRgxskmejgywodizQNyiKoXmWRAjKup2/LYwm+T9V0gsKH6tuld1gM0PzmOiB4Q==",
"requires": {
"@octokit/openapi-types": "^9.5.0"
}
},
"@pmmmwh/react-refresh-webpack-plugin": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz",
......@@ -9079,9 +9171,9 @@
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"@types/semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw=="
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now=="
},
"@types/source-list-map": {
"version": "0.1.2",
......@@ -10637,6 +10729,11 @@
"integrity": "sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=",
"dev": true
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"better-opn": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz",
......@@ -13091,6 +13188,11 @@
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"des.js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
......@@ -19367,8 +19469,7 @@
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"dev": true
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-forge": {
"version": "0.10.0",
......@@ -25682,6 +25783,11 @@
"unist-util-is": "^4.0.0"
}
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
......@@ -11,6 +11,7 @@
"@material-ui/core": "^4.12.1",
"@material-ui/lab": "^4.0.0-alpha.60",
"@monaco-editor/react": "^4.2.1",
"@octokit/core": "^3.5.1",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^12.0.0",
"@types/javascript-time-ago": "^2.0.3",
......@@ -21,7 +22,7 @@
"@types/react-dom": "^17.0.9",
"@types/react-redux": "^7.1.18",
"@types/react-router-dom": "^5.1.8",
"@types/semver": "^7.3.7",
"@types/semver": "^7.3.8",
"@types/webpack-env": "^1.16.2",
"@typescript-eslint/eslint-plugin": "^4.28.2",
"@typescript-eslint/parser": "^4.28.2",
......@@ -56,7 +57,7 @@
"redux": "^4.0.5",
"redux-saga": "^1.1.3",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"semver": "^7.3.5",
"typescript": "^4.3.5",
"xterm": "^4.10.0"
},
......
......@@ -16,6 +16,7 @@ import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { makeStyles } from '@material-ui/core/styles';
import Toolbar from '@material-ui/core/Toolbar';
import { Octokit } from '@octokit/core';
import { SnackbarProvider } from 'notistack';
import React from 'react';
import { useTranslation } from 'react-i18next';
......@@ -29,6 +30,7 @@ import {
Switch,
useHistory,
} from 'react-router-dom';
import semver from 'semver';
import { ClusterTitle } from './components/cluster/Chooser';
import ActionsNotifier from './components/common/ActionsNotifier';
import AlertNotification from './components/common/AlertNotification';
......@@ -240,7 +242,7 @@ function AppContainer() {
const isSidebarOpen = useTypedSelector(state => state.ui.sidebar.isSidebarOpen);
const classes = useStyle({ isSidebarOpen });
const [releaseNotes, setReleaseNotes] = React.useState<string>();
const [appVersion, setAppVersion] = React.useState('');
const [releaseDownlaodURL, setReleaseDownloadURL] = React.useState<string | null>(null);
const Router = ({ children }: React.PropsWithChildren<{}>) =>
helpers.isElectron() ? (
<HashRouter>{children}</HashRouter>
......@@ -252,13 +254,54 @@ function AppContainer() {
React.useEffect(() => {
if (desktopApi) {
desktopApi.receive(
'showReleaseNotes',
(data: { releaseNotes: string; appVersion: string }) => {
setReleaseNotes(data.releaseNotes);
setAppVersion(data.appVersion);
desktopApi.receive('appVersion', (currentBuildAppVersion: string) => {
const octokit = new Octokit();
async function fetchRelease() {
const githubReleaseURL = `GET /repos/{owner}/{repo}/releases`;
// get me all the releases -> default decreasing order of releases
const response = await octokit.request(githubReleaseURL, {
owner: 'kinvolk',
repo: 'headlamp',
});
const latestRelease = response.data.find(
release => !release.name?.startsWith('headlamp-helm')
);
if (
latestRelease &&
semver.gt(latestRelease.name as string, currentBuildAppVersion) &&
!process.env.FLATPAK_ID
) {
setReleaseDownloadURL(latestRelease.html_url);
}
/*
check if there is already a version in store if it exists don't store the current version
this check will help us later in determining whether we are on the latest release or not
*/
const storedAppVersion = localStorage.getItem('app_version');
if (!storedAppVersion) {
localStorage.setItem('app_version', currentBuildAppVersion);
} else if (semver.lt(storedAppVersion as string, currentBuildAppVersion)) {
// get the release notes for the version with which the app was built with
const githubReleaseURL = `GET /repos/{owner}/{repo}/releases/tags/v${currentBuildAppVersion}`;
const response = await octokit.request(githubReleaseURL, {
owner: 'kinvolk',
repo: 'headlamp',
});
const [releaseNotes] = response.data.body.split('<!-- end-release-notes -->');
setReleaseNotes(releaseNotes);
// set the store version to latest so that we don't show release notes on
// every start of app
localStorage.setItem('app_version', currentBuildAppVersion);
}
}
);
const isUpdateCheckingDisabled = JSON.parse(
localStorage.getItem('disable_update_check') || 'false'
);
if (!isUpdateCheckingDisabled) {
fetchRelease();
}
});
}
}, []);
......@@ -269,8 +312,8 @@ function AppContainer() {
horizontal: 'left',
}}
>
<UpdatePopup />
{releaseNotes && <ReleaseNotesModal releaseNotes={releaseNotes} appVersion={appVersion} />}
{releaseDownlaodURL && <UpdatePopup releaseDownloadURL={releaseDownlaodURL} />}
{releaseNotes && <ReleaseNotesModal releaseNotes={releaseNotes} />}
<Router>
<Link href="#main" className={classes.visuallyHidden}>
Skip to main content
......
......@@ -9,11 +9,10 @@ import ReactMarkdown from 'react-markdown';
interface ReleaseNotesModalProps {
releaseNotes: string;
appVersion: string;
}
export default function ReleaseNotesModal(props: ReleaseNotesModalProps) {
const { releaseNotes, appVersion } = props;
const { releaseNotes } = props;
const [showReleaseNotes, setShowReleaseNotes] = React.useState(Boolean(releaseNotes));
const theme = useTheme();
const { t } = useTranslation('frequent');
......@@ -30,6 +29,7 @@ export default function ReleaseNotesModal(props: ReleaseNotesModalProps) {
minHeight: '50%',
overflow: 'auto',
};
const appVersion = localStorage.getItem('app_version');
return (
<Modal open={showReleaseNotes} BackdropComponent={Backdrop} style={modalStyle}>
......
......@@ -2,18 +2,10 @@ import { Button, Snackbar } from '@material-ui/core';
import React from 'react';
import { useTranslation } from 'react-i18next';
function UpdatePopup() {
const [show, setShow] = React.useState(false);
const [updateDownloadURL, setUpdateDownloadURL] = React.useState<string | undefined>();
function UpdatePopup(props: { releaseDownloadURL: string }) {
const [show, setShow] = React.useState(true);
const { releaseDownloadURL } = props;
const { t } = useTranslation('frequent');
const { desktopApi } = window;
React.useEffect(() => {
desktopApi &&
desktopApi.receive('updateAvailable', (data: { downloadURL: string }) => {
setShow(true);
setUpdateDownloadURL(data.downloadURL);
});
}, []);
return (
<Snackbar
......@@ -29,13 +21,13 @@ function UpdatePopup() {
message={t('An update is available')}
action={
<React.Fragment>
<Button color="secondary" onClick={() => window.open(updateDownloadURL)}>
<Button color="secondary" onClick={() => window.open(releaseDownloadURL)}>
{t('frequent|More')}
</Button>
<Button
color="inherit"
onClick={() => {
desktopApi.send('disableUpdateChecking');
localStorage.setItem('disable_update_check', 'true');
setShow(false);
}}
>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment