[ENG-1214] Disable updater for .deb distrubutions (#1455)

* inject __SD_UPDATER__ + don't always create updater store

* clippy

---------

Co-authored-by: jake <77554505+brxken128@users.noreply.github.com>
This commit is contained in:
Brendan Allan 2023-10-11 02:50:44 +08:00 committed by GitHub
parent 0324827ad8
commit 703649348e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 64 deletions

View file

@ -133,6 +133,7 @@ async fn main() -> tauri::Result<()> {
});
let app = app
.plugin(updater::plugin())
.setup(|app| {
let app = app.handle();
@ -189,6 +190,7 @@ async fn main() -> tauri::Result<()> {
file::open_ephemeral_file_with,
file::reveal_items,
theme::lock_app_theme,
// TODO: move to plugin w/tauri-specta
updater::check_for_update,
updater::install_update
])

View file

@ -1,6 +1,5 @@
use tauri::Manager;
use tauri::{plugin::TauriPlugin, Manager, Runtime};
use tokio::sync::Mutex;
use tracing::{error, warn};
#[derive(Debug, Clone, specta::Type, serde::Serialize)]
pub struct Update {
@ -93,3 +92,25 @@ pub async fn install_update(
Ok(())
}
pub fn plugin<R: Runtime>() -> TauriPlugin<R> {
tauri::plugin::Builder::new("sd-updater")
.on_page_load(|window, _| {
#[cfg(target_os = "linux")]
let updater_available = {
let env = window.env();
env.appimage.is_some()
};
#[cfg(not(target_os = "linux"))]
let updater_available = true;
if updater_available {
window
.eval("window.__SD_UPDATER__ = true")
.expect("Failed to inject updater JS");
}
})
.js_init_script(String::new())
.build()
}

View file

@ -5,7 +5,7 @@ import { listen } from '@tauri-apps/api/event';
import { homeDir } from '@tauri-apps/api/path';
import { open } from '@tauri-apps/api/shell';
import { appWindow } from '@tauri-apps/api/window';
import { useEffect } from 'react';
import { useEffect, useRef } from 'react';
import { createBrowserRouter } from 'react-router-dom';
import { RspcProvider } from '@sd/client';
import {
@ -15,14 +15,15 @@ import {
Platform,
PlatformProvider,
routes,
SpacedriveInterface
SpacedriveInterface,
usePlatform
} from '@sd/interface';
import { getSpacedropState } from '@sd/interface/hooks/useSpacedropState';
import '@sd/ui/style';
import * as commands from './commands';
import { updater, useUpdater } from './updater';
import { createUpdater } from './updater';
// TODO: Bring this back once upstream is fixed up.
// const client = hooks.createClient({
@ -76,7 +77,7 @@ const platform = {
showDevtools: () => invoke('show_devtools'),
confirm: (msg, cb) => confirm(msg).then(cb),
userHomeDir: homeDir,
updater,
updater: window.__SD_UPDATER__ ? createUpdater() : undefined,
auth: {
start(url) {
open(url);
@ -121,8 +122,6 @@ export default function App() {
};
}, []);
useUpdater();
return (
<RspcProvider queryClient={queryClient}>
<PlatformProvider platform={platform}>
@ -136,6 +135,8 @@ export default function App() {
// This is required because `ErrorPage` uses the OS which comes from `PlatformProvider`
function AppInner() {
useUpdater();
if (startupError) {
return (
<ErrorPage
@ -147,3 +148,14 @@ function AppInner() {
return <SpacedriveInterface router={router} />;
}
function useUpdater() {
const alreadyChecked = useRef(false);
const { updater } = usePlatform();
useEffect(() => {
if (!alreadyChecked.current && import.meta.env.PROD) updater?.checkForUpdate();
alreadyChecked.current = true;
}, [updater]);
}

View file

@ -62,9 +62,9 @@ export function installUpdate() {
return invoke()<null>("install_update")
}
export type Update = { version: string; body: string | null }
export type OpenWithApplication = { url: string; name: string }
export type AppThemeType = "Auto" | "Light" | "Dark"
export type EphemeralFileOpenResult = { t: "Ok"; c: string } | { t: "Err"; c: string }
export type Update = { version: string; body: string | null }
export type OpenFilePathResult = { t: "NoLibrary" } | { t: "NoFile"; c: number } | { t: "OpenError"; c: [number, string] } | { t: "AllGood"; c: number } | { t: "Internal"; c: string }
export type RevealItem = { Location: { id: number } } | { FilePath: { id: number } } | { Ephemeral: { path: string } }

View file

@ -1,26 +1,68 @@
import { listen } from '@tauri-apps/api/event';
import { useEffect, useRef } from 'react';
import { proxy, useSnapshot } from 'valtio';
import { UpdateStore } from '@sd/interface';
import { toast, ToastId } from '@sd/ui';
import * as commands from './commands';
export const updateStore = proxy<UpdateStore>({
status: 'idle'
});
declare global {
interface Window {
__SD_UPDATER__?: true;
}
}
listen<UpdateStore>('updater', (e) => {
Object.assign(updateStore, e.payload);
console.log(updateStore);
});
export function createUpdater() {
if (!window.__SD_UPDATER__) return;
const onInstallCallbacks = new Set<() => void>();
const updateStore = proxy<UpdateStore>({
status: 'idle'
});
export const updater = {
useSnapshot: () => useSnapshot(updateStore),
checkForUpdate: commands.checkForUpdate,
installUpdate: () => {
listen<UpdateStore>('updater', (e) => {
Object.assign(updateStore, e.payload);
console.log(updateStore);
});
const onInstallCallbacks = new Set<() => void>();
async function checkForUpdate() {
const update = await commands.checkForUpdate();
if (!update) return null;
let id: ToastId | null = null;
const cb = () => {
if (id !== null) toast.dismiss(id);
};
onInstallCallbacks.add(cb);
toast.info(
(_id) => {
id = _id;
return {
title: 'New Update Available',
body: `Version ${update.version}`
};
},
{
onClose() {
onInstallCallbacks.delete(cb);
},
duration: 10 * 1000,
action: {
label: 'Update',
onClick: installUpdate
}
}
);
return update;
}
function installUpdate() {
for (const cb of onInstallCallbacks) {
cb();
}
@ -40,48 +82,10 @@ export const updater = {
return promise;
}
};
async function checkForUpdate() {
const update = await updater.checkForUpdate();
if (!update) return;
let id: ToastId | null = null;
const cb = () => {
if (id !== null) toast.dismiss(id);
return {
useSnapshot: () => useSnapshot(updateStore),
checkForUpdate,
installUpdate
};
onInstallCallbacks.add(cb);
toast.info(
(_id) => {
id = _id;
return {
title: 'New Update Available',
body: `Version ${update.version}`
};
},
{
onClose() {
onInstallCallbacks.delete(cb);
},
duration: 10 * 1000,
action: {
label: 'Update',
onClick: () => updater.installUpdate()
}
}
);
}
export function useUpdater() {
const alreadyChecked = useRef(false);
useEffect(() => {
if (!alreadyChecked.current && import.meta.env.PROD) checkForUpdate();
alreadyChecked.current = true;
}, []);
}