mirror of
https://github.com/urbit/shrub.git
synced 2024-12-19 16:51:42 +03:00
grid: default to desk name if title empty
This commit is contained in:
parent
72a9d90ec1
commit
7e7d938720
@ -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 “{docket.title}”</h2>
|
<h2 className="h4">Install “{getAppName(docket)}”</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 “{docket.title}”
|
Get “{getAppName(docket)}”
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -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>
|
||||||
</>
|
</>
|
||||||
|
@ -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}
|
||||||
|
@ -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>
|
||||||
|
@ -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" />
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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 “{docket?.title || ''}”?</h1>
|
<h1 className="h4">Remove “{getAppName(docket)}”?</h1>
|
||||||
<p className="text-base tracking-tight pr-6">
|
<p className="text-base tracking-tight pr-6">
|
||||||
This will remove the software's tile from your home screen.
|
This will remove the software'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 “{docket?.title}”
|
Remove “{getAppName(docket)}”
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
@ -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 “{charge?.title || ''}”</h1>
|
<h1 className="h4">Suspend “{getAppName(charge)}”</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 “{charge?.title}”
|
Suspend “{getAppName(docket)}”
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
Loading…
Reference in New Issue
Block a user