Merge pull request #5239 from urbit/hm/landscape-dist-fixes

interface: dist fixes
This commit is contained in:
Liam Fitzgerald 2021-09-22 09:58:48 +10:00 committed by GitHub
commit cbae49c02a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 90 additions and 140 deletions

View File

@ -8,10 +8,18 @@ import { Toggle } from './Toggle';
type SettingsProps = {
name: string;
on: boolean;
disabled?: boolean;
toggle: (open: boolean) => Promise<void>;
} & HTMLAttributes<HTMLDivElement>;
export const Setting: FC<SettingsProps> = ({ name, on, toggle, className, children }) => {
export const Setting: FC<SettingsProps> = ({
name,
on,
disabled = false,
toggle,
className,
children
}) => {
const { status, call } = useAsyncCall(toggle);
const id = slugify(name);
@ -26,6 +34,7 @@ export const Setting: FC<SettingsProps> = ({ name, on, toggle, className, childr
pressed={on}
onPressedChange={call}
className="flex-none self-start text-blue-400"
disabled={disabled}
/>
<div className="flex-1 flex flex-col justify-center space-y-6">{children}</div>
</div>

View File

@ -43,6 +43,16 @@ const cards: OnboardingCardProps[] = [
// }
];
if (window?.navigator?.registerProtocolHandler) {
cards.push({
title: 'Open Urbit-Native Links',
body: 'Enable your Urbit to open links you find in the wild',
button: 'Enable Link Handler',
color: '#82A6CA',
href: '/apps/grid/leap/system-preferences/interface'
});
}
interface OnboardingCardProps {
title: string;
button: string;

View File

@ -33,7 +33,12 @@ export function InterfacePrefs() {
return (
<>
<h2 className="h3 mb-7">Interface Settings</h2>
<Setting on={protocolHandling} toggle={toggleProtoHandling} name="Handle Urbit links">
<Setting
on={protocolHandling}
toggle={toggleProtoHandling}
name="Handle Urbit links"
disabled={!window?.navigator?.registerProtocolHandler}
>
<p>Automatically open urbit links with this urbit</p>
</Setting>
</>

View File

@ -12,7 +12,7 @@ export const SystemUpdatePrefs = () => {
_.pick(s, ['toggleOTAs', 'changeOTASource'])
);
const base = useVat('base');
const otasEnabled = base && !(base.arak?.rail ?? true);
const otasEnabled = base && !(base.arak?.rail?.paused ?? true);
const otaSource = base && base.arak.rail!.ship!;
const toggleBase = useCallback((on: boolean) => toggleOTAs('base', on), [toggleOTAs]);

View File

@ -26,6 +26,9 @@ if(urbitrc.URL) {
devServer = {
...devServer,
index: 'index.html',
// headers: {
// 'Service-Worker-Allowed': '/'
// },
proxy: [
{
context: (path) => {

View File

@ -4,7 +4,6 @@ import {
createSubscription,
reduceStateN
} from './base';
import airlock from '~/logic/api';
import { reduce } from '../reducers/launch-update';
import _ from 'lodash';
@ -16,10 +15,6 @@ export interface LaunchState {
};
weather: WeatherState | null | Record<string, never> | boolean;
userLocation: string | null;
baseHash: string | null;
runtimeLag: boolean;
getRuntimeLag: () => Promise<void>;
getBaseHash: () => Promise<void>;
}
// @ts-ignore investigate zustand types
@ -30,23 +25,7 @@ const useLaunchState = createState<LaunchState>(
tileOrdering: [],
tiles: {},
weather: null,
userLocation: null,
baseHash: null,
runtimeLag: false,
getBaseHash: async () => {
const baseHash = await airlock.scry({
app: 'file-server',
path: '/clay/base/hash'
});
set({ baseHash });
},
getRuntimeLag: async () => {
const runtimeLag = await airlock.scry({
app: 'launch',
path: '/runtime-lag'
});
set({ runtimeLag });
}
userLocation: null
}),
['weather'],
[

View File

@ -1,7 +1,7 @@
if ('serviceWorker' in navigator && process.env.NODE_ENV !== 'development') {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/~landscape/js/bundle/serviceworker.js', {
scope: '/'
navigator.serviceWorker.register('/apps/landscape/serviceworker.js', {
scope: '/apps/landscape'
}).then((reg) => {
});
});

View File

@ -28,7 +28,6 @@ import './css/indigo-static.css';
import { Content } from './landscape/components/Content';
import './landscape/css/custom.css';
import { bootstrapApi } from '~/logic/api/bootstrap';
import useLaunchState from '../logic/state/launch';
const Root = withState(styled.div`
font-family: ${p => p.theme.fonts.sans};
@ -104,8 +103,6 @@ class App extends React.Component {
this.updateMedium(this.mediumWatcher);
this.updateLarge(this.largeWatcher);
}, 500);
this.props.getBaseHash();
this.props.getRuntimeLag(); // TODO consider polling periodically
this.props.getAll();
gcpManager.start();
Mousetrap.bindGlobal(['command+/', 'ctrl+/'], (e) => {
@ -211,14 +208,12 @@ const selContacts = s => s.contacts[`~${window.ship}`];
const selLocal = s => [s.set, s.omniboxShown, s.toggleOmnibox, s.dark];
const selSettings = s => [s.display, s.getAll];
const selGraph = s => s.getShallowChildren;
const selLaunch = s => [s.getRuntimeLag, s.getBaseHash];
const WithApp = React.forwardRef((props, ref) => {
const ourContact = useContactState(selContacts);
const [display, getAll] = useSettingsState(selSettings, shallow);
const [setLocal, omniboxShown, toggleOmnibox, dark] = useLocalState(selLocal);
const getShallowChildren = useGraphState(selGraph);
const [getRuntimeLag, getBaseHash] = useLaunchState(selLaunch, shallow);
return (
<WarmApp
@ -229,8 +224,6 @@ const WithApp = React.forwardRef((props, ref) => {
set={setLocal}
dark={dark}
getShallowChildren={getShallowChildren}
getRuntimeLag={getRuntimeLag}
getBaseHash={getBaseHash}
toggleOmnibox={toggleOmnibox}
omniboxShown={omniboxShown}
/>

View File

@ -3,23 +3,20 @@ import { Box, Button, Col, Icon, Row, Text } from '@tlon/indigo-react';
import f from 'lodash/fp';
import React, { ReactElement, useEffect, useMemo, useState } from 'react';
import { Helmet } from 'react-helmet';
import { Route, useHistory } from 'react-router-dom';
import { Route } from 'react-router-dom';
import styled from 'styled-components';
import {
hasTutorialGroup,
TUTORIAL_BOOK,
TUTORIAL_CHAT, TUTORIAL_GROUP,
TUTORIAL_HOST,
TUTORIAL_LINKS
hasTutorialGroup,
TUTORIAL_BOOK,
TUTORIAL_CHAT,
TUTORIAL_GROUP,
TUTORIAL_HOST,
TUTORIAL_LINKS
} from '~/logic/lib/tutorialModal';
import { useModal } from '~/logic/lib/useModal';
import { useQuery } from '~/logic/lib/useQuery';
import { useWaitForProps } from '~/logic/lib/useWaitForProps';
import { writeText } from '~/logic/lib/util';
import useHarkState from '~/logic/state/hark';
import useLaunchState from '~/logic/state/launch';
import useLocalState from '~/logic/state/local';
import useMetadataState from '~/logic/state/metadata';
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
@ -53,8 +50,6 @@ interface LaunchAppProps {
export const LaunchApp = (props: LaunchAppProps): ReactElement | null => {
const { connection } = props;
const { baseHash, runtimeLag } = useLaunchState(state => state);
const [hashText, setHashText] = useState(baseHash);
const [exitingTut, setExitingTut] = useState(false);
const seen = useSettingsState(s => s?.tutorial?.seen) ?? true;
const associations = useMetadataState(s => s.associations);
@ -67,35 +62,6 @@ export const LaunchApp = (props: LaunchAppProps): ReactElement | null => {
!hideGroups ? { hideGroups } = calmState : null;
const waiter = useWaitForProps({ ...props, associations });
const hashBox = (
<Box
position="sticky"
left={3}
bottom={3}
mt={3}
backgroundColor="white"
borderRadius={2}
width="fit-content"
fontSize={0}
cursor="pointer"
onClick={() => {
writeText(baseHash);
setHashText('copied');
setTimeout(() => {
setHashText(baseHash);
}, 2000);
}}
>
<Box
height="100%"
backgroundColor={runtimeLag ? 'yellow' : 'washedGray'}
p={2}
width="fit-content"
>
<Text mono bold>{hashText || baseHash}</Text>
</Box>
</Box>
);
const { query } = useQuery();
@ -247,7 +213,6 @@ export const LaunchApp = (props: LaunchAppProps): ReactElement | null => {
(<Groups />)
}
</Box>
{hashBox}
</ScrollbarLessBox>
</>
);

View File

@ -1,9 +1,7 @@
import React, { ReactElement } from 'react';
import useLaunchState from '~/logic/state/launch';
import { WeatherState } from '~/types';
import BasicTile from './tiles/basic';
import ClockTile from './tiles/clock';
import CustomTile from './tiles/custom';
import WeatherTile from './tiles/weather';
const Tiles = (): ReactElement => {
@ -16,16 +14,7 @@ const Tiles = (): ReactElement => {
return tile.isShown;
}).map((key) => {
const tile = tileState[key];
if ('basic' in tile.type) {
const basic = tile.type.basic;
return (
<BasicTile
key={key}
title={basic.title}
linkedUrl={basic.linkedUrl}
/>
);
} else if ('custom' in tile.type) {
if ('custom' in tile.type) {
if (key === 'weather') {
return (
<WeatherTile key={key} />
@ -35,14 +24,6 @@ const Tiles = (): ReactElement => {
return (
<ClockTile key={key} location={location} />
);
} else {
return (
<CustomTile
key={key}
tileImage={tile.type.custom.image}
linkedUrl={tile.type.custom.linkedUrl}
/>
);
}
}
return null;

View File

@ -1,11 +1,9 @@
import { Box, Center, Col, LoadingSpinner, Text, Icon } from '@tlon/indigo-react';
import { Col } from '@tlon/indigo-react';
import {
IndexedNotification,
JoinRequests, Notifications,
JoinRequests,
Notifications,
seen,
Timebox,
unixToDa
} from '@urbit/api';
@ -13,10 +11,8 @@ import { BigInteger } from 'big-integer';
import _ from 'lodash';
import f from 'lodash/fp';
import moment from 'moment';
import React, { useEffect, useRef } from 'react';
import React, { useEffect } from 'react';
import { getNotificationKey } from '~/logic/lib/hark';
import { useLazyScroll } from '~/logic/lib/useLazyScroll';
import useLaunchState from '~/logic/state/launch';
import { daToUnix } from '~/logic/lib/util';
import useHarkState from '~/logic/state/hark';
import { Invites } from './invites';
@ -59,8 +55,6 @@ export default function Inbox(props: {
};
}, []);
const runtimeLag = useLaunchState(state => state.runtimeLag);
const ready = useHarkState(
s => Object.keys(s.unreads.graph).length > 0
);
@ -99,14 +93,6 @@ export default function Inbox(props: {
return (
<Col p={1} position="relative" height="100%" overflowY="auto" overflowX="hidden">
{runtimeLag && (
<Box bg="yellow" borderRadius={2} p={2} m={2}>
<Icon verticalAlign="middle" mr={2} icon="Tutorial" />
<Text verticalAlign="middle">
Update your binary to continue receiving updates.
</Text>
</Box>
)}
<Invites pendingJoin={props.pendingJoin} />
</Col>
);

View File

@ -1,5 +1,5 @@
import { BaseAnchor, Box, Button, Center, Col, H3, Icon, Image, Row, Text } from '@tlon/indigo-react';
import { Association, GraphNode, resourceFromPath, GraphConfig } from '@urbit/api';
import { BaseAnchor, Box, BoxProps, Button, Center, Col, H3, Icon, Image, Row, Text } from '@tlon/indigo-react';
import { Association, GraphNode, resourceFromPath, GraphConfig, Treaty } from '@urbit/api';
import React, { useCallback, useEffect, useState } from 'react';
import _ from 'lodash';
import { Link, useLocation } from 'react-router-dom';
@ -196,8 +196,40 @@ const ClampedText = styled(Text)`
overflow: hidden;
`;
type AppTileProps = Treaty & BoxProps;
function AppTile({ color, image, ...props }: AppTileProps) {
return (
<Box
position="relative"
flex="none"
height={['48px', '132px']}
width={['48px', '132px']}
marginRight={3}
borderRadius={3}
bg={color || 'gray'}
{...props}
>
{image && (
<Image
src={image}
position="absolute"
top="0"
left="0"
width="100%"
height="100%"
/>
)}
</Box>
);
}
window.navigator.registerProtocolHandler = undefined;
function AppPermalink({ link, ship, desk }: Omit<IAppPermalink, 'type'>) {
const treaty = useTreaty(ship, desk);
const hasProtocolHandling = Boolean(window?.navigator?.registerProtocolHandler);
const href = hasProtocolHandling ? link : `/apps/grid/perma?ext=${link}`;
useEffect(() => {
if (!treaty) {
@ -208,36 +240,23 @@ function AppPermalink({ link, ship, desk }: Omit<IAppPermalink, 'type'>) {
return (
<Row
display="inline-flex"
width="500px"
width="100%"
maxWidth="500px"
padding={3}
bg="washedGray"
borderRadius={3}
>
<Box
position="relative"
flex="none"
height="132px"
width="132px"
marginRight={3}
borderRadius={3}
bg={treaty?.color || 'gray'}
>
{treaty?.image && (
<Image
src={treaty.image}
position="absolute"
top="0"
left="0"
width="100%"
height="100%"
/>
)}
</Box>
{treaty && <AppTile display={['none', 'block']} {...treaty} />}
<Col>
<H3 color="black">{treaty?.title}</H3>
{treaty?.ship && <Author ship={treaty?.ship} showImage dontShowTime={true} marginBottom={2} />}
<Row flexDirection={['row', 'column']} alignItems={['center', 'start']} marginBottom={2}>
{treaty && <AppTile display={['block', 'none']} {...treaty} />}
<Col>
<H3 color="black">{treaty?.title}</H3>
{treaty?.ship && <Author ship={treaty?.ship} showImage dontShowTime={true} />}
</Col>
</Row>
<ClampedText marginBottom={2} color="gray">{treaty?.info}</ClampedText>
<Button as="a" href={link} primary alignSelf="start" display="inline-flex" marginTop="auto">Open App</Button>
<Button as="a" href={href} primary alignSelf="start" display="inline-flex" marginTop="auto">Open App</Button>
</Col>
</Row>
);