interface/views: ts lint

This commit is contained in:
Matilde Park 2021-05-13 18:39:54 -04:00
parent 0ec0aa4f82
commit ec632c7b17
46 changed files with 142 additions and 90 deletions

View File

@ -226,7 +226,9 @@ export class ChatInput extends Component<ChatInputProps, ChatInputState> {
} }
} }
// @ts-ignore withLocalState prop passing weirdness
export default withLocalState<Omit<ChatInputProps, keyof IuseStorage>, 'hideAvatars', ChatInput>( export default withLocalState<Omit<ChatInputProps, keyof IuseStorage>, 'hideAvatars', ChatInput>(
// @ts-ignore withLocalState prop passing weirdness
withStorage<ChatInputProps, ChatInput>(ChatInput, { accept: 'image/*' }), withStorage<ChatInputProps, ChatInput>(ChatInput, { accept: 'image/*' }),
['hideAvatars'] ['hideAvatars']
); );

View File

@ -251,8 +251,7 @@ function ChatMessage(props: ChatMessageProps) {
let onDelete = props?.onDelete ?? (() => {}); let onDelete = props?.onDelete ?? (() => {});
const transcluded = props?.transcluded ?? 0; const transcluded = props?.transcluded ?? 0;
const renderSigil = props.renderSigil ?? (Boolean(nextMsg && msg.author !== nextMsg.author) || const renderSigil = props.renderSigil ?? (Boolean(nextMsg && msg.author !== nextMsg.author) ||
!nextMsg || !nextMsg
msg.number === 1
); );
const ourMention = msg?.contents?.some((e: MentionContent) => { const ourMention = msg?.contents?.some((e: MentionContent) => {

View File

@ -136,6 +136,7 @@ export function ChatPane(props: ChatPaneProps): ReactElement {
} }
return ( return (
// @ts-ignore
<Col {...bind} height="100%" overflow="hidden" position="relative"> <Col {...bind} height="100%" overflow="hidden" position="relative">
<ShareProfile <ShareProfile
our={ourContact} our={ourContact}

View File

@ -239,6 +239,7 @@ class ChatWindow extends Component<
}; };
return ( return (
// @ts-ignore
<ChatMessage <ChatMessage
key={index.toString()} key={index.toString()}
ref={ref} ref={ref}
@ -281,6 +282,7 @@ class ChatWindow extends Component<
origin='bottom' origin='bottom'
style={virtScrollerStyle} style={virtScrollerStyle}
onBottomLoaded={this.onBottomLoaded} onBottomLoaded={this.onBottomLoaded}
// @ts-ignore paging @liam-fitzgerald on virtualscroller props
onScroll={this.onScroll} onScroll={this.onScroll}
data={graph} data={graph}
size={graph.size} size={graph.size}

View File

@ -64,7 +64,6 @@ export default function Groups(props: GroupsProps & Parameters<typeof Box>[0]) {
unreads={unreadCount} unreads={unreadCount}
path={group?.group} path={group?.group}
title={group.metadata.title} title={group.metadata.title}
picture={group.metadata.picture}
/> />
); );
})} })}
@ -96,7 +95,7 @@ function Group(props: GroupProps) {
.diff(moment())) .diff(moment()))
.as('days'))) || 0; .as('days'))) || 0;
return ( return (
<Tile ref={anchorRef} position="relative" bg={isTutorialGroup ? 'lightBlue' : undefined} to={`/~landscape${path}`} gridColumnStart={first ? '1' : null}> <Tile ref={anchorRef} position="relative" bg={isTutorialGroup ? 'lightBlue' : undefined} to={`/~landscape${path}`} gridColumnStart={first ? 1 : null}>
<Col height="100%" justifyContent="space-between"> <Col height="100%" justifyContent="space-between">
<Text>{title}</Text> <Text>{title}</Text>
{!hideUnreads && (<Col> {!hideUnreads && (<Col>

View File

@ -35,6 +35,7 @@ const Tiles = (props: TileProps): ReactElement => {
return ( return (
<WeatherTile <WeatherTile
key={key} key={key}
// @ts-ignore withState not passing props
api={props.api} api={props.api}
/> />
); );

View File

@ -135,7 +135,7 @@ class WeatherTile extends React.Component<WeatherTileProps, WeatherTileState> {
{locationName ? ` Current location is near ${locationName}.` : ''} {locationName ? ` Current location is near ${locationName}.` : ''}
</Text> </Text>
{error} {error}
<Box mt='auto' display='flex' marginBlockEnd={0}> <Box mt='auto' display='flex' style={{ marginBlockEnd: '0' }}>
<BaseInput <BaseInput
id="location" id="location"
size={10} size={10}

View File

@ -1,4 +1,5 @@
import { Box, Center, Col, LoadingSpinner, Text } from '@tlon/indigo-react'; import { Box, Center, Col, LoadingSpinner, Text } from '@tlon/indigo-react';
import { Group } from '@urbit/api';
import { Association } from '@urbit/api/metadata'; import { Association } from '@urbit/api/metadata';
import bigInt from 'big-integer'; import bigInt from 'big-integer';
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
@ -35,7 +36,7 @@ export function LinkResource(props: LinkResourceProps) {
const [, , ship, name] = rid.split('/'); const [, , ship, name] = rid.split('/');
const resourcePath = `${ship.slice(1)}/${name}`; const resourcePath = `${ship.slice(1)}/${name}`;
const resource = associations.graph[rid] const resource: any = associations.graph[rid]
? associations.graph[rid] ? associations.graph[rid]
: { metadata: {} }; : { metadata: {} };
const groups = useGroupState(state => state.groups); const groups = useGroupState(state => state.groups);
@ -62,13 +63,14 @@ export function LinkResource(props: LinkResourceProps) {
path={relativePath('')} path={relativePath('')}
render={(props) => { render={(props) => {
return ( return (
// @ts-ignore
<LinkWindow <LinkWindow
key={rid} key={rid}
association={resource} association={resource}
resource={resourcePath} resource={resourcePath}
graph={graph} graph={graph}
baseUrl={resourceUrl} baseUrl={resourceUrl}
group={group} group={group as Group}
path={resource.group} path={resource.group}
pendingSize={Object.keys(graphTimesentMap[resourcePath] || {}).length} pendingSize={Object.keys(graphTimesentMap[resourcePath] || {}).length}
api={api} api={api}
@ -110,7 +112,7 @@ export function LinkResource(props: LinkResourceProps) {
node={node} node={node}
baseUrl={resourceUrl} baseUrl={resourceUrl}
association={association} association={association}
group={group} group={group as Group}
path={resource?.group} path={resource?.group}
api={api} api={api}
mt={3} mt={3}
@ -126,7 +128,7 @@ export function LinkResource(props: LinkResourceProps) {
editCommentId={editCommentId} editCommentId={editCommentId}
history={props.history} history={props.history}
baseUrl={`${resourceUrl}/index/${props.match.params.index}`} baseUrl={`${resourceUrl}/index/${props.match.params.index}`}
group={group} group={group as Group}
px={3} px={3}
/> />
</Col> </Col>

View File

@ -21,6 +21,7 @@ interface LinkWindowProps {
path: string; path: string;
api: GlobalApi; api: GlobalApi;
pendingSize: number; pendingSize: number;
mb?: number;
} }
const style = { const style = {
@ -48,6 +49,7 @@ class LinkWindow extends Component<LinkWindowProps, {}> {
const { props } = this; const { props } = this;
const { association, graph, api } = props; const { association, graph, api } = props;
const [, , ship, name] = association.resource.split('/'); const [, , ship, name] = association.resource.split('/');
// @ts-ignore Uint8Array vs. BigInt mismatch?
const node = graph.get(index); const node = graph.get(index);
const first = graph.peekLargest()?.[0]; const first = graph.peekLargest()?.[0];
const post = node?.post; const post = node?.post;
@ -58,6 +60,7 @@ class LinkWindow extends Component<LinkWindowProps, {}> {
...props, ...props,
node node
}; };
{/* @ts-ignore calling @liam-fitzgerald on Uint8Array props */}
if (this.canWrite() && index.eq(first ?? bigInt.zero)) { if (this.canWrite() && index.eq(first ?? bigInt.zero)) {
return ( return (
<React.Fragment key={index.toString()}> <React.Fragment key={index.toString()}>
@ -125,6 +128,7 @@ class LinkWindow extends Component<LinkWindowProps, {}> {
return ( return (
<Col width="100%" height="100%" position="relative"> <Col width="100%" height="100%" position="relative">
{/* @ts-ignore calling @liam-fitzgerald on virtualscroller */}
<VirtualScroller <VirtualScroller
origin="top" origin="top"
offset={0} offset={0}

View File

@ -20,6 +20,8 @@ interface LinkItemProps {
group: Group; group: Group;
path: string; path: string;
baseUrl: string; baseUrl: string;
mt?: number;
measure?: any;
} }
export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject<HTMLDivElement>): ReactElement => { export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject<HTMLDivElement>): ReactElement => {
const { const {
@ -49,6 +51,7 @@ export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject<H
setTimeout(() => { setTimeout(() => {
console.log(remoteRef.current); console.log(remoteRef.current);
if(document.activeElement instanceof HTMLIFrameElement if(document.activeElement instanceof HTMLIFrameElement
// @ts-ignore forwardref prop passing
&& remoteRef?.current?.containerRef?.contains(document.activeElement)) { && remoteRef?.current?.containerRef?.contains(document.activeElement)) {
markRead(); markRead();
} }
@ -100,6 +103,7 @@ export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject<H
const appPath = `/ship/~${resource}`; const appPath = `/ship/~${resource}`;
const unreads = useHarkState(state => state.unreads); const unreads = useHarkState(state => state.unreads);
const commColor = (unreads.graph?.[appPath]?.[`/${index}`]?.unreads ?? 0) > 0 ? 'blue' : 'gray'; const commColor = (unreads.graph?.[appPath]?.[`/${index}`]?.unreads ?? 0) > 0 ? 'blue' : 'gray';
// @ts-ignore hark will have to choose between sets and numbers
const isUnread = unreads.graph?.[appPath]?.['/']?.unreads?.has(node.post.index); const isUnread = unreads.graph?.[appPath]?.['/']?.unreads?.has(node.post.index);
return ( return (
@ -135,8 +139,10 @@ export const LinkItem = React.forwardRef((props: LinkItemProps, ref: RefObject<H
<> <>
<RemoteContent <RemoteContent
ref={(r) => { ref={(r) => {
// @ts-ignore RemoteContent weirdness
remoteRef.current = r; remoteRef.current = r;
}} }}
// @ts-ignore RemoteContent weirdness
renderUrl={false} renderUrl={false}
url={href} url={href}
text={contents[0].text} text={contents[0].text}

View File

@ -12,6 +12,7 @@ interface LinkSubmitProps {
api: GlobalApi; api: GlobalApi;
name: string; name: string;
ship: string; ship: string;
parentIndex?: any;
} }
const LinkSubmit = (props: LinkSubmitProps) => { const LinkSubmit = (props: LinkSubmitProps) => {
@ -157,6 +158,7 @@ const LinkSubmit = (props: LinkSubmitProps) => {
return ( return (
<> <>
{/* @ts-ignore archaic event type mismatch */}
<Box <Box
flexShrink={0} flexShrink={0}
position='relative' position='relative'
@ -194,6 +196,7 @@ const LinkSubmit = (props: LinkSubmitProps) => {
onBlur={() => [setUrlFocused(false), setSubmitFocused(false)]} onBlur={() => [setUrlFocused(false), setSubmitFocused(false)]}
onFocus={() => [setUrlFocused(true), setSubmitFocused(true)]} onFocus={() => [setUrlFocused(true), setSubmitFocused(true)]}
spellCheck="false" spellCheck="false"
// @ts-ignore archaic event type mismatch error
onPaste={onPaste} onPaste={onPaste}
onKeyPress={onKeyPress} onKeyPress={onKeyPress}
value={linkValue} value={linkValue}

View File

@ -49,7 +49,7 @@ function TranscludedLinkNode(props: {
<Author <Author
pt='12px' pt='12px'
pl='12px' pl='12px'
size='24' size={24}
sigilPadding='6' sigilPadding='6'
showImage showImage
ship={node.post.author} ship={node.post.author}
@ -121,7 +121,7 @@ function TranscludedComment(props: {
<Author <Author
pt='12px' pt='12px'
pl='12px' pl='12px'
size='24' size={24}
sigilPadding='6' sigilPadding='6'
showImage showImage
ship={comment.post.author} ship={comment.post.author}
@ -175,7 +175,7 @@ function TranscludedPublishNode(props: {
<Author <Author
pl='12px' pl='12px'
pt='12px' pt='12px'
size='24' size={24}
sigilPadding='6' sigilPadding='6'
showImage showImage
ship={post.post.author} ship={post.post.author}
@ -235,7 +235,7 @@ export function TranscludedPost(props: {
<Author <Author
pt='12px' pt='12px'
pl='12px' pl='12px'
size='24' size={24}
sigilPadding='6' sigilPadding='6'
showImage showImage
ship={post.author} ship={post.author}
@ -273,7 +273,7 @@ export function TranscludedNode(props: {
if ( if (
typeof node?.post === "string" && typeof node?.post === "string" &&
assoc.metadata.config.graph === "chat" (assoc.metadata.config as GraphConfig).graph === "chat"
) { ) {
return ( return (
<Box <Box
@ -296,6 +296,7 @@ export function TranscludedNode(props: {
renderSigil renderSigil
transcluded={transcluded + 1} transcluded={transcluded + 1}
className="items-top cf hide-child" className="items-top cf hide-child"
// @ts-ignore isn't forwarding props to memo
association={assoc} association={assoc}
msg={node.post} msg={node.post}
fontSize={0} fontSize={0}

View File

@ -1,20 +1,12 @@
import { import { BaseAnchor, Box, Center, Col, Icon, Row, Text } from "@tlon/indigo-react";
BaseAnchor, Box, import { Association, GraphNode, resourceFromPath, GraphConfig } from '@urbit/api';
Center, Col, Icon, Row, Text
} from "@tlon/indigo-react";
import { Association, GraphNode, resourceFromPath } from '@urbit/api';
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import GlobalApi from '~/logic/api/global'; import GlobalApi from '~/logic/api/global';
import { import {
getPermalinkForGraph, GraphPermalink as IGraphPermalink, parsePermalink getPermalinkForGraph, GraphPermalink as IGraphPermalink, parsePermalink
} from '~/logic/lib/permalinks'; } from '~/logic/lib/permalinks';
import { getModuleIcon } from "~/logic/lib/util"; import { getModuleIcon, GraphModule } from "~/logic/lib/util";
import { useVirtualResizeProp } from "~/logic/lib/virtualContext"; import { useVirtualResizeProp } from "~/logic/lib/virtualContext";
import useGraphState from "~/logic/state/graph"; import useGraphState from "~/logic/state/graph";
import useMetadataState from "~/logic/state/metadata"; import useMetadataState from "~/logic/state/metadata";
@ -129,7 +121,7 @@ function GraphPermalink(
<PermalinkDetails <PermalinkDetails
known known
showTransclusion={showTransclusion} showTransclusion={showTransclusion}
icon={getModuleIcon(association.metadata.config.graph)} icon={getModuleIcon((association.metadata.config as GraphConfig).graph as GraphModule)}
title={association.metadata.title} title={association.metadata.title}
permalink={permalink} permalink={permalink}
/> />
@ -197,6 +189,7 @@ export function PermalinkEmbed(props: {
transcluded: number; transcluded: number;
showOurContact?: boolean; showOurContact?: boolean;
full?: boolean; full?: boolean;
pending?: any;
}) { }) {
const permalink = parsePermalink(props.link); const permalink = parsePermalink(props.link);

View File

@ -39,7 +39,7 @@ export function SetStatus(props: any) {
ref={inputRef} ref={inputRef}
onChange={onStatusChange} onChange={onStatusChange}
value={_status} value={_status}
autocomplete='off' autoComplete='off'
width='75%' width='75%'
mr={2} mr={2}
onKeyPress={(evt) => { onKeyPress={(evt) => {

View File

@ -10,10 +10,13 @@ type PublishResourceProps = StoreState & {
association: Association; association: Association;
api: GlobalApi; api: GlobalApi;
baseUrl: string; baseUrl: string;
history?: any;
match?: any;
location?: any;
}; };
export function PublishResource(props: PublishResourceProps) { export function PublishResource(props: PublishResourceProps) {
const { association, api, baseUrl, notebooks } = props; const { association, api, baseUrl } = props;
const rid = association.resource; const rid = association.resource;
const [, , ship, book] = rid.split('/'); const [, , ship, book] = rid.split('/');
const location = useLocation(); const location = useLocation();

View File

@ -69,6 +69,7 @@ export function NotePreview(props: NotePreviewProps) {
const [rev, title, body, content] = getLatestRevision(node); const [rev, title, body, content] = getLatestRevision(node);
const appPath = `/ship/${props.host}/${props.book}`; const appPath = `/ship/${props.host}/${props.book}`;
const unreads = useHarkState(state => state.unreads); const unreads = useHarkState(state => state.unreads);
// @ts-ignore hark will have to choose between sets and numbers
const isUnread = unreads.graph?.[appPath]?.['/']?.unreads?.has(`/${noteId}/1/1`); const isUnread = unreads.graph?.[appPath]?.['/']?.unreads?.has(`/${noteId}/1/1`);
const snippet = getSnippet(body); const snippet = getSnippet(body);

View File

@ -1,5 +1,5 @@
import { Box, Col, Row, Text } from '@tlon/indigo-react'; import { Box, Col, Row, Text } from '@tlon/indigo-react';
import { Association, Graph, Unreads } from '@urbit/api'; import { Association, Graph } from '@urbit/api';
import React, { ReactElement } from 'react'; import React, { ReactElement } from 'react';
import { RouteComponentProps } from 'react-router-dom'; import { RouteComponentProps } from 'react-router-dom';
import { useShowNickname } from '~/logic/lib/util'; import { useShowNickname } from '~/logic/lib/util';
@ -14,7 +14,6 @@ interface NotebookProps {
association: Association; association: Association;
baseUrl: string; baseUrl: string;
rootUrl: string; rootUrl: string;
unreads: Unreads;
} }
export function Notebook(props: NotebookProps & RouteComponentProps): ReactElement | null { export function Notebook(props: NotebookProps & RouteComponentProps): ReactElement | null {

View File

@ -15,7 +15,6 @@ interface NotebookPostsProps {
} }
export function NotebookPosts(props: NotebookPostsProps) { export function NotebookPosts(props: NotebookPostsProps) {
const contacts = useContactState(state => state.contacts);
return ( return (
<Col> <Col>
{Array.from(props.graph || []).map( {Array.from(props.graph || []).map(
@ -25,7 +24,6 @@ export function NotebookPosts(props: NotebookPostsProps) {
key={date.toString()} key={date.toString()}
host={props.host} host={props.host}
book={props.book} book={props.book}
contact={contacts[`~${node.post.author}`]}
node={node} node={node}
baseUrl={props.baseUrl} baseUrl={props.baseUrl}
group={props.group} group={props.group}

View File

@ -57,7 +57,9 @@ const StoreDebugger = (props: StoreDebuggerProps) => {
placeholder="Drill Down" placeholder="Drill Down"
width="100%" width="100%"
onKeyUp={(event) => { onKeyUp={(event) => {
// @ts-ignore clearly value is in eventtarget
if (event.target.value) { if (event.target.value) {
// @ts-ignore clearly value is in eventtarget
tryFilter(event.target.value); tryFilter(event.target.value);
} else { } else {
setFilter(''); setFilter('');

View File

@ -98,7 +98,9 @@ export default function DisplayForm(props: DisplayFormProps) {
Customize visual interfaces across your Landscape Customize visual interfaces across your Landscape
</Text> </Text>
</Col> </Col>
<BackgroundPicker api={api} <BackgroundPicker
api={api}
bgType={bgType}
/> />
<Label>Theme</Label> <Label>Theme</Label>
<Radio name="theme" id="light" label="Light" /> <Radio name="theme" id="light" label="Light" />

View File

@ -78,6 +78,7 @@ class TermApp extends Component {
border={['0','1']} border={['0','1']}
cursor='text' cursor='text'
> >
{/* @ts-ignore declare props in later pass */}
<History log={this.state.lines.slice(0, -1)} /> <History log={this.state.lines.slice(0, -1)} />
<Input <Input
ship={this.props.ship} ship={this.props.ship}

View File

@ -21,7 +21,9 @@ export class History extends Component {
<Box <Box
mt='auto' mt='auto'
> >
{/* @ts-ignore declare props in later pass */}
{this.props.log.map((line, i) => { {this.props.log.map((line, i) => {
// @ts-ignore react memo not passing props
return <Line key={i} line={line} />; return <Line key={i} line={line} />;
})} })}
</Box> </Box>

View File

@ -15,10 +15,11 @@ export class Input extends Component {
componentDidUpdate() { componentDidUpdate() {
if ( if (
!document.activeElement == document.body document.activeElement == this.inputRef.current
|| document.activeElement == this.inputRef.current
) { ) {
// @ts-ignore ref type issues
this.inputRef.current.focus(); this.inputRef.current.focus();
// @ts-ignore ref type issues
this.inputRef.current.setSelectionRange(this.props.cursor, this.props.cursor); this.inputRef.current.setSelectionRange(this.props.cursor, this.props.cursor);
} }
} }
@ -26,7 +27,7 @@ export class Input extends Component {
keyPress(e) { keyPress(e) {
const key = e.key; const key = e.key;
// let paste and leap events pass // let paste and leap events pass
if ((e.getModifierState('Control') || event.getModifierState('Meta')) if ((e.getModifierState('Control') || e.getModifierState('Meta'))
&& (e.key === 'v' || e.key === '/')) { && (e.key === 'v' || e.key === '/')) {
return; return;
} }
@ -115,6 +116,7 @@ belt = { met: 'bac' };
onKeyDown={this.keyPress} onKeyDown={this.keyPress}
onClick={this.click} onClick={this.click}
onPaste={this.paste} onPaste={this.paste}
// @ts-ignore indigo-react doesn't let us pass refs
ref={this.inputRef} ref={this.inputRef}
defaultValue="connecting..." defaultValue="connecting..."
value={prompt} value={prompt}

View File

@ -1,6 +1,6 @@
import { Text } from '@tlon/indigo-react'; import { Text } from '@tlon/indigo-react';
import React from 'react'; import React from 'react';
// @ts-ignore line isn't in props?
export default React.memo(({ line }) => { export default React.memo(({ line }) => {
// line body to jsx // line body to jsx
// NOTE lines are lists of characters that might span multiple codepoints // NOTE lines are lists of characters that might span multiple codepoints

View File

@ -46,7 +46,7 @@ export function CommentItem(props: CommentItemProps) {
const children = Array.from(revs.children); const children = Array.from(revs.children);
const indices = []; const indices = [];
for (const child in children) { for (const child in children) {
const node = children[child]; const node = children[child] as any;
if (!node?.post || typeof node.post !== 'string') { if (!node?.post || typeof node.post !== 'string') {
indices.push(node.post?.index); indices.push(node.post?.index);
} }

View File

@ -129,6 +129,7 @@ export function DropdownSearch<C>(props: DropdownSearchProps<C>): ReactElement {
return ( return (
<Box {...rest} position="relative" zIndex={9}> <Box {...rest} position="relative" zIndex={9}>
{ /* @ts-ignore investigate onblur on styled-system component later */}
<Input <Input
ref={textarea} ref={textarea}
onChange={changeCallback} onChange={changeCallback}

View File

@ -6,6 +6,7 @@ import {
ErrorLabel, Icon, Label, ErrorLabel, Icon, Label,
Row, Text Row, Text
} from '@tlon/indigo-react'; } from '@tlon/indigo-react';
import { OpenPolicy } from '@urbit/api';
import { Association } from '@urbit/api/metadata'; import { Association } from '@urbit/api/metadata';
import { FieldArray, useFormikContext } from 'formik'; import { FieldArray, useFormikContext } from 'formik';
import _ from 'lodash'; import _ from 'lodash';
@ -100,7 +101,7 @@ export function GroupSearch<I extends string, V extends FormValues<I>>(props: Gr
return Object.values( return Object.values(
Object.keys(associations.groups) Object.keys(associations.groups)
.filter( .filter(
e => groupState?.[e]?.policy?.open e => (groupState?.[e]?.policy as OpenPolicy)?.open
) )
.reduce((obj, key) => { .reduce((obj, key) => {
obj[key] = associations.groups[key]; obj[key] = associations.groups[key];

View File

@ -13,7 +13,7 @@ import useStorage from '~/logic/lib/useStorage';
type ImageInputProps = Parameters<typeof Box>[0] & { type ImageInputProps = Parameters<typeof Box>[0] & {
id: string; id: string;
label: string; label?: string;
placeholder?: string; placeholder?: string;
}; };

View File

@ -10,7 +10,7 @@ import {
Metadata, MetadataUpdatePreview, Metadata, MetadataUpdatePreview,
resourceFromPath resourceFromPath
} from '@urbit/api'; } from '@urbit/api';
import { GraphConfig } from '@urbit/api/dist'; import { GraphConfig } from '@urbit/api';
import _ from 'lodash'; import _ from 'lodash';
import React, { ReactElement, ReactNode, useCallback } from 'react'; import React, { ReactElement, ReactNode, useCallback } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
@ -217,6 +217,7 @@ function InviteActions(props: {
const hideJoin = useCallback(async (e) => { const hideJoin = useCallback(async (e) => {
if(status?.progress === 'done') { if(status?.progress === 'done') {
set(s => { set(s => {
// @ts-ignore investigate zustand types
delete s.pendingJoin[resource] delete s.pendingJoin[resource]
}); });
e.stopPropagation(); e.stopPropagation();
@ -245,14 +246,14 @@ function InviteActions(props: {
color="blue" color="blue"
height={4} height={4}
backgroundColor="white" backgroundColor="white"
onClick={inviteAccept} onClick={inviteAccept as any}
> >
Accept Accept
</StatelessAsyncButton> </StatelessAsyncButton>
<StatelessAsyncButton <StatelessAsyncButton
height={4} height={4}
backgroundColor="white" backgroundColor="white"
onClick={inviteDecline} onClick={inviteDecline as any}
> >
Decline Decline
</StatelessAsyncButton> </StatelessAsyncButton>

View File

@ -218,7 +218,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => {
textOverflow='ellipsis' textOverflow='ellipsis'
overflow='hidden' overflow='hidden'
whiteSpace='pre' whiteSpace='pre'
marginBottom={0} mb={0}
disableRemoteContent disableRemoteContent
gray gray
title={contact?.status ? contact.status : ''} title={contact?.status ? contact.status : ''}

View File

@ -41,7 +41,7 @@ export const ProfileStatus = (props) => {
<Input <Input
onChange={onStatusChange} onChange={onStatusChange}
value={_status} value={_status}
autocomplete='off' autoComplete='off'
width='100%' width='100%'
placeholder='Set Status' placeholder='Set Status'
onKeyPress={(evt) => { onKeyPress={(evt) => {

View File

@ -8,15 +8,15 @@ const ReconnectButton = ({ connection, subscription }) => {
if (connectedStatus === 'disconnected') { if (connectedStatus === 'disconnected') {
return ( return (
<Button onClick={reconnect} borderColor='red' px={2}> <Button onClick={reconnect} borderColor='red' px={2}>
<Text display={['none', 'inline']} textAlign='middle' color='red'>Reconnect</Text> <Text display={['none', 'inline']} textAlign='center' color='red'>Reconnect</Text>
<Text color='red'> </Text> <Text color='red'> </Text>
</Button> </Button>
); );
} else if (connectedStatus === 'reconnecting') { } else if (connectedStatus === 'reconnecting') {
return ( return (
<Button borderColor='yellow' px={2} onClick={() => {}} cursor='default'> <Button borderColor='yellow' px={2} onClick={() => {}} cursor='default'>
<LoadingSpinner pr={['0','2']} foreground='scales.yellow60' background='scales.yellow30' /> <LoadingSpinner foreground='scales.yellow60' background='scales.yellow30' />
<Text display={['none', 'inline']} textAlign='middle' color='yellow'>Reconnecting</Text> <Text display={['none', 'inline']} pl={['0','2']} textAlign='center' color='yellow'>Reconnecting</Text>
</Button> </Button>
); );
} else { } else {

View File

@ -24,7 +24,7 @@ const DISABLED_BLOCK_TOKENS = [
const DISABLED_INLINE_TOKENS = []; const DISABLED_INLINE_TOKENS = [];
type RichTextProps = ReactMarkdownProps & { type RichTextProps = ReactMarkdownProps & {
api: GlobalApi; api?: GlobalApi;
disableRemoteContent?: boolean; disableRemoteContent?: boolean;
contact?: Contact; contact?: Contact;
group?: Group; group?: Group;
@ -34,6 +34,20 @@ type RichTextProps = ReactMarkdownProps & {
color?: string; color?: string;
children?: any; children?: any;
width?: string; width?: string;
display?: string[] | string;
mono?: boolean;
mb?: number;
minWidth?: number | string;
maxWidth?: number | string;
flexShrink?: number;
textOverflow?: string;
overflow?: string;
whiteSpace?: string;
gray?: boolean;
title?: string;
py?: number;
overflowX?: any;
verticalAlign?: any;
} }
const RichText = React.memo(({ disableRemoteContent = false, api, ...props }: RichTextProps) => ( const RichText = React.memo(({ disableRemoteContent = false, api, ...props }: RichTextProps) => (
@ -48,6 +62,7 @@ const RichText = React.memo(({ disableRemoteContent = false, api, ...props }: Ri
oembedShown: false oembedShown: false
} : null; } : null;
if (!disableRemoteContent) { if (!disableRemoteContent) {
// @ts-ignore RemoteContent weirdness
return <RemoteContent className="mw-100" url={linkProps.href} />; return <RemoteContent className="mw-100" url={linkProps.href} />;
} }
@ -59,16 +74,16 @@ const RichText = React.memo(({ disableRemoteContent = false, api, ...props }: Ri
borderBottom='1px solid' borderBottom='1px solid'
remoteContentPolicy={remoteContentPolicy} remoteContentPolicy={remoteContentPolicy}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
}} }}
{...linkProps} {...linkProps}
>{linkProps.children}</Anchor> >{linkProps.children}</Anchor>
); );
}, },
linkReference: (linkProps) => { linkReference: (linkProps): any => {
const linkText = String(linkProps.children[0].props.children); const linkText = String(linkProps.children[0].props.children);
if (isValidPatp(linkText)) { if (isValidPatp(linkText)) {
return <Mention contact={props.contact || {}} group={props.group} ship={deSig(linkText)} api={api} />; return <Mention ship={deSig(linkText)} api={api} />;
} else if(linkText.startsWith('web+urbitgraph://')) { } else if(linkText.startsWith('web+urbitgraph://')) {
return ( return (
<PermalinkEmbed <PermalinkEmbed

View File

@ -10,7 +10,6 @@ const Spinner = ({
<LoadingSpinner <LoadingSpinner
foreground='black' foreground='black'
background='gray' background='gray'
style={{ flexShrink: 0 }}
/> />
<Text display='inline-block' ml={2} verticalAlign='middle' flexShrink={0}>{text}</Text> <Text display='inline-block' ml={2} verticalAlign='middle' flexShrink={0}>{text}</Text>
</Text> </Text>

View File

@ -73,7 +73,7 @@ const StatusBar = (props) => {
px={3} px={3}
pb={3} pb={3}
> >
<Row collapse> <Row>
<Button <Button
width='32px' width='32px'
borderColor='lightGray' borderColor='lightGray'
@ -108,7 +108,7 @@ const StatusBar = (props) => {
subscription={props.subscription} subscription={props.subscription}
/> />
</Row> </Row>
<Row justifyContent='flex-end' collapse> <Row justifyContent='flex-end'>
<StatusBarItem <StatusBarItem
width='32px' width='32px'
mr={2} mr={2}

View File

@ -100,8 +100,8 @@ export function Omnibox(props: OmniboxProps): ReactElement {
} }
Mousetrap.bind('escape', props.toggle); Mousetrap.bind('escape', props.toggle);
const touchstart = new Event('touchstart'); const touchstart = new Event('touchstart');
inputRef?.current?.input?.dispatchEvent(touchstart); inputRef?.current?.dispatchEvent(touchstart);
inputRef?.current?.input?.focus(); inputRef?.current?.focus();
return () => { return () => {
Mousetrap.unbind('escape'); Mousetrap.unbind('escape');
setQuery(''); setQuery('');
@ -173,6 +173,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
const totalLength = flattenedResults.length; const totalLength = flattenedResults.length;
if (selected.length) { if (selected.length) {
const currentIndex = flattenedResults.indexOf( const currentIndex = flattenedResults.indexOf(
// @ts-ignore unclear how to give this spread a return signature
...flattenedResults.filter((e) => { ...flattenedResults.filter((e) => {
return e.link === selected[1]; return e.link === selected[1];
}) })
@ -194,6 +195,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
const flattenedResults = Array.from(results.values()).flat(); const flattenedResults = Array.from(results.values()).flat();
if (selected.length) { if (selected.length) {
const currentIndex = flattenedResults.indexOf( const currentIndex = flattenedResults.indexOf(
// @ts-ignore unclear how to give this spread a return signature
...flattenedResults.filter((e) => { ...flattenedResults.filter((e) => {
return e.link === selected[1]; return e.link === selected[1];
}) })
@ -325,6 +327,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
{categoryResults.sort(sortResults).map((result, i2) => ( {categoryResults.sort(sortResults).map((result, i2) => (
<OmniboxResult <OmniboxResult
key={i2} key={i2}
// @ts-ignore withHovering doesn't pass props
icon={result.app} icon={result.app}
text={result.title} text={result.title}
subtext={result.host} subtext={result.host}
@ -365,8 +368,10 @@ export function Omnibox(props: OmniboxProps): ReactElement {
omniboxRef.current = el; omniboxRef.current = el;
}} }}
> >
{ /* @ts-ignore investigate zustand types */ }
<OmniboxInput <OmniboxInput
ref={(el) => { ref={(el) => {
// @ts-ignore investigate refs
inputRef.current = el; inputRef.current = el;
}} }}
control={e => control(e)} control={e => control(e)}
@ -380,5 +385,5 @@ export function Omnibox(props: OmniboxProps): ReactElement {
</Portal> </Portal>
); );
} }
// @ts-ignore investigate zustand types
export default withLocalState(Omnibox, ['toggleOmnibox', 'omniboxShown']); export default withLocalState(Omnibox, ['toggleOmnibox', 'omniboxShown']);

View File

@ -4,6 +4,7 @@ import React, { Component, ReactElement } from 'react';
import defaultApps from '~/logic/lib/default-apps'; import defaultApps from '~/logic/lib/default-apps';
import Sigil from '~/logic/lib/sigil'; import Sigil from '~/logic/lib/sigil';
import { cite, uxToHex } from '~/logic/lib/util'; import { cite, uxToHex } from '~/logic/lib/util';
import { IconRef } from '~/types/util';
import withState from '~/logic/lib/withState'; import withState from '~/logic/lib/withState';
import useContactState from '~/logic/state/contact'; import useContactState from '~/logic/state/contact';
import useHarkState from '~/logic/state/hark'; import useHarkState from '~/logic/state/hark';
@ -18,6 +19,7 @@ interface OmniboxResultProps {
link: string; link: string;
navigate: () => void; navigate: () => void;
notificationsCount: number; notificationsCount: number;
runtimeLag: any;
selected: string; selected: string;
setSelection: () => void; setSelection: () => void;
subtext: string; subtext: string;
@ -50,6 +52,7 @@ export class OmniboxResult extends Component<OmniboxResultProps, OmniboxResultSt
props.selected === props.link props.selected === props.link
&& this.result.current && this.result.current
) { ) {
// @ts-ignore ref is forwarded as never, investigate later
this.result.current.scrollIntoView({ block: 'nearest' }); this.result.current.scrollIntoView({ block: 'nearest' });
} }
} }
@ -63,7 +66,7 @@ export class OmniboxResult extends Component<OmniboxResultProps, OmniboxResultSt
notificationsCount: number, notificationsCount: number,
text: string, text: string,
color: string color: string
): (typeof Icon) { ): (any) {
const iconFill = const iconFill =
(this.state.hovered || selected === link) ? 'white' : 'black'; (this.state.hovered || selected === link) ? 'white' : 'black';
const bulletFill = const bulletFill =
@ -89,7 +92,7 @@ export class OmniboxResult extends Component<OmniboxResultProps, OmniboxResultSt
<Icon <Icon
display='inline-block' display='inline-block'
verticalAlign='middle' verticalAlign='middle'
icon={icon} icon={icon as IconRef}
mr={2} mr={2}
size='18px' size='18px'
color={iconFill} color={iconFill}
@ -254,6 +257,7 @@ export class OmniboxResult extends Component<OmniboxResultProps, OmniboxResultSt
onClick={navigate} onClick={navigate}
width='100%' width='100%'
justifyContent='space-between' justifyContent='space-between'
// @ts-ignore indigo-react doesn't allow us to pass refs
ref={this.result} ref={this.result}
> >
<Box <Box

View File

@ -1,18 +0,0 @@
import deep_diff from 'deep-diff';
import React, { Component, useEffect, useRef } from 'react';
const withPropsChecker = (WrappedComponent: Component) => {
return (props: any) => {
const prevProps = useRef(props);
useEffect(() => {
const diff = deep_diff.diff(prevProps.current, props);
if (diff) {
console.log(diff);
}
prevProps.current = props;
});
return <WrappedComponent {...props} />;
};
};
export default withPropsChecker;

View File

@ -9,7 +9,7 @@ import { Content, ReferenceContent } from '@urbit/api';
import _ from 'lodash'; import _ from 'lodash';
import { import {
BlockContent, Content as AstContent, Parent, Root BlockContent, Content as AstContent, Parent, Root
} from 'mdast'; } from 'ts-mdast';
import React from 'react'; import React from 'react';
import GlobalApi from '~/logic/api/global'; import GlobalApi from '~/logic/api/global';
import { referenceToPermalink } from '~/logic/lib/permalinks'; import { referenceToPermalink } from '~/logic/lib/permalinks';
@ -350,12 +350,18 @@ const renderers = {
'graph-mention': ({ ship }) => <Mention api={{} as any} ship={ship} />, 'graph-mention': ({ ship }) => <Mention api={{} as any} ship={ship} />,
image: ({ url }) => ( image: ({ url }) => (
<Box mt="1" mb="2" flexShrink={0}> <Box mt="1" mb="2" flexShrink={0}>
<RemoteContent key={url} url={url} /> <RemoteContent
// @ts-ignore RemoteContent weirdness
key={url} url={url}
/>
</Box> </Box>
), ),
'graph-url': ({ url }) => ( 'graph-url': ({ url }) => (
<Box mt={1} mb={2} flexShrink={0}> <Box mt={1} mb={2} flexShrink={0}>
<RemoteContent key={url} url={url} /> <RemoteContent
// @ts-ignore RemoteContent weirdness
key={url} url={url}
/>
</Box> </Box>
), ),
'graph-reference': ({ api, reference, transcluded }) => { 'graph-reference': ({ api, reference, transcluded }) => {

View File

@ -1,5 +1,6 @@
import { Box, Col } from '@tlon/indigo-react'; import { Box, Col } from '@tlon/indigo-react';
import { Association, Graph, GraphNode, Group } from '@urbit/api'; import { Association, Graph, GraphNode, Group } from '@urbit/api';
import { History } from 'history';
import bigInt from 'big-integer'; import bigInt from 'big-integer';
import React from 'react'; import React from 'react';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
@ -26,7 +27,7 @@ interface PostFeedProps {
pendingSize: number; pendingSize: number;
} }
class PostFeed extends React.Component<PostFeedProps, PostFeedState> { class PostFeed extends React.Component<PostFeedProps, any> {
isFetching: boolean; isFetching: boolean;
constructor(props) { constructor(props) {
super(props); super(props);
@ -36,7 +37,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
this.fetchPosts = this.fetchPosts.bind(this); this.fetchPosts = this.fetchPosts.bind(this);
this.doNotFetch = this.doNotFetch.bind(this); this.doNotFetch = this.doNotFetch.bind(this);
} }
// @ts-ignore needs @liam-fitzgerald peek at props for virtualscroller
renderItem = React.forwardRef(({ index, scrollWindow }, ref) => { renderItem = React.forwardRef(({ index, scrollWindow }, ref) => {
const { const {
graph, graph,
@ -57,7 +58,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
const first = graph.peekLargest()?.[0]; const first = graph.peekLargest()?.[0];
const post = node?.post; const post = node?.post;
const nodeIndex = const nodeIndex =
( parentNode && ( parentNode &&
typeof parentNode.post !== 'string' typeof parentNode.post !== 'string'
) ? parentNode.post.index.split('/').slice(1).map((ind) => { ) ? parentNode.post.index.split('/').slice(1).map((ind) => {
@ -69,6 +70,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
<React.Fragment key={index.toString()}> <React.Fragment key={index.toString()}>
<Col <Col
key={index.toString()} key={index.toString()}
// @ts-ignore indigo-react doesn't allow us to pass refs
ref={ref} ref={ref}
mb={3} mb={3}
width="100%" width="100%"
@ -76,6 +78,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
> >
<PostItem <PostItem
key={parentNode.post.index} key={parentNode.post.index}
// @ts-ignore withHovering prop pass is broken?
parentPost={grandparentNode?.post} parentPost={grandparentNode?.post}
node={parentNode} node={parentNode}
parentNode={grandparentNode} parentNode={grandparentNode}
@ -92,6 +95,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
/> />
</Col> </Col>
<PostItem <PostItem
// @ts-ignore withHovering prop pass is broken?
node={node} node={node}
graphPath={graphPath} graphPath={graphPath}
association={association} association={association}
@ -110,8 +114,10 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
} }
return ( return (
// @ts-ignore indigo-react doesn't allow us to pass refs
<Box key={index.toString()} ref={ref}> <Box key={index.toString()} ref={ref}>
<PostItem <PostItem
// @ts-ignore withHovering prop pass is broken?
node={node} node={node}
graphPath={graphPath} graphPath={graphPath}
association={association} association={association}
@ -179,6 +185,7 @@ class PostFeed extends React.Component<PostFeedProps, PostFeedState> {
data={graph} data={graph}
averageHeight={106} averageHeight={106}
size={graph.size} size={graph.size}
totalSize={graph.size}
style={virtualScrollerStyle} style={virtualScrollerStyle}
pendingSize={pendingSize} pendingSize={pendingSize}
renderer={this.renderItem} renderer={this.renderItem}

View File

@ -120,7 +120,7 @@ const PostInput = (props: PostInputProps): ReactElement | null => {
fontSize={1} fontSize={1}
minHeight="62px" minHeight="62px"
fontFamily={code ? 'mono' : 'sans'} fontFamily={code ? 'mono' : 'sans'}
lineNumber={3} rows={3}
style={{ style={{
resize: 'vertical' resize: 'vertical'
}} }}

View File

@ -15,6 +15,7 @@ interface PostHeaderProps {
association: Association; association: Association;
isReply: boolean; isReply: boolean;
showTimestamp: boolean; showTimestamp: boolean;
graphPath: any;
} }
const PostHeader = (props: PostHeaderProps): ReactElement => { const PostHeader = (props: PostHeaderProps): ReactElement => {

View File

@ -1,4 +1,5 @@
import { Box, Col, Text } from '@tlon/indigo-react'; import { Box, Col, Text } from '@tlon/indigo-react';
import { GraphNode } from '@urbit/api';
import bigInt from 'big-integer'; import bigInt from 'big-integer';
import React from 'react'; import React from 'react';
import { resourceFromPath } from '~/logic/lib/group'; import { resourceFromPath } from '~/logic/lib/group';
@ -37,7 +38,7 @@ export default function PostReplies(props) {
return bigInt(ind); return bigInt(ind);
}); });
let node; let node: GraphNode;
let parentNode; let parentNode;
nodeIndex.forEach((i, idx) => { nodeIndex.forEach((i, idx) => {
if (!graph) { if (!graph) {
@ -69,6 +70,7 @@ export default function PostReplies(props) {
<Box mt={3} width="100%" alignItems="center"> <Box mt={3} width="100%" alignItems="center">
<PostItem <PostItem
key={node.post.index} key={node.post.index}
// @ts-ignore withHovering prop pass is broken?
node={node} node={node}
graphPath={graphPath} graphPath={graphPath}
association={association} association={association}

View File

@ -1,5 +1,6 @@
import { Box, Col, Text } from '@tlon/indigo-react'; import { Box, Col, Text } from '@tlon/indigo-react';
import { Association, Graph, Group } from '@urbit/api'; import { Association, Graph, Group } from '@urbit/api';
import { History } from 'history';
import React, { ReactElement } from 'react'; import React, { ReactElement } from 'react';
import GlobalApi from '~/logic/api/global'; import GlobalApi from '~/logic/api/global';
import { Loading } from '~/views/components/Loading'; import { Loading } from '~/views/components/Loading';
@ -15,6 +16,7 @@ interface PostTimelineProps {
group: Group; group: Group;
pendingSize: number; pendingSize: number;
vip: string; vip: string;
history?: History;
} }
const PostTimeline = (props: PostTimelineProps): ReactElement => { const PostTimeline = (props: PostTimelineProps): ReactElement => {

View File

@ -31,7 +31,7 @@ interface NewGroupProps {
api: GlobalApi; api: GlobalApi;
} }
export function NewGroup(props: NewGroupProps & RouteComponentProps): ReactElement { export function NewGroup(props: NewGroupProps): ReactElement {
const { api } = props; const { api } = props;
const history = useHistory(); const history = useHistory();
const initialValues: FormSchema = { const initialValues: FormSchema = {

View File

@ -81,12 +81,15 @@ export function SidebarList(props: {
const cycleChannels = useCallback((backward: boolean) => { const cycleChannels = useCallback((backward: boolean) => {
const idx = ordered.findIndex(s => s === selected); const idx = ordered.findIndex(s => s === selected);
const offset = backward ? -1 : 1 const offset = backward ? -1 : 1
const newIdx = modulo(idx+offset, ordered.length - 1); const newIdx = modulo(idx+offset, ordered.length - 1);
const { metadata, resource } = associations[ordered[newIdx]]; const { metadata, resource } = associations[ordered[newIdx]];
const joined = graphKeys.has(resource.slice(7)); const joined = graphKeys.has(resource.slice(7));
const path = getResourcePath(workspace, resource, joined, metadata.config.graph) let path = '/~landscape/home';
if ('graph' in metadata.config) {
path = getResourcePath(workspace, resource, joined, metadata.config.graph);
}
history.push(path) history.push(path)
}, [selected, history.push]); }, [selected, history.push]);