From 1bd0f4be77fcdd6c69799ac78429b08e3552b9d0 Mon Sep 17 00:00:00 2001 From: tomholford Date: Mon, 21 Nov 2022 16:10:59 -0800 Subject: [PATCH] grid: distinguish app sync from system install By using `%kiln-install` instead of `%kiln-sync` for System Updates, this ensures that the `%kids` desk is also updated. Also, address UX feedback: render the entire source ship's patp to avoid ambiguity. (as opposed to truncating a moon's name). --- pkg/grid/src/components/ShipName.tsx | 5 ++- .../{SourceSyncer.tsx => SourceSetter.tsx} | 42 +++++++++++-------- pkg/grid/src/nav/preferences/AppPrefs.tsx | 14 ++++--- .../src/nav/preferences/SystemUpdatePrefs.tsx | 15 +++++-- pkg/grid/src/state/kiln.ts | 19 ++++++++- 5 files changed, 64 insertions(+), 31 deletions(-) rename pkg/grid/src/components/{SourceSyncer.tsx => SourceSetter.tsx} (74%) diff --git a/pkg/grid/src/components/ShipName.tsx b/pkg/grid/src/components/ShipName.tsx index 5ada5a372b..4a49706b19 100644 --- a/pkg/grid/src/components/ShipName.tsx +++ b/pkg/grid/src/components/ShipName.tsx @@ -3,11 +3,12 @@ import React, { HTMLAttributes } from 'react'; type ShipNameProps = { name: string; + truncate?: boolean; } & HTMLAttributes; -export const ShipName = ({ name, ...props }: ShipNameProps) => { +export const ShipName = ({ name, truncate = true, ...props }: ShipNameProps) => { const separator = /([_^-])/; - const citedName = cite(name); + const citedName = truncate ? cite(name) : name; if (!citedName) { return null; diff --git a/pkg/grid/src/components/SourceSyncer.tsx b/pkg/grid/src/components/SourceSetter.tsx similarity index 74% rename from pkg/grid/src/components/SourceSyncer.tsx rename to pkg/grid/src/components/SourceSetter.tsx index 69c63e63c4..b37936f26b 100644 --- a/pkg/grid/src/components/SourceSyncer.tsx +++ b/pkg/grid/src/components/SourceSetter.tsx @@ -1,34 +1,39 @@ import React, { useCallback, useState } from 'react'; import { useAsyncCall } from '../logic/useAsyncCall'; -import useKilnState from '../state/kiln'; import { Button } from './Button'; import { ShipName } from './ShipName'; import { Spinner } from './Spinner'; -interface SourceSyncerProps { +interface SourceSetterProps { appName: string; + srcDesk: string; + srcShip?: string; title: string; - syncDesk: string; - syncShip?: string; + toggleSrc: (desk: string, ship: string) => Promise; } -export default function SourceSyncer({ appName, title, syncDesk, syncShip }: SourceSyncerProps) { - const [newSyncShip, setNewSyncShip] = useState(syncShip ?? ''); - const { toggleSync } = useKilnState(); - const { status: requestStatus, call: setSync } = useAsyncCall(toggleSync); - const syncDirty = newSyncShip !== syncShip; +export default function SourceSetter({ + appName, + srcDesk, + srcShip, + title, + toggleSrc +}: SourceSetterProps) { + const [newSyncShip, setNewSyncShip] = useState(srcShip ?? ''); + const { status: requestStatus, call: handleSubmit } = useAsyncCall(toggleSrc); + const syncDirty = newSyncShip !== srcShip; - const onUnsync = useCallback(() => { - if (!syncShip) { + const onUnset = useCallback(() => { + if (!srcShip) { return; } if ( // eslint-disable-next-line no-alert, no-restricted-globals confirm(`Are you sure you want to unsync ${appName}? You will no longer receive updates.`) ) { - toggleSync(syncDesk, syncShip); + toggleSrc(srcDesk, srcShip); } - }, [syncShip, syncDesk, toggleSync]); + }, [srcShip, srcDesk]); const handleSourceChange = useCallback((e: React.ChangeEvent) => { const { target } = e; @@ -39,26 +44,27 @@ export default function SourceSyncer({ appName, title, syncDesk, syncShip }: Sou const onSubmit = useCallback( async (e: React.FormEvent) => { e.preventDefault(); - await setSync(syncDesk, newSyncShip); + await handleSubmit(srcDesk, newSyncShip); }, - [syncDesk, newSyncShip, toggleSync] + [srcDesk, newSyncShip] ); return ( <>

{title}

- {syncShip ? ( + {srcShip ? ( <>

Automatic Updates

Automatically download and apply updates to keep {appName} up to date.

- OTA Source: + OTA Source:{' '} +

-
diff --git a/pkg/grid/src/nav/preferences/AppPrefs.tsx b/pkg/grid/src/nav/preferences/AppPrefs.tsx index f86f651f6f..3cc00e1b91 100644 --- a/pkg/grid/src/nav/preferences/AppPrefs.tsx +++ b/pkg/grid/src/nav/preferences/AppPrefs.tsx @@ -1,23 +1,25 @@ import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import SourceSetter from '../../components/SourceSetter'; import { useCharge } from '../../state/docket'; -import { usePike } from '../../state/kiln'; +import useKilnState, { usePike } from '../../state/kiln'; import { getAppName } from '../../state/util'; -import SourceSyncer from '../../components/SourceSyncer'; export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => { const { desk } = match.params; const charge = useCharge(desk); const appName = getAppName(charge); const pike = usePike(desk); - const syncShip = pike?.sync?.ship; + const srcShip = pike?.sync?.ship; + const { toggleSync } = useKilnState(); return ( - ); }; diff --git a/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx index 6d7441c2c5..b08bd32dcd 100644 --- a/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx +++ b/pkg/grid/src/nav/preferences/SystemUpdatePrefs.tsx @@ -1,15 +1,22 @@ import _ from 'lodash'; import React from 'react'; -import SourceSyncer from '../../components/SourceSyncer'; -import { usePike } from '../../state/kiln'; +import SourceSetter from '../../components/SourceSetter'; +import useKilnState, { usePike } from '../../state/kiln'; export const SystemUpdatePrefs = () => { const desk = 'base'; const appName = 'your Urbit'; const pike = usePike(desk); - const syncShip = pike?.sync?.ship; + const srcShip = pike?.sync?.ship; + const { toggleInstall } = useKilnState(); return ( - + ); }; diff --git a/pkg/grid/src/state/kiln.ts b/pkg/grid/src/state/kiln.ts index a4ae9992f5..8d4247a73b 100644 --- a/pkg/grid/src/state/kiln.ts +++ b/pkg/grid/src/state/kiln.ts @@ -1,4 +1,13 @@ -import { scryLag, getPikes, Pikes, Pike, kilnUnsync, kilnSync } from '@urbit/api'; +import { + scryLag, + getPikes, + Pikes, + Pike, + kilnUnsync, + kilnSync, + kilnUninstall, + kilnInstall +} from '@urbit/api'; import create from 'zustand'; import produce from 'immer'; import { useCallback } from 'react'; @@ -12,6 +21,7 @@ interface KilnState { lag: boolean; fetchLag: () => Promise; fetchPikes: () => Promise; + toggleInstall: (desk: string, ship: string) => Promise; toggleSync: (desk: string, ship: string) => Promise; set: (s: KilnState) => void; initializeKiln: () => Promise; @@ -33,6 +43,13 @@ const useKilnState = create((set, get) => ({ const lag = await api.scry(scryLag); set({ lag }); }, + toggleInstall: async (desk: string, ship: string) => { + const synced = !!get().pikes[desk].sync; + await (useMockData + ? fakeRequest('') + : api.poke(synced ? kilnUninstall(desk) : kilnInstall(ship, desk))); + await get().fetchPikes(); + }, toggleSync: async (desk: string, ship: string) => { const synced = !!get().pikes[desk].sync; await (useMockData