mirror of
https://github.com/tloncorp/landscape.git
synced 2025-01-06 08:05:02 +03:00
Merge pull request #47 from urbit/ja/tile-fixes
garden: various maladies
This commit is contained in:
commit
d8e5c8583f
@ -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'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'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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user