mirror of
https://github.com/urbit/shrub.git
synced 2024-12-25 21:12:56 +03:00
Merge pull request #5239 from urbit/hm/landscape-dist-fixes
interface: dist fixes
This commit is contained in:
commit
cbae49c02a
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
</>
|
||||
|
@ -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]);
|
||||
|
@ -26,6 +26,9 @@ if(urbitrc.URL) {
|
||||
devServer = {
|
||||
...devServer,
|
||||
index: 'index.html',
|
||||
// headers: {
|
||||
// 'Service-Worker-Allowed': '/'
|
||||
// },
|
||||
proxy: [
|
||||
{
|
||||
context: (path) => {
|
||||
|
@ -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'],
|
||||
[
|
||||
|
@ -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) => {
|
||||
});
|
||||
});
|
||||
|
@ -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}
|
||||
/>
|
||||
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user