Merge pull request #47 from urbit/ja/tile-fixes

garden: various maladies
This commit is contained in:
Hunter Miller 2023-01-11 13:49:54 -06:00 committed by GitHub
commit d8e5c8583f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 57 deletions

View File

@ -9,44 +9,33 @@ export const SecurityPrefs = () => {
const { push } = useHistory();
return (
<Dialog
open
onOpenChange={(open) => !open && push('/leap/system-preferences')}
>
<DialogContent containerClass="w-1/3" showClose={false}>
<h3 className="h4 mb-6 flex items-center">Log Out</h3>
<div className="flex flex-1 flex-col justify-center space-y-6">
<div className="flex flex-col space-y-3">
<p className="leading-5">
Logging out of Landscape will additionally log you out of any
applications installed on your urbit.
</p>
<p className="leading-5">
You&apos;ll need to log into your urbit again in order to access
its apps.
</p>
</div>
<Checkbox
defaultChecked={false}
checked={allSessions}
onCheckedChange={() => setAllSessions((prev) => !prev)}
>
Log out of all connected sessions.
</Checkbox>
<div className="flex justify-end space-x-2">
<Button
variant="secondary"
onClick={() => push('/leap/system-preferences')}
>
Cancel
</Button>
<form method="post" action="/~/logout">
{allSessions && <input type="hidden" name="all" />}
<Button>Logout</Button>
</form>
</div>
<div className="inner-section space-y-8">
<h2 className="h4">Log Out</h2>
<div className="flex flex-1 flex-col justify-center space-y-6">
<div className="flex flex-col space-y-3">
<p className="leading-5">
Logging out of Landscape will additionally log you out of any
applications installed on your urbit.
</p>
<p className="leading-5">
You&apos;ll need to log into your urbit again in order to access its
apps.
</p>
</div>
</DialogContent>
</Dialog>
<Checkbox
defaultChecked={false}
checked={allSessions}
onCheckedChange={() => setAllSessions((prev) => !prev)}
>
Log out of all connected sessions
</Checkbox>
<div className="flex justify-end space-x-2">
<form method="post" action="/~/logout">
{allSessions && <input type="hidden" name="all" />}
<Button>Log Out</Button>
</form>
</div>
</div>
</div>
);
};

View File

@ -107,7 +107,7 @@ export const SystemPreferences = (
>
<div className="system-preferences-grid bg-gray-50">
<Route exact={isMobile} path={match.url}>
<aside className="system-preferences-aside min-h-fit max-h-[calc(100vh-6.25rem)] w-full min-w-60 flex flex-col border-r-2 border-gray-50 bg-white py-4 font-semibold text-black sm:w-auto sm:py-8 sm:text-gray-600">
<aside className="system-preferences-aside min-h-fit flex max-h-[calc(100vh-6.25rem)] w-full min-w-60 flex-col border-r-2 border-gray-50 bg-white py-4 font-semibold text-black sm:w-auto sm:py-8 sm:text-gray-600">
<nav className="flex flex-col px-2 sm:px-6">
<SearchSystemPreferences subUrl={subUrl} />
<span className="pt-1 pl-2 pb-3 text-sm font-semibold text-gray-400">
@ -236,6 +236,7 @@ export const SystemPreferences = (
component={AttentionAndPrivacy}
/>
<Route path={[`${match.url}/storage`]} component={StoragePrefs} />
<Route path={`${match.url}/security`} component={SecurityPrefs} />
<Route
path={[`${match.url}/system-updates`, match.url]}
component={AboutSystem}
@ -249,7 +250,6 @@ export const SystemPreferences = (
</Link>
</section>
</Route>
<Route path={`${match.url}/security`} component={SecurityPrefs} />
</div>
</ErrorBoundary>
);

View File

@ -46,7 +46,8 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk, disabled = fa
target="_blank"
rel="noreferrer"
className={classNames(
'group absolute font-semibold w-full h-full rounded-3xl default-ring focus-visible:ring-4 overflow-hidden',
'default-ring group absolute h-full w-full overflow-hidden rounded-3xl font-semibold focus-visible:ring-4',
suspended && 'opacity-50 grayscale',
isDragging && 'opacity-0',
lightText && active && !loading ? 'text-gray-200' : 'text-gray-800',
!active && 'cursor-default'
@ -56,15 +57,21 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk, disabled = fa
onAuxClick={() => addRecentApp(desk)}
>
<div>
<div className="absolute z-10 top-4 left-4 sm:top-6 sm:left-6 flex items-center">
<div className="absolute top-4 left-4 z-10 flex items-center sm:top-6 sm:left-6">
{pike?.zest === 'held' && !disabled && (
<Bullet className="w-4 h-4 text-orange-500 dark:text-black" />
<Bullet className="h-4 w-4 text-orange-500 dark:text-black" />
)}
{!active && (
<>
{loading && <Spinner className="h-6 w-6 mr-2" />}
{loading && <Spinner className="mr-2 h-6 w-6" />}
<span className="text-gray-500">
{suspended ? 'Suspended' : loading ? 'Installing' : hung ? 'Errored' : null}
{suspended
? 'Suspended'
: loading
? 'Installing'
: hung
? 'Errored'
: null}
</span>
</>
)}
@ -74,18 +81,22 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk, disabled = fa
chad={chad}
menuColor={active ? menuColor : suspendMenuColor}
lightText={lightText}
className="absolute z-10 top-3 right-3 sm:top-5 sm:right-5 opacity-0 pointer-coarse:opacity-100 hover-none:opacity-100 focus:opacity-100 group-hover:opacity-100"
className="absolute top-3 right-3 z-10 opacity-0 focus:opacity-100 group-hover:opacity-100 pointer-coarse:opacity-100 hover-none:opacity-100 sm:top-5 sm:right-5"
/>
{title && (
<div
className="h4 absolute z-10 bottom-[8%] left-[5%] sm:bottom-7 sm:left-5 py-1 px-3 rounded-lg"
className="h4 absolute bottom-[8%] left-[5%] z-10 rounded-lg py-1 px-3 sm:bottom-7 sm:left-5"
style={{ backgroundColor }}
>
<h3 className="mix-blend-hard-light">{title}</h3>
</div>
)}
{image && !loading && (
<img className="absolute top-0 left-0 h-full w-full object-cover" src={image} alt="" />
<img
className="absolute top-0 left-0 h-full w-full object-cover"
src={image}
alt=""
/>
)}
</div>
</a>

View File

@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
import { Chad, chadIsRunning } from '@urbit/api';
import useDocketState from '../state/docket';
import { disableDefault, handleDropdownLink } from '../state/util';
import { useMedia } from '../logic/useMedia';
export interface TileMenuProps {
desk: string;
@ -32,25 +33,32 @@ const Item = React.forwardRef(({ children, ...props }, ref) => (
<DropdownMenu.Item
ref={ref}
{...props}
className="block w-full px-4 py-3 leading-none rounded mix-blend-hard-light select-none default-ring ring-gray-600"
className="default-ring block w-full select-none rounded px-4 py-3 leading-none mix-blend-hard-light ring-gray-600"
>
{children}
</DropdownMenu.Item>
)) as ItemComponent;
export const TileMenu = ({ desk, chad, menuColor, lightText, className }: TileMenuProps) => {
export const TileMenu = ({
desk,
chad,
menuColor,
lightText,
className,
}: TileMenuProps) => {
const [open, setOpen] = useState(false);
const toggleDocket = useDocketState((s) => s.toggleDocket);
const menuBg = { backgroundColor: menuColor };
const linkOnSelect = useCallback(handleDropdownLink(setOpen), []);
const active = chadIsRunning(chad);
const suspended = 'suspend' in chad;
const isMobile = useMedia('(any-pointer: coarse)');
return (
<DropdownMenu.Root open={open} onOpenChange={(isOpen) => setOpen(isOpen)}>
<DropdownMenu.Trigger
className={classNames(
'flex items-center justify-center w-8 h-8 rounded-full transition-opacity duration-75 default-ring',
'default-ring flex h-8 w-8 items-center justify-center rounded-full transition-opacity duration-75',
open && 'opacity-100',
className
)}
@ -58,7 +66,10 @@ export const TileMenu = ({ desk, chad, menuColor, lightText, className }: TileMe
// onMouseOver={() => queryClient.setQueryData(['apps', name], app)}
>
<MenuIcon
className={classNames('w-4 h-4 mix-blend-hard-light', lightText && 'text-gray-100')}
className={classNames(
'h-4 w-4 mix-blend-hard-light',
lightText && 'text-gray-100'
)}
/>
<span className="sr-only">Menu</span>
</DropdownMenu.Trigger>
@ -72,23 +83,40 @@ export const TileMenu = ({ desk, chad, menuColor, lightText, className }: TileMe
style={menuBg}
>
<DropdownMenu.Group>
<Item as={Link} to={`/app/${desk}`} onSelect={linkOnSelect}>
<Item
as={Link}
to={`/app/${desk}`}
onSelect={isMobile ? (e) => e.preventDefault() : linkOnSelect}
>
App Info
</Item>
</DropdownMenu.Group>
<DropdownMenu.Separator className="-mx-4 my-2 border-t-2 border-solid border-gray-600 mix-blend-soft-light" />
<DropdownMenu.Group>
{active && (
<Item as={Link} to={`/app/${desk}/suspend`} onSelect={linkOnSelect}>
<Item
as={Link}
to={`/app/${desk}/suspend`}
onSelect={isMobile ? (e) => e.preventDefault() : linkOnSelect}
>
Suspend App
</Item>
)}
{suspended && <Item onSelect={() => toggleDocket(desk)}>Resume App</Item>}
<Item as={Link} to={`/app/${desk}/remove`} onSelect={linkOnSelect}>
{suspended && (
<Item onSelect={() => toggleDocket(desk)}>Resume App</Item>
)}
<Item
as={Link}
to={`/app/${desk}/remove`}
onSelect={isMobile ? (e) => e.preventDefault() : linkOnSelect}
>
Uninstall App
</Item>
</DropdownMenu.Group>
<DropdownMenu.Arrow className="w-4 h-[10px] fill-current" style={{ color: menuColor }} />
<DropdownMenu.Arrow
className="h-[10px] w-4 fill-current"
style={{ color: menuColor }}
/>
</DropdownMenu.Content>
</DropdownMenu.Root>
);