Новая обработка обновлений в соответствии с новым протоколом предоставляемым SDU серверами
This commit is contained in:
@@ -1,29 +1,36 @@
|
|||||||
import { Button, MantineRadius } from "@mantine/core";
|
import { Button, MantineRadius } from "@mantine/core";
|
||||||
import { IconRefresh } from "@tabler/icons-react";
|
import { IconRefresh } from "@tabler/icons-react";
|
||||||
import { AnimatedRoundedProgress } from "../AnimatedRoundedProgress/AnimatedRoundedProgress";
|
import { AnimatedRoundedProgress } from "../AnimatedRoundedProgress/AnimatedRoundedProgress";
|
||||||
import { UpdateStatus, useUpdater } from "@/app/hooks/useUpdater";
|
import { useUpdater } from "@/app/providers/UpdateProvider/useUpdater";
|
||||||
|
import { UpdateStatus } from "@/app/providers/UpdateProvider/UpdateProvider";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
interface UpdateAlertProps {
|
interface UpdateAlertProps {
|
||||||
radius?: MantineRadius;
|
radius?: MantineRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Компонент для отображения кнопки обновлений если оно доступно, и прогресса загрузки если обновление уже скачивается
|
||||||
|
*/
|
||||||
export function UpdateAlert(props : UpdateAlertProps) {
|
export function UpdateAlert(props : UpdateAlertProps) {
|
||||||
const radius = props.radius || 0;
|
const radius = props.radius || 0;
|
||||||
const {
|
const {
|
||||||
appUpdateUrl,
|
|
||||||
kernelUpdateUrl,
|
kernelUpdateUrl,
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
updateStatus,
|
updateStatus,
|
||||||
kernelOutdatedForNextAppUpdates,
|
|
||||||
downloadLastApplicationUpdate,
|
downloadLastApplicationUpdate,
|
||||||
restartAppForUpdateApply,
|
restartAppForUpdateApply,
|
||||||
|
checkForUpdates
|
||||||
} = useUpdater();
|
} = useUpdater();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkForUpdates();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{updateStatus == UpdateStatus.IDLE && <>
|
{updateStatus == UpdateStatus.KERNEL_UPDATE_NEED && <>
|
||||||
{kernelOutdatedForNextAppUpdates && <>
|
|
||||||
<Button h={45} leftSection={
|
<Button h={45} leftSection={
|
||||||
<IconRefresh size={15}/>
|
<IconRefresh size={15}/>
|
||||||
} onClick={() => {
|
} onClick={() => {
|
||||||
@@ -32,14 +39,13 @@ export function UpdateAlert(props : UpdateAlertProps) {
|
|||||||
Kernel update required
|
Kernel update required
|
||||||
</Button>
|
</Button>
|
||||||
</>}
|
</>}
|
||||||
{!kernelOutdatedForNextAppUpdates && appUpdateUrl != "" && <>
|
{updateStatus == UpdateStatus.APP_UPDATE_AVAILABLE && <>
|
||||||
<Button h={45} onClick={downloadLastApplicationUpdate} leftSection={
|
<Button h={45} onClick={downloadLastApplicationUpdate} leftSection={
|
||||||
<IconRefresh size={15}/>
|
<IconRefresh size={15}/>
|
||||||
} fullWidth variant={'gradient'} gradient={{ from: 'blue', to: 'green', deg: 233 }} radius={radius}>
|
} fullWidth variant={'gradient'} gradient={{ from: 'blue', to: 'green', deg: 233 }} radius={radius}>
|
||||||
New version available
|
New version available
|
||||||
</Button>
|
</Button>
|
||||||
</>}
|
</>}
|
||||||
</>}
|
|
||||||
{updateStatus == UpdateStatus.DOWNLOADING && <>
|
{updateStatus == UpdateStatus.DOWNLOADING && <>
|
||||||
<Button h={45} leftSection={
|
<Button h={45} leftSection={
|
||||||
<AnimatedRoundedProgress value={downloadProgress} />
|
<AnimatedRoundedProgress value={downloadProgress} />
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import { PacketRequestUpdate } from "../providers/ProtocolProvider/protocol/packets/packet.requestupdate";
|
|
||||||
import { APPLICATION_ARCH, APPLICATION_PLATFROM, CORE_VERSION } from "../constants";
|
|
||||||
import { PacketKernelUpdate } from "../providers/ProtocolProvider/protocol/packets/packet.kernelupdate";
|
|
||||||
import { usePacket } from "../providers/ProtocolProvider/usePacket";
|
|
||||||
import { PacketAppUpdate } from "../providers/ProtocolProvider/protocol/packets/packet.appupdate";
|
|
||||||
import { compareVersions } from "../utils/update";
|
|
||||||
import { useSender } from "../providers/ProtocolProvider/useSender";
|
|
||||||
import { useConsoleLogger } from "./useConsoleLogger";
|
|
||||||
import { useFileStorage } from "./useFileStorage";
|
|
||||||
import { APP_VERSION } from "../version";
|
|
||||||
import { useMemory } from "../providers/MemoryProvider/useMemory";
|
|
||||||
|
|
||||||
export enum UpdateStatus {
|
|
||||||
IDLE,
|
|
||||||
DOWNLOADING,
|
|
||||||
COMPILE,
|
|
||||||
READY_FOR_RESTART
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useUpdater() {
|
|
||||||
const send = useSender();
|
|
||||||
const [kernelOutdatedForNextAppUpdates,
|
|
||||||
setKernelOutdatedForNextAppUpdates] = useState(false);
|
|
||||||
const [kernelUpdateUrl, setKernelUpdateUrl] = useState("");
|
|
||||||
const [appUpdateUrl, setAppUpdateUrl] = useState("");
|
|
||||||
const [appActualVersion, setAppActualVersion] = useState("");
|
|
||||||
const [kernelActualVersion, setKernelActualVersion] = useState("");
|
|
||||||
const [downloadProgress, setDownloadProgress] = useMemory<number>("dp", 0, true);
|
|
||||||
const [updateStatus, setUpdateStatus] = useMemory<UpdateStatus>("us", UpdateStatus.IDLE, true);
|
|
||||||
const {error, info} = useConsoleLogger('useUpdater');
|
|
||||||
const {writeFile} = useFileStorage();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let packet = new PacketRequestUpdate();
|
|
||||||
packet.setAppVersion(APP_VERSION);
|
|
||||||
packet.setKernelVersion(CORE_VERSION);
|
|
||||||
packet.setArch(APPLICATION_ARCH);
|
|
||||||
packet.setPlatform(APPLICATION_PLATFROM);
|
|
||||||
send(packet);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
usePacket(0x0D, (packet : PacketKernelUpdate) => {
|
|
||||||
let url = packet.getUrl();
|
|
||||||
let version = packet.getVersion();
|
|
||||||
setKernelActualVersion(version);
|
|
||||||
setKernelUpdateUrl(url);
|
|
||||||
console.info("Kernel update available: ", version, url);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
usePacket(0x0E, (packet : PacketAppUpdate) => {
|
|
||||||
let url = packet.getUrl();
|
|
||||||
let version = packet.getVersion();
|
|
||||||
let kernelVersionRequired = packet.getKernelVersionRequired();
|
|
||||||
if(compareVersions(CORE_VERSION, kernelVersionRequired) < 0){
|
|
||||||
error("Kernel version is outdated. Cannot update app.");
|
|
||||||
setKernelOutdatedForNextAppUpdates(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setAppActualVersion(version);
|
|
||||||
setAppUpdateUrl(url);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const downloadLastApplicationUpdate = () => {
|
|
||||||
if(appUpdateUrl == ""){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(updateStatus != UpdateStatus.IDLE){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setUpdateStatus(UpdateStatus.DOWNLOADING);
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("GET", appUpdateUrl, true);
|
|
||||||
xhr.responseType = "blob";
|
|
||||||
|
|
||||||
xhr.onprogress = (event) => {
|
|
||||||
if (event.lengthComputable) {
|
|
||||||
const percentComplete = (event.loaded / event.total) * 100;
|
|
||||||
setDownloadProgress(Math.round(percentComplete));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.onload = async () => {
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
setUpdateStatus(UpdateStatus.COMPILE);
|
|
||||||
const blob : Blob = xhr.response;
|
|
||||||
let bundleName = `bundle ${appActualVersion}.zip`;
|
|
||||||
await writeFile(bundleName, Buffer.from(await blob.arrayBuffer()));
|
|
||||||
info("Update downloaded, starting compiler...");
|
|
||||||
await window.electron.ipcRenderer.invoke('update:installServiceUpdate', bundleName);
|
|
||||||
info("Update compiled successfully.");
|
|
||||||
setTimeout(() => {
|
|
||||||
setUpdateStatus(UpdateStatus.READY_FOR_RESTART);
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.onerror = () => {
|
|
||||||
error("Error downloading update");
|
|
||||||
setUpdateStatus(UpdateStatus.IDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
const restartAppForUpdateApply = () => {
|
|
||||||
if(updateStatus != UpdateStatus.READY_FOR_RESTART){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.electron.ipcRenderer.invoke('update:restartApp');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
appUpdateUrl,
|
|
||||||
kernelUpdateUrl,
|
|
||||||
appActualVersion,
|
|
||||||
kernelActualVersion,
|
|
||||||
kernelOutdatedForNextAppUpdates,
|
|
||||||
downloadProgress,
|
|
||||||
updateStatus,
|
|
||||||
downloadLastApplicationUpdate,
|
|
||||||
restartAppForUpdateApply
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,64 +2,34 @@ import Packet from "../packet";
|
|||||||
import Stream from "../stream";
|
import Stream from "../stream";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запрашивает сервер обновлений
|
||||||
|
*/
|
||||||
export class PacketRequestUpdate extends Packet {
|
export class PacketRequestUpdate extends Packet {
|
||||||
|
|
||||||
private kernelVersion: string = "";
|
private updateServer: string = "";
|
||||||
private appVersion: string = "";
|
|
||||||
private arch: string = "";
|
|
||||||
private platform: string = "";
|
|
||||||
|
|
||||||
public getPacketId(): number {
|
public getPacketId(): number {
|
||||||
return 0xA;
|
return 0xA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public _receive(stream: Stream): void {
|
public _receive(stream: Stream): void {
|
||||||
this.kernelVersion = stream.readString();
|
this.updateServer = stream.readString();
|
||||||
this.appVersion = stream.readString();
|
|
||||||
this.arch = stream.readString();
|
|
||||||
this.platform = stream.readString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public _send(): Promise<Stream> | Stream {
|
public _send(): Promise<Stream> | Stream {
|
||||||
let stream = new Stream();
|
let stream = new Stream();
|
||||||
stream.writeInt16(this.getPacketId());
|
stream.writeInt16(this.getPacketId());
|
||||||
stream.writeString(this.kernelVersion);
|
stream.writeString(this.updateServer);
|
||||||
stream.writeString(this.appVersion);
|
|
||||||
stream.writeString(this.arch);
|
|
||||||
stream.writeString(this.platform);
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setKernelVersion(version: string): void {
|
public setUpdateServer(updateServer: string) {
|
||||||
this.kernelVersion = version;
|
this.updateServer = updateServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getKernelVersion(): string {
|
public getUpdateServer(): string {
|
||||||
return this.kernelVersion;
|
return this.updateServer;
|
||||||
}
|
|
||||||
|
|
||||||
public setAppVersion(version: string): void {
|
|
||||||
this.appVersion = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getAppVersion(): string {
|
|
||||||
return this.appVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setArch(arch: string): void {
|
|
||||||
this.arch = arch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getArch(): string {
|
|
||||||
return this.arch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPlatform(platform: string): void {
|
|
||||||
this.platform = platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPlatform(): string {
|
|
||||||
return this.platform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
172
app/providers/UpdateProvider/UpdateProvider.tsx
Normal file
172
app/providers/UpdateProvider/UpdateProvider.tsx
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
import { createContext, useEffect, useRef, useState } from "react";
|
||||||
|
import { PacketRequestUpdate } from "../ProtocolProvider/protocol/packets/packet.requestupdate";
|
||||||
|
import { useSender } from "../ProtocolProvider/useSender";
|
||||||
|
import { usePacket } from "../ProtocolProvider/usePacket";
|
||||||
|
import { useConsoleLogger } from "@/app/hooks/useConsoleLogger";
|
||||||
|
import { useFileStorage } from "@/app/hooks/useFileStorage";
|
||||||
|
import { APPLICATION_ARCH, APPLICATION_PLATFROM, CORE_VERSION } from "@/app/constants";
|
||||||
|
import { APP_VERSION } from "@/app/version";
|
||||||
|
|
||||||
|
export interface UpdateProviderProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum UpdateStatus {
|
||||||
|
DOWNLOADING,
|
||||||
|
COMPILE,
|
||||||
|
READY_FOR_RESTART,
|
||||||
|
NO_UPDATES,
|
||||||
|
KERNEL_UPDATE_NEED,
|
||||||
|
APP_UPDATE_AVAILABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ответ от сервера обновлений на запрос наличия обновлений. Содержит информацию о том, какие обновления есть, и ссылки на них
|
||||||
|
*/
|
||||||
|
export interface UpdateServerResponse {
|
||||||
|
version: string;
|
||||||
|
platform: string;
|
||||||
|
arch: string;
|
||||||
|
kernel_update_required: boolean;
|
||||||
|
service_pack_url: string;
|
||||||
|
kernel_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateContextValue {
|
||||||
|
updateStatus: UpdateStatus;
|
||||||
|
downloadProgress: number;
|
||||||
|
kernelUpdateUrl: string;
|
||||||
|
checkForUpdates: () => void;
|
||||||
|
downloadLastApplicationUpdate: () => void;
|
||||||
|
restartAppForUpdateApply: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const UpdateProviderContext = createContext<UpdateContextValue | null>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Провайдер для управления обновлениями приложения. При инициализации
|
||||||
|
* запрашвиает сервер обновлений с основного сервера и получает актуальные версии с сервера обновлений
|
||||||
|
*/
|
||||||
|
export function UpdateProvider(props: UpdateProviderProps) {
|
||||||
|
const send = useSender();
|
||||||
|
const {info, error} = useConsoleLogger('UpdateProvider');
|
||||||
|
const updateServerRef = useRef<string | null>(null);
|
||||||
|
const [updateStatus, setUpdateStatus] = useState<UpdateStatus>(UpdateStatus.NO_UPDATES);
|
||||||
|
const [downloadProgress, setDownloadProgress] = useState<number>(0);
|
||||||
|
const [kernelUpdateUrl, setKernelUpdateUrl] = useState<string>("");
|
||||||
|
const [appUpdateUrl, setAppUpdateUrl] = useState<string>("");
|
||||||
|
const [appActualVersion, setAppActualVersion] = useState<string>("");
|
||||||
|
const {writeFile} = useFileStorage();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let packet = new PacketRequestUpdate();
|
||||||
|
/**
|
||||||
|
* Клиент хочет получить сервер обновлений с основного сервера
|
||||||
|
*/
|
||||||
|
packet.setUpdateServer("");
|
||||||
|
send(packet);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
usePacket(0xA, (packet : PacketRequestUpdate) => {
|
||||||
|
updateServerRef.current = packet.getUpdateServer();
|
||||||
|
info(`Update server ${updateServerRef.current}`);
|
||||||
|
checkForUpdates();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const checkForUpdates = async () => {
|
||||||
|
if(updateServerRef.current == null){
|
||||||
|
/**
|
||||||
|
* SDU еще не определен
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Запрашиваем обновления с SDU сервера
|
||||||
|
*/
|
||||||
|
let response = await fetch(`${updateServerRef.current}/updates/get?app=${APP_VERSION}&kernel=${CORE_VERSION}&arch=${APPLICATION_ARCH}&platform=${APPLICATION_PLATFROM}`);
|
||||||
|
if(response.status != 200){
|
||||||
|
error("Failed to check for updates: " + response.statusText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let updateInfo : UpdateServerResponse = await response.json();
|
||||||
|
console.info("Update info: ", updateInfo);
|
||||||
|
if(updateInfo.kernel_update_required){
|
||||||
|
/**
|
||||||
|
* Чтобы дальше получать обновления приложения нужно сначала обновить ядро
|
||||||
|
*/
|
||||||
|
setUpdateStatus(UpdateStatus.KERNEL_UPDATE_NEED);
|
||||||
|
setKernelUpdateUrl(updateInfo.kernel_url);
|
||||||
|
info("Kernel update needed for next application updates");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(updateInfo.service_pack_url != null){
|
||||||
|
/**
|
||||||
|
* Доступно обновление приложения, которое можно скачать и установить
|
||||||
|
*/
|
||||||
|
setUpdateStatus(UpdateStatus.APP_UPDATE_AVAILABLE);
|
||||||
|
setAppUpdateUrl(updateInfo.service_pack_url);
|
||||||
|
setAppActualVersion(updateInfo.version);
|
||||||
|
info("Application update available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadLastApplicationUpdate = async () => {
|
||||||
|
if(updateStatus != UpdateStatus.APP_UPDATE_AVAILABLE){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setUpdateStatus(UpdateStatus.DOWNLOADING);
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", updateServerRef.current + appUpdateUrl, true);
|
||||||
|
xhr.responseType = "blob";
|
||||||
|
|
||||||
|
xhr.onprogress = (event) => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
const percentComplete = (event.loaded / event.total) * 100;
|
||||||
|
setDownloadProgress(Math.round(percentComplete));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.onload = async () => {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
setUpdateStatus(UpdateStatus.COMPILE);
|
||||||
|
const blob : Blob = xhr.response;
|
||||||
|
let bundleName = `bundle ${appActualVersion}.zip`;
|
||||||
|
await writeFile(bundleName, Buffer.from(await blob.arrayBuffer()));
|
||||||
|
info("Update downloaded, starting compiler...");
|
||||||
|
await window.electron.ipcRenderer.invoke('update:installServiceUpdate', bundleName);
|
||||||
|
info("Update compiled successfully.");
|
||||||
|
setTimeout(() => {
|
||||||
|
setUpdateStatus(UpdateStatus.READY_FOR_RESTART);
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onerror = () => {
|
||||||
|
error("Error downloading update");
|
||||||
|
setUpdateStatus(UpdateStatus.APP_UPDATE_AVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
const restartAppForUpdateApply = () => {
|
||||||
|
if(updateStatus != UpdateStatus.READY_FOR_RESTART){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.electron.ipcRenderer.invoke('update:restartApp');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UpdateProviderContext.Provider value={{
|
||||||
|
updateStatus,
|
||||||
|
downloadProgress,
|
||||||
|
kernelUpdateUrl,
|
||||||
|
checkForUpdates,
|
||||||
|
downloadLastApplicationUpdate,
|
||||||
|
restartAppForUpdateApply
|
||||||
|
}}>
|
||||||
|
{props.children}
|
||||||
|
</UpdateProviderContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
10
app/providers/UpdateProvider/useUpdater.ts
Normal file
10
app/providers/UpdateProvider/useUpdater.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { UpdateContextValue, UpdateProviderContext } from "./UpdateProvider";
|
||||||
|
|
||||||
|
export function useUpdater() : UpdateContextValue {
|
||||||
|
const context = useContext(UpdateProviderContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error("useUpdater must be used within an UpdateProvider");
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import { useAccountProvider } from "@/app/providers/AccountProvider/useAccountPr
|
|||||||
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
|
import { useLogout } from "@/app/providers/AccountProvider/useLogout";
|
||||||
import { useUpdateMessage } from "@/app/hooks/useUpdateMessage";
|
import { useUpdateMessage } from "@/app/hooks/useUpdateMessage";
|
||||||
import { useDeviceMessage } from "@/app/hooks/useDeviceMessage";
|
import { useDeviceMessage } from "@/app/hooks/useDeviceMessage";
|
||||||
|
import { UpdateProvider } from "@/app/providers/UpdateProvider/UpdateProvider";
|
||||||
|
|
||||||
export function Main() {
|
export function Main() {
|
||||||
const { mainColor, borderColor } = useRosettaColors();
|
const { mainColor, borderColor } = useRosettaColors();
|
||||||
@@ -146,6 +147,7 @@ export function Main() {
|
|||||||
<PrivateView>
|
<PrivateView>
|
||||||
<SystemAccountProvider>
|
<SystemAccountProvider>
|
||||||
<TransportProvider>
|
<TransportProvider>
|
||||||
|
<UpdateProvider>
|
||||||
<Flex direction={'row'} style={{
|
<Flex direction={'row'} style={{
|
||||||
height: '100%',
|
height: '100%',
|
||||||
width: '100vw',
|
width: '100vw',
|
||||||
@@ -192,6 +194,7 @@ export function Main() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
)}
|
)}
|
||||||
|
</UpdateProvider>
|
||||||
</TransportProvider>
|
</TransportProvider>
|
||||||
</SystemAccountProvider>
|
</SystemAccountProvider>
|
||||||
</PrivateView>);
|
</PrivateView>);
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ import { SettingsAlert } from "@/app/components/SettingsAlert/SettingsAlert";
|
|||||||
import { SettingsInput } from "@/app/components/SettingsInput/SettingsInput";
|
import { SettingsInput } from "@/app/components/SettingsInput/SettingsInput";
|
||||||
import { UpdateAlert } from "@/app/components/UpdateAlert/UpdateAlert";
|
import { UpdateAlert } from "@/app/components/UpdateAlert/UpdateAlert";
|
||||||
import { CORE_VERSION } from "@/app/constants";
|
import { CORE_VERSION } from "@/app/constants";
|
||||||
import { useUpdater } from "@/app/hooks/useUpdater";
|
import { UpdateStatus } from "@/app/providers/UpdateProvider/UpdateProvider";
|
||||||
|
import { useUpdater } from "@/app/providers/UpdateProvider/useUpdater";
|
||||||
import { APP_VERSION } from "@/app/version";
|
import { APP_VERSION } from "@/app/version";
|
||||||
import { Box, Text } from "@mantine/core";
|
import { Box, Text } from "@mantine/core";
|
||||||
|
|
||||||
export function Update() {
|
export function Update() {
|
||||||
const {appUpdateUrl, kernelUpdateUrl, kernelOutdatedForNextAppUpdates} = useUpdater();
|
const {updateStatus} = useUpdater();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Breadcrumbs text="Updates"></Breadcrumbs>
|
<Breadcrumbs text="Updates"></Breadcrumbs>
|
||||||
<InternalScreen>
|
<InternalScreen>
|
||||||
{(kernelUpdateUrl != "" || appUpdateUrl != "" || kernelOutdatedForNextAppUpdates) && (
|
{(updateStatus != UpdateStatus.NO_UPDATES) && (
|
||||||
<SettingsAlert type="error" text="We recommend always using the latest version of the application. You can also update the app using the button in the left menu below the list of dialogs."></SettingsAlert>
|
<SettingsAlert type="error" text="We recommend always using the latest version of the application. You can also update the app using the button in the left menu below the list of dialogs."></SettingsAlert>
|
||||||
)}
|
)}
|
||||||
<Box mt={'sm'}>
|
<Box mt={'sm'}>
|
||||||
|
|||||||
Reference in New Issue
Block a user