UNPKG

@kui-shell/plugin-electron-components

Version:

Kui plugin that houses electron-specific React components

229 lines (227 loc) 8.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireDefault(require("react")); var _core = require("@kui-shell/core"); var _TextWithIconWidget = _interopRequireDefault(require("@kui-shell/plugin-client-common/mdist/components/Client/StatusStripe/TextWithIconWidget")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* * Copyright 2020 The Kubernetes Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = void 0 && (void 0).__awaiter || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /* * For debugging, this will reset the dulyNoted bit: * * localStorage.removeItem('kui-shell.org/UpdateChecker/DulyNoted') * */ const Markdown = _react.default.lazy(() => Promise.resolve().then(() => require('@kui-shell/plugin-client-common/mdist/components/Content/Markdown'))); const strings = (0, _core.i18n)('plugin-core-support'); /** Default repo/org */ const repo = 'kubernetes-sigs/kui'; /** Base URL for get */ const baseUrl = () => { try { return require('@kui-shell/client/config.d/repo.json').url; } catch (err) { return `https://api.github.com/repos/${repo}`; } }; /** Releases feed */ const FEED = () => `${baseUrl()}/releases/latest`; /** By default, check for updates once a day */ const DEFAULT_INTERVAL = 24 * 60 * 60 * 1000; /** By default, wait 1 minute after statup for the first check */ const DEFAULT_LAG = 60 * 60 * 1000; /** Remember that the version "duly noted" the availability of particular version in localStorage, using this key */ const DULY_NOTED_KEY = 'kui-shell.org/UpdateChecker/DulyNoted'; /** * GitHub gives back "v8.10.0" and the Kui version command gives back "8.10.0". * * @see https://github.com/IBM/kui/issues/4918 * */ function stripOffPrefixV(githubVersionString) { return githubVersionString.replace(/^v/, ''); } class UpdateChecker extends _react.default.PureComponent { constructor(props) { super(props); this._brewUpgrade = () => (0, _core.pexecInCurrentTab)(`brew upgrade ${this.props.brewName || 'kui'}`); this.state = { pinger: this.initPinger(), currentVersion: undefined, latestVersion: undefined, popover: undefined, dulyNoted: localStorage.getItem(DULY_NOTED_KEY) }; } /** Initialize a timer that periodically checks for updates */ initPinger() { return setInterval(() => { this.checkForUpdates(); }, this.props.interval || DEFAULT_INTERVAL); } /** Ping the release feed to check for the latest release */ checkForUpdates() { Promise.resolve().then(() => require('needle')).then(_ => _.default('get', FEED(), { json: true })).then(res => { const version = res.body.tag_name; const entryForLatestVersion = { title: 'Release Notes from Kui', updated: res.body.published_at, version: res.body.tag_name, content: res.body.body, download: res.body.html_url }; const latestVersion = stripOffPrefixV(version); // see https://github.com/IBM/kui/issues/4918 this.setState(curState => ({ latestVersion, entryForLatestVersion, popover: this.popover(entryForLatestVersion), dulyNoted: curState.dulyNoted && curState.dulyNoted !== latestVersion ? undefined : curState.dulyNoted })); }).catch(err => { console.error('error checking for updates', err); }); } popover(entryForLatestVersion) { if (entryForLatestVersion) { return { className: 'kui--update-checker--popover', onHide: () => this.dulyNoted(), bodyContent: _react.default.createElement(_react.default.Suspense, { fallback: _react.default.createElement("div", null) }, _react.default.createElement(Markdown, { source: entryForLatestVersion.content, baseUrl: baseUrl() })), headerContent: _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("div", null, entryForLatestVersion.title), _react.default.createElement("div", null, _react.default.createElement("strong", null, entryForLatestVersion.version)), _react.default.createElement("div", { className: "sub-text even-smaller-text" }, process.platform === 'darwin' ? _react.default.createElement("a", { href: "#", onClick: this._brewUpgrade }, "Upgrade") : _react.default.createElement("a", { href: entryForLatestVersion.download }, "Download"))) }; } } /** What version are we running? */ getCurrentVersion() { return __awaiter(this, void 0, void 0, function* () { if (!this.state.currentVersion) { const tab = (0, _core.getCurrentTab)(); if (!tab || !tab.REPL) { if (tab && !tab.REPL) { _core.Events.eventChannelUnsafe.once(`/tab/new/${tab.uuid}`, () => this.getCurrentVersion()); } return; } const currentVersion = yield tab.REPL.qexec('version'); this.setState({ currentVersion }); } }); } componentDidMount() { return __awaiter(this, void 0, void 0, function* () { yield this.getCurrentVersion(); setTimeout(() => this.checkForUpdates(), this.props.lag || DEFAULT_LAG); }); } /** Bye! */ componentWillUnmount() { if (this.state.pinger) { clearInterval(this.state.pinger); } } /** Given current state, is an update available? */ isUpdateAvailable() { const isSemverUpdateAvailable = () => { const latest = this.state.latestVersion.split('.').map(_ => parseInt(_)); const current = this.state.currentVersion.split('.').map(_ => parseInt(_)); const res = latest[0] > current[0] || latest[0] === current[0] && latest[1] > current[1] || latest[0] === current[0] && latest[1] === current[1] && latest[2] > current[2]; return res; }; return this.state.currentVersion && this.state.latestVersion && isSemverUpdateAvailable() && this.state.latestVersion !== this.state.dulyNoted; } /** Text for update available notification */ text() { return this.isUpdateAvailable() ? strings('Update available', this.state.latestVersion) : ''; } /** User has acknoledged the notification */ dulyNoted() { return __awaiter(this, void 0, void 0, function* () { try { localStorage.setItem(DULY_NOTED_KEY, this.state.latestVersion); } catch (err) { console.error('Error opening releases page'); } this.setState({ dulyNoted: this.state.latestVersion }); }); } title() { return strings('Version X is available. Click to see the changelog and download the new release.', this.state.latestVersion); } render() { if (this.isUpdateAvailable()) { return _react.default.createElement(_TextWithIconWidget.default, { id: "kui--plugin-core-support--update-checker", className: this.props.className, viewLevel: "info", text: this.text(), title: this.title(), position: "top-end", popover: this.state.popover }); } else { return _react.default.createElement(_react.default.Fragment, null); } } } exports.default = UpdateChecker;