mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
Show updater status banner for all statuses (#396)
Also adds updater channel to about modal
This commit is contained in:
parent
3ade98879b
commit
e5e6259dec
@ -27,6 +27,7 @@ contextBridge.exposeInMainWorld("api", {
|
|||||||
ipcRenderer.on("fullscreen-change", (_event, isFullScreen) => callback(isFullScreen)),
|
ipcRenderer.on("fullscreen-change", (_event, isFullScreen) => callback(isFullScreen)),
|
||||||
onUpdaterStatusChange: (callback) => ipcRenderer.on("app-update-status", (_event, status) => callback(status)),
|
onUpdaterStatusChange: (callback) => ipcRenderer.on("app-update-status", (_event, status) => callback(status)),
|
||||||
getUpdaterStatus: () => ipcRenderer.sendSync("get-app-update-status"),
|
getUpdaterStatus: () => ipcRenderer.sendSync("get-app-update-status"),
|
||||||
|
getUpdaterChannel: () => ipcRenderer.sendSync("get-updater-channel"),
|
||||||
installAppUpdate: () => ipcRenderer.send("install-app-update"),
|
installAppUpdate: () => ipcRenderer.send("install-app-update"),
|
||||||
onMenuItemAbout: (callback) => ipcRenderer.on("menu-item-about", callback),
|
onMenuItemAbout: (callback) => ipcRenderer.on("menu-item-about", callback),
|
||||||
updateWindowControlsOverlay: (rect) => ipcRenderer.send("update-window-controls-overlay", rect),
|
updateWindowControlsOverlay: (rect) => ipcRenderer.send("update-window-controls-overlay", rect),
|
||||||
|
@ -29,7 +29,7 @@ export class Updater {
|
|||||||
|
|
||||||
autoUpdater.autoInstallOnAppQuit = settings["autoupdate:installonquit"];
|
autoUpdater.autoInstallOnAppQuit = settings["autoupdate:installonquit"];
|
||||||
|
|
||||||
// Only update the release channel if it's specified, otherwise use the one configured in the artifact.
|
// Only update the release channel if it's specified, otherwise use the one configured in the updater.
|
||||||
const channel = settings["autoupdate:channel"];
|
const channel = settings["autoupdate:channel"];
|
||||||
if (channel) {
|
if (channel) {
|
||||||
autoUpdater.channel = channel;
|
autoUpdater.channel = channel;
|
||||||
@ -180,6 +180,9 @@ ipcMain.on("install-app-update", () => fireAndForget(() => updater?.promptToInst
|
|||||||
ipcMain.on("get-app-update-status", (event) => {
|
ipcMain.on("get-app-update-status", (event) => {
|
||||||
event.returnValue = updater?.status;
|
event.returnValue = updater?.status;
|
||||||
});
|
});
|
||||||
|
ipcMain.on("get-updater-channel", (event) => {
|
||||||
|
event.returnValue = isDev() ? "dev" : (autoUpdater.channel ?? "latest");
|
||||||
|
});
|
||||||
|
|
||||||
let autoUpdateLock = false;
|
let autoUpdateLock = false;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ interface AboutModalProps {}
|
|||||||
const AboutModal = ({}: AboutModalProps) => {
|
const AboutModal = ({}: AboutModalProps) => {
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
const [details] = useState(() => getApi().getAboutModalDetails());
|
const [details] = useState(() => getApi().getAboutModalDetails());
|
||||||
|
const [updaterChannel] = useState(() => getApi().getUpdaterChannel());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal className="about-modal" onClose={() => modalsModel.popModal()}>
|
<Modal className="about-modal" onClose={() => modalsModel.popModal()}>
|
||||||
@ -32,6 +33,8 @@ const AboutModal = ({}: AboutModalProps) => {
|
|||||||
<div className="section text-standard">
|
<div className="section text-standard">
|
||||||
Client Version {details.version} ({isDev() ? "dev-" : ""}
|
Client Version {details.version} ({isDev() ? "dev-" : ""}
|
||||||
{details.buildTime})
|
{details.buildTime})
|
||||||
|
<br />
|
||||||
|
Update Channel: {updaterChannel}
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<LinkButton
|
<LinkButton
|
||||||
|
@ -97,13 +97,4 @@
|
|||||||
--os-handle-interactive-area-offset: 0px;
|
--os-handle-interactive-area-offset: 0px;
|
||||||
--os-handle-border-radius: 2px;
|
--os-handle-border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-available-button {
|
|
||||||
height: 80%;
|
|
||||||
opacity: 0.7;
|
|
||||||
margin: auto 4px;
|
|
||||||
color: black;
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
flex: 0 0 fit-content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ import { useAtomValue } from "jotai";
|
|||||||
import { OverlayScrollbars } from "overlayscrollbars";
|
import { OverlayScrollbars } from "overlayscrollbars";
|
||||||
import React, { createRef, useCallback, useEffect, useRef, useState } from "react";
|
import React, { createRef, useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { debounce } from "throttle-debounce";
|
import { debounce } from "throttle-debounce";
|
||||||
import { Button } from "../element/button";
|
|
||||||
import { Tab } from "./tab";
|
import { Tab } from "./tab";
|
||||||
import "./tabbar.less";
|
import "./tabbar.less";
|
||||||
|
import { UpdateStatusBanner } from "./updatestatus";
|
||||||
|
|
||||||
const TAB_DEFAULT_WIDTH = 130;
|
const TAB_DEFAULT_WIDTH = 130;
|
||||||
const TAB_MIN_WIDTH = 100;
|
const TAB_MIN_WIDTH = 100;
|
||||||
@ -74,8 +74,6 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
|
|
||||||
const isFullScreen = useAtomValue(atoms.isFullScreen);
|
const isFullScreen = useAtomValue(atoms.isFullScreen);
|
||||||
|
|
||||||
const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom);
|
|
||||||
|
|
||||||
let prevDelta: number;
|
let prevDelta: number;
|
||||||
let prevDragDirection: string;
|
let prevDragDirection: string;
|
||||||
|
|
||||||
@ -477,24 +475,6 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
</div>
|
</div>
|
||||||
) : undefined;
|
) : undefined;
|
||||||
|
|
||||||
function onUpdateAvailableClick() {
|
|
||||||
getApi().installAppUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
let updateAvailableLabel: React.ReactNode = null;
|
|
||||||
if (appUpdateStatus === "ready") {
|
|
||||||
updateAvailableLabel = (
|
|
||||||
<Button
|
|
||||||
ref={updateStatusButtonRef}
|
|
||||||
className="update-available-button"
|
|
||||||
title="Click to Install Update"
|
|
||||||
onClick={onUpdateAvailableClick}
|
|
||||||
>
|
|
||||||
Update Available
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={tabbarWrapperRef} className="tab-bar-wrapper">
|
<div ref={tabbarWrapperRef} className="tab-bar-wrapper">
|
||||||
<WindowDrag ref={draggerLeftRef} className="left" />
|
<WindowDrag ref={draggerLeftRef} className="left" />
|
||||||
@ -527,7 +507,7 @@ const TabBar = React.memo(({ workspace }: TabBarProps) => {
|
|||||||
<i className="fa fa-solid fa-plus fa-fw" />
|
<i className="fa fa-solid fa-plus fa-fw" />
|
||||||
</div>
|
</div>
|
||||||
<WindowDrag ref={draggerRightRef} className="right" />
|
<WindowDrag ref={draggerRightRef} className="right" />
|
||||||
{updateAvailableLabel}
|
<UpdateStatusBanner buttonRef={updateStatusButtonRef} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
11
frontend/app/tab/updatestatus.less
Normal file
11
frontend/app/tab/updatestatus.less
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.update-available-button {
|
||||||
|
height: 80%;
|
||||||
|
margin: auto 4px;
|
||||||
|
color: black;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
flex: 0 0 fit-content;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: unset !important;
|
||||||
|
}
|
||||||
|
}
|
49
frontend/app/tab/updatestatus.tsx
Normal file
49
frontend/app/tab/updatestatus.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { Button } from "@/element/button";
|
||||||
|
import { atoms, getApi } from "@/store/global";
|
||||||
|
import { useAtomValue } from "jotai";
|
||||||
|
import { memo } from "react";
|
||||||
|
import "./updatestatus.less";
|
||||||
|
|
||||||
|
const UpdateStatusBannerComponent = ({ buttonRef }: { buttonRef: React.RefObject<HTMLButtonElement> }) => {
|
||||||
|
const appUpdateStatus = useAtomValue(atoms.updaterStatusAtom);
|
||||||
|
function onClick() {
|
||||||
|
if (appUpdateStatus === "ready") getApi().installAppUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
let buttonText: string;
|
||||||
|
switch (appUpdateStatus) {
|
||||||
|
case "ready":
|
||||||
|
buttonText = "Update Available";
|
||||||
|
break;
|
||||||
|
case "checking":
|
||||||
|
buttonText = "Checking for Updates";
|
||||||
|
break;
|
||||||
|
case "downloading":
|
||||||
|
buttonText = "Downloading Update";
|
||||||
|
break;
|
||||||
|
case "installing":
|
||||||
|
buttonText = "Installing Update";
|
||||||
|
break;
|
||||||
|
case "error":
|
||||||
|
buttonText = "Updater Error: Try Checking Again";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttonText) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
ref={buttonRef}
|
||||||
|
className="update-available-button"
|
||||||
|
title={appUpdateStatus === "ready" ? "Click to Install Update" : buttonText}
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={appUpdateStatus !== "ready"}
|
||||||
|
>
|
||||||
|
{buttonText}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UpdateStatusBanner = memo(UpdateStatusBannerComponent) as typeof UpdateStatusBannerComponent;
|
1
frontend/types/custom.d.ts
vendored
1
frontend/types/custom.d.ts
vendored
@ -67,6 +67,7 @@ declare global {
|
|||||||
onFullScreenChange: (callback: (isFullScreen: boolean) => void) => void;
|
onFullScreenChange: (callback: (isFullScreen: boolean) => void) => void;
|
||||||
onUpdaterStatusChange: (callback: (status: UpdaterStatus) => void) => void;
|
onUpdaterStatusChange: (callback: (status: UpdaterStatus) => void) => void;
|
||||||
getUpdaterStatus: () => UpdaterStatus;
|
getUpdaterStatus: () => UpdaterStatus;
|
||||||
|
getUpdaterChannel: () => string;
|
||||||
installAppUpdate: () => void;
|
installAppUpdate: () => void;
|
||||||
onMenuItemAbout: (callback: () => void) => void;
|
onMenuItemAbout: (callback: () => void) => void;
|
||||||
updateWindowControlsOverlay: (rect: Dimensions) => void;
|
updateWindowControlsOverlay: (rect: Dimensions) => void;
|
||||||
|
Loading…
Reference in New Issue
Block a user