grid: default to desk name if title empty

This commit is contained in:
Hunter Miller 2021-10-25 11:55:57 -05:00
parent 72a9d90ec1
commit 7e7d938720
9 changed files with 30 additions and 16 deletions

View File

@ -9,7 +9,7 @@ import { DocketHeader } from './DocketHeader';
import { Spinner } from './Spinner'; import { Spinner } from './Spinner';
import { VatMeta } from './VatMeta'; import { VatMeta } from './VatMeta';
import useDocketState, { ChargeWithDesk } from '../state/docket'; import useDocketState, { ChargeWithDesk } from '../state/docket';
import { getAppHref } from '../state/util'; import { getAppHref, getAppName } from '../state/util';
import { addRecentApp } from '../nav/search/Home'; import { addRecentApp } from '../nav/search/Home';
import { TreatyMeta } from './TreatyMeta'; import { TreatyMeta } from './TreatyMeta';
@ -113,7 +113,7 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
className="space-y-6" className="space-y-6"
containerClass="w-full max-w-md" containerClass="w-full max-w-md"
> >
<h2 className="h4">Install &ldquo;{docket.title}&rdquo;</h2> <h2 className="h4">Install &ldquo;{getAppName(docket)}&rdquo;</h2>
<p className="text-base tracking-tight pr-6"> <p className="text-base tracking-tight pr-6">
This application will be able to view and interact with the contents of your This application will be able to view and interact with the contents of your
Urbit. Only install if you trust the developer. Urbit. Only install if you trust the developer.
@ -123,7 +123,7 @@ export const AppInfo: FC<AppInfoProps> = ({ docket, vat, className }) => {
Cancel Cancel
</DialogClose> </DialogClose>
<DialogClose as={Button} onClick={installApp}> <DialogClose as={Button} onClick={installApp}>
Get &ldquo;{docket.title}&rdquo; Get &ldquo;{getAppName(docket)}&rdquo;
</DialogClose> </DialogClose>
</div> </div>
</DialogContent> </DialogContent>

View File

@ -2,7 +2,7 @@ import classNames from 'classnames';
import React, { HTMLProps, ReactNode } from 'react'; import React, { HTMLProps, ReactNode } from 'react';
import { Link, LinkProps } from 'react-router-dom'; import { Link, LinkProps } from 'react-router-dom';
import { DocketWithDesk } from '../state/docket'; import { DocketWithDesk } from '../state/docket';
import { getAppHref } from '../state/util'; import { getAppHref, getAppName } from '../state/util';
import { DocketImage } from './DocketImage'; import { DocketImage } from './DocketImage';
type Sizes = 'xs' | 'small' | 'default'; type Sizes = 'xs' | 'small' | 'default';
@ -57,7 +57,7 @@ export const AppLink = <T extends DocketWithDesk>({
<> <>
<DocketImage color={app.color} image={app.image} size={size} /> <DocketImage color={app.color} image={app.image} size={size} />
<div className="flex-1 text-black"> <div className="flex-1 text-black">
<p>{app.title}</p> <p>{getAppName(app)}</p>
{app.info && size === 'default' && <p className="font-normal">{app.info}</p>} {app.info && size === 'default' && <p className="font-normal">{app.info}</p>}
</div> </div>
</> </>

View File

@ -4,6 +4,7 @@ import { MatchItem } from '../nav/Nav';
import { useRecentsStore } from '../nav/search/Home'; import { useRecentsStore } from '../nav/search/Home';
import { AppLink, AppLinkProps } from './AppLink'; import { AppLink, AppLinkProps } from './AppLink';
import { DocketWithDesk } from '../state/docket'; import { DocketWithDesk } from '../state/docket';
import { getAppName } from '../state/util';
type AppListProps<T extends DocketWithDesk> = { type AppListProps<T extends DocketWithDesk> = {
apps: T[]; apps: T[];
@ -45,7 +46,7 @@ export const AppList = <T extends DocketWithDesk>({
aria-labelledby={labelledBy} aria-labelledby={labelledBy}
> >
{apps.map((app) => ( {apps.map((app) => (
<li key={app.title} id={app.title} role="option" aria-selected={selected(app)}> <li key={getAppName(app)} id={getAppName(app)} role="option" aria-selected={selected(app)}>
<AppLink <AppLink
{...props} {...props}
app={app} app={app}

View File

@ -14,6 +14,7 @@ import { LeftArrow } from '../components/icons/LeftArrow';
import { System } from '../components/icons/System'; import { System } from '../components/icons/System';
import { Interface } from '../components/icons/Interface'; import { Interface } from '../components/icons/Interface';
import { Notifications } from '../components/icons/Notifications'; import { Notifications } from '../components/icons/Notifications';
import { getAppName } from '../state/util';
interface SystemPreferencesSectionProps { interface SystemPreferencesSectionProps {
url: string; url: string;
@ -112,7 +113,7 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
active={matchSub('apps', charge.desk)} active={matchSub('apps', charge.desk)}
> >
<DocketImage size="small" className="mr-3" {...charge} /> <DocketImage size="small" className="mr-3" {...charge} />
{charge.title} {getAppName(charge)}
</SystemPreferencesSection> </SystemPreferencesSection>
))} ))}
</ul> </ul>

View File

@ -4,6 +4,7 @@ import { Setting } from '../../components/Setting';
import { ShipName } from '../../components/ShipName'; import { ShipName } from '../../components/ShipName';
import { useCharge } from '../../state/docket'; import { useCharge } from '../../state/docket';
import useKilnState, { useVat } from '../../state/kiln'; import useKilnState, { useVat } from '../../state/kiln';
import { getAppName } from '../../state/util';
export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => { export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => {
const { desk } = match.params; const { desk } = match.params;
@ -18,11 +19,11 @@ export const AppPrefs = ({ match }: RouteComponentProps<{ desk: string }>) => {
return ( return (
<> <>
<h2 className="h3 mb-7">{charge?.title} Settings</h2> <h2 className="h3 mb-7">{getAppName(charge)} Settings</h2>
<div className="space-y-3"> <div className="space-y-3">
{tracking ? ( {tracking ? (
<Setting on={otasEnabled} toggle={toggleUpdates} name="Automatic Updates"> <Setting on={otasEnabled} toggle={toggleUpdates} name="Automatic Updates">
<p>Automatically download and apply updates to keep {charge?.title} up to date.</p> <p>Automatically download and apply updates to keep {getAppName(charge)} up to date.</p>
{otaSource && ( {otaSource && (
<p> <p>
OTA Source: <ShipName name={otaSource} className="font-semibold font-mono" /> OTA Source: <ShipName name={otaSource} className="font-semibold font-mono" />

View File

@ -4,6 +4,7 @@ import { AppInfo } from '../../components/AppInfo';
import { Spinner } from '../../components/Spinner'; import { Spinner } from '../../components/Spinner';
import useDocketState, { useCharge, useTreaty } from '../../state/docket'; import useDocketState, { useCharge, useTreaty } from '../../state/docket';
import { useVat } from '../../state/kiln'; import { useVat } from '../../state/kiln';
import { getAppName } from '../../state/util';
import { useLeapStore } from '../Nav'; import { useLeapStore } from '../Nav';
export const TreatyInfo = () => { export const TreatyInfo = () => {
@ -12,6 +13,7 @@ export const TreatyInfo = () => {
const treaty = useTreaty(host, desk); const treaty = useTreaty(host, desk);
const vat = useVat(desk); const vat = useVat(desk);
const charge = useCharge(desk); const charge = useCharge(desk);
const name = getAppName(treaty);
useEffect(() => { useEffect(() => {
if (!charge) { if (!charge) {
@ -20,9 +22,9 @@ export const TreatyInfo = () => {
}, [host, desk]); }, [host, desk]);
useEffect(() => { useEffect(() => {
select(<>{treaty?.title}</>); select(<>{name}</>);
useLeapStore.setState({ matches: [] }); useLeapStore.setState({ matches: [] });
}, [treaty?.title]); }, [name]);
if (!treaty) { if (!treaty) {
// TODO: maybe replace spinner with skeletons // TODO: maybe replace spinner with skeletons

View File

@ -1,4 +1,4 @@
import { DocketHref } from '@urbit/api/docket'; import { Docket, DocketHref, Treaty } from '@urbit/api/docket';
import { hsla, parseToHsla } from 'color2k'; import { hsla, parseToHsla } from 'color2k';
import _ from 'lodash'; import _ from 'lodash';
@ -16,6 +16,14 @@ export function getAppHref(href: DocketHref) {
return 'site' in href ? href.site : `/apps/${href.glob.base}/`; return 'site' in href ? href.site : `/apps/${href.glob.base}/`;
} }
export function getAppName(app: (Docket & { desk: string }) | Treaty | undefined): string {
if (!app) {
return '';
}
return app.title || app.desk;
}
export function disableDefault<T extends Event>(e: T): void { export function disableDefault<T extends Event>(e: T): void {
e.preventDefault(); e.preventDefault();
} }

View File

@ -4,6 +4,7 @@ import { Button } from '../components/Button';
import { Dialog, DialogClose, DialogContent } from '../components/Dialog'; import { Dialog, DialogClose, DialogContent } from '../components/Dialog';
import { useRecentsStore } from '../nav/search/Home'; import { useRecentsStore } from '../nav/search/Home';
import useDocketState, { useCharges } from '../state/docket'; import useDocketState, { useCharges } from '../state/docket';
import { getAppName } from '../state/util';
export const RemoveApp = () => { export const RemoveApp = () => {
const history = useHistory(); const history = useHistory();
@ -21,7 +22,7 @@ export const RemoveApp = () => {
return ( return (
<Dialog open onOpenChange={(open) => !open && history.push('/')}> <Dialog open onOpenChange={(open) => !open && history.push('/')}>
<DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md"> <DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md">
<h1 className="h4">Remove &ldquo;{docket?.title || ''}&rdquo;?</h1> <h1 className="h4">Remove &ldquo;{getAppName(docket)}&rdquo;?</h1>
<p className="text-base tracking-tight pr-6"> <p className="text-base tracking-tight pr-6">
This will remove the software&apos;s tile from your home screen. This will remove the software&apos;s tile from your home screen.
</p> </p>
@ -30,7 +31,7 @@ export const RemoveApp = () => {
Cancel Cancel
</DialogClose> </DialogClose>
<DialogClose as={Button} onClick={handleRemoveApp}> <DialogClose as={Button} onClick={handleRemoveApp}>
Remove &ldquo;{docket?.title}&rdquo; Remove &ldquo;{getAppName(docket)}&rdquo;
</DialogClose> </DialogClose>
</div> </div>
</DialogContent> </DialogContent>

View File

@ -24,7 +24,7 @@ export const SuspendApp = () => {
return ( return (
<Dialog open onOpenChange={(open) => !open && history.push('/')}> <Dialog open onOpenChange={(open) => !open && history.push('/')}>
<DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md"> <DialogContent showClose={false} className="space-y-6" containerClass="w-full max-w-md">
<h1 className="h4">Suspend &ldquo;{charge?.title || ''}&rdquo;</h1> <h1 className="h4">Suspend &ldquo;{getAppName(charge)}&rdquo;</h1>
<p className="text-base tracking-tight pr-6"> <p className="text-base tracking-tight pr-6">
Suspending an app will turn off automatic updates. You cannot use an app when it is Suspending an app will turn off automatic updates. You cannot use an app when it is
suspended, but you can resume it at any time. suspended, but you can resume it at any time.
@ -34,7 +34,7 @@ export const SuspendApp = () => {
Cancel Cancel
</DialogClose> </DialogClose>
<DialogClose as={Button} onClick={handleSuspendApp}> <DialogClose as={Button} onClick={handleSuspendApp}>
Suspend &ldquo;{charge?.title}&rdquo; Suspend &ldquo;{getAppName(docket)}&rdquo;
</DialogClose> </DialogClose>
</div> </div>
</DialogContent> </DialogContent>