mirror of
https://github.com/urbit/shrub.git
synced 2024-12-19 16:51:42 +03:00
Merge pull request #4975 from urbit/lf/more-buses
interface: post-deploy fix omnibus
This commit is contained in:
commit
6a23722448
@ -62,8 +62,8 @@ export function getNotificationKey(
|
||||
): string {
|
||||
const base = time.toString();
|
||||
if ('graph' in notification.index) {
|
||||
const { graph, index } = notification.index.graph;
|
||||
return `${base}-${graph}-${index}`;
|
||||
const { graph, index, description } = notification.index.graph;
|
||||
return `${base}-${graph}-${index}-${description}`;
|
||||
} else if ('group' in notification.index) {
|
||||
const { group } = notification.index.group;
|
||||
return `${base}-${group}`;
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
Timebox
|
||||
} from '@urbit/api';
|
||||
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
|
||||
import { BigInteger } from 'big-integer';
|
||||
import _ from 'lodash';
|
||||
import { compose } from 'lodash/fp';
|
||||
import { makePatDa } from '~/logic/lib/util';
|
||||
@ -152,7 +151,9 @@ function unreads(json: any, state: HarkState): HarkState {
|
||||
const { unreads, notifications, last } = stats;
|
||||
updateNotificationStats(state, index, 'last', () => last);
|
||||
_.each(notifications, ({ time, index }) => {
|
||||
addNotificationToUnread(state, index, makePatDa(time));
|
||||
if(!time) {
|
||||
addNotificationToUnread(state, index);
|
||||
}
|
||||
});
|
||||
if('count' in unreads) {
|
||||
updateUnreadCount(state, index, (u = 0) => u + unreads.count);
|
||||
@ -210,14 +211,16 @@ function updateUnreads(state: HarkState, index: NotifIndex, f: (us: Set<string>)
|
||||
return state;
|
||||
}
|
||||
|
||||
function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigInteger) {
|
||||
function addNotificationToUnread(state: HarkState, index: NotifIndex) {
|
||||
if('graph' in index) {
|
||||
const path = [index.graph.graph, index.graph.index, 'notifications'];
|
||||
const curr = _.get(state.unreads.graph, path, []);
|
||||
_.set(state.unreads.graph, path,
|
||||
[
|
||||
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
|
||||
{ time, index }
|
||||
...curr.filter((c) => {
|
||||
return !(notifIdxEqual(c.index, index));
|
||||
}),
|
||||
{ index }
|
||||
]
|
||||
);
|
||||
} else if ('group' in index) {
|
||||
@ -225,12 +228,23 @@ function addNotificationToUnread(state: HarkState, index: NotifIndex, time: BigI
|
||||
const curr = _.get(state.unreads.group, path, []);
|
||||
_.set(state.unreads.group, path,
|
||||
[
|
||||
...curr.filter(c => !(c.time.eq(time) && notifIdxEqual(c.index, index))),
|
||||
{ time, index }
|
||||
...curr.filter(c => !notifIdxEqual(c.index, index)),
|
||||
{ index }
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
function removeNotificationFromUnread(state: HarkState, index: NotifIndex) {
|
||||
if('graph' in index) {
|
||||
const path = [index.graph.graph, index.graph.index, 'notifications'];
|
||||
const curr = _.get(state.unreads.graph, path, []);
|
||||
_.set(state.unreads.graph, path, curr.filter(c => !notifIdxEqual(c.index, index)));
|
||||
} else if ('group' in index) {
|
||||
const path = [index.group.group, 'notifications'];
|
||||
const curr = _.get(state.unreads.group, path, []);
|
||||
_.set(state.unreads.group, path, curr.filter(c => !notifIdxEqual(c.index, index)));
|
||||
}
|
||||
}
|
||||
|
||||
function updateNotificationStats(state: HarkState, index: NotifIndex, statField: 'unreads' | 'last', f: (x: number) => number, notify = false) {
|
||||
if('graph' in index) {
|
||||
@ -280,6 +294,9 @@ const timebox = (json: any, state: HarkState): HarkState => {
|
||||
state.notifications = state.notifications.set(time, data.notifications);
|
||||
} else {
|
||||
state.unreadNotes = data.notifications;
|
||||
_.each(data.notifications, ({ index }) => {
|
||||
addNotificationToUnread(state, index);
|
||||
});
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -338,6 +355,7 @@ function read(json: any, state: HarkState): HarkState {
|
||||
read[0].notification.contents = mergeNotifs(read[0].notification.contents, toMerge[0].notification.contents);
|
||||
}
|
||||
state.notifications = state.notifications.set(time, [...read, ...rest]);
|
||||
removeNotificationFromUnread(state, index);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -364,6 +382,7 @@ function archive(json: any, state: HarkState): HarkState {
|
||||
}
|
||||
} else {
|
||||
state.unreadNotes = state.unreadNotes.filter(({ index: idx }) => !notifIdxEqual(idx, index));
|
||||
removeNotificationFromUnread(state, index);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
@ -54,7 +54,12 @@ Omnibus.args = {
|
||||
{ mention: 'sipfyn-pidmex' },
|
||||
{ text: `: you can always use a pattern like this
|
||||
> blockquote demo
|
||||
should not be quoted` }
|
||||
should not be quoted
|
||||
> blockquote, then newline, then mention
|
||||
` },
|
||||
{ mention: '~sampel-palnet' },
|
||||
{ text: '> mention inside blockquote' },
|
||||
{ mention: '~sampel-palnet' }
|
||||
]
|
||||
};
|
||||
|
||||
|
17
pkg/interface/src/stories/PendingDm.stories.tsx
Normal file
17
pkg/interface/src/stories/PendingDm.stories.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import { Meta } from '@storybook/react';
|
||||
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import { PendingDm } from '~/views/apps/notifications/PendingDm';
|
||||
|
||||
export default {
|
||||
title: 'Notifications/PendingDm',
|
||||
component: PendingDm
|
||||
} as Meta;
|
||||
const fakeApi = {} as any;
|
||||
|
||||
export const Default = () => (
|
||||
<Box width="95%" p="1" backgroundColor="white">
|
||||
<PendingDm api={fakeApi} ship="~hastuc-dibtux" />
|
||||
</Box>
|
||||
);
|
@ -1,5 +1,6 @@
|
||||
import { cite, Content } from '@urbit/api';
|
||||
import { cite, Content, Post } from '@urbit/api';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import _ from 'lodash';
|
||||
import bigInt from 'big-integer';
|
||||
import { Box, Row, Col, Text } from '@tlon/indigo-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
@ -27,6 +28,27 @@ const getCurrDmSize = (ship: string) => {
|
||||
return shipGraph?.children?.size ?? 0;
|
||||
};
|
||||
|
||||
function quoteReply(post: Post) {
|
||||
const reply = _.reduce(
|
||||
post.contents,
|
||||
(acc, content) => {
|
||||
if ('text' in content) {
|
||||
return `${acc}${content.text}`;
|
||||
} else if ('url' in content) {
|
||||
return `${acc}${content.url}`;
|
||||
} else if ('mention' in content) {
|
||||
return `${acc}${content.mention}`;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
''
|
||||
)
|
||||
.split('\n')
|
||||
.map(l => `> ${l}`)
|
||||
.join('\n');
|
||||
return `${reply}\n\n~${post.author}:`;
|
||||
}
|
||||
|
||||
export function DmResource(props: DmResourceProps) {
|
||||
const { ship, api } = props;
|
||||
const dm = useDM(ship);
|
||||
@ -38,7 +60,12 @@ export function DmResource(props: DmResourceProps) {
|
||||
const nickname = showNickname ? contact!.nickname : cite(ship) ?? ship;
|
||||
|
||||
useEffect(() => {
|
||||
api.graph.getNewest(`~${window.ship}`, 'dm-inbox', 100, `/${patpToUd(ship)}`);
|
||||
api.graph.getNewest(
|
||||
`~${window.ship}`,
|
||||
'dm-inbox',
|
||||
100,
|
||||
`/${patpToUd(ship)}`
|
||||
);
|
||||
}, [ship]);
|
||||
|
||||
const fetchMessages = useCallback(
|
||||
@ -75,7 +102,10 @@ export function DmResource(props: DmResourceProps) {
|
||||
);
|
||||
|
||||
const dismissUnread = useCallback(() => {
|
||||
api.hark.dismissReadCount(`/ship/~${window.ship}/dm-inbox`, `/${patp2dec(ship)}`);
|
||||
api.hark.dismissReadCount(
|
||||
`/ship/~${window.ship}/dm-inbox`,
|
||||
`/${patp2dec(ship)}`
|
||||
);
|
||||
}, [ship]);
|
||||
|
||||
const onSubmit = useCallback(
|
||||
@ -99,7 +129,7 @@ export function DmResource(props: DmResourceProps) {
|
||||
<Row alignItems="baseline">
|
||||
<Box
|
||||
borderRight={1}
|
||||
borderRightColor='gray'
|
||||
borderRightColor="gray"
|
||||
pr={3}
|
||||
fontSize={1}
|
||||
mr={3}
|
||||
@ -131,10 +161,10 @@ export function DmResource(props: DmResourceProps) {
|
||||
id={ship}
|
||||
graph={dm}
|
||||
unreadCount={unreadCount}
|
||||
onReply={() => ''}
|
||||
onReply={quoteReply}
|
||||
fetchMessages={fetchMessages}
|
||||
dismissUnread={dismissUnread}
|
||||
getPermalink={() => ''}
|
||||
getPermalink={() => undefined}
|
||||
isAdmin
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
|
@ -329,9 +329,11 @@ const MessageActions = ({ onReply, onDelete, msg, isAdmin, permalink }) => {
|
||||
<MessageActionItem onClick={() => onReply(msg)}>
|
||||
Reply
|
||||
</MessageActionItem>
|
||||
{permalink ? (
|
||||
<MessageActionItem onClick={doCopy}>
|
||||
{copyDisplay}
|
||||
</MessageActionItem>
|
||||
) : null }
|
||||
{(isAdmin || isOwn()) ? (
|
||||
<MessageActionItem onClick={e => onDelete(msg)} color='red'>
|
||||
Delete Message
|
||||
|
@ -25,7 +25,7 @@ type ChatWindowProps = {
|
||||
dismissUnread: () => void;
|
||||
pendingSize?: number;
|
||||
showOurContact: boolean;
|
||||
getPermalink: (index: BigInteger) => string;
|
||||
getPermalink: (index: BigInteger) => string | undefined;
|
||||
isAdmin: boolean;
|
||||
};
|
||||
|
||||
@ -208,7 +208,7 @@ class ChatWindow extends Component<
|
||||
This message has been deleted.
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
}
|
||||
if (!this.state.initialized) {
|
||||
return (
|
||||
<MessagePlaceholder
|
||||
@ -239,7 +239,7 @@ class ChatWindow extends Component<
|
||||
};
|
||||
|
||||
return (
|
||||
// @ts-ignore
|
||||
// @ts-ignore virt typings
|
||||
<ChatMessage
|
||||
key={index.toString()}
|
||||
ref={ref}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { Box, Col, Row, Text } from '@tlon/indigo-react';
|
||||
import { Box, Row, Text } from '@tlon/indigo-react';
|
||||
import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction';
|
||||
import Author from '~/views/components/Author';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
@ -23,8 +23,12 @@ export function PendingDm(props: { ship: string; api: GlobalApi }) {
|
||||
bg="washedGray"
|
||||
borderRadius="2"
|
||||
gridTemplateColumns={['1fr 24px', '1fr 200px']}
|
||||
gridRowGap={2}
|
||||
gridTemplateRows="auto"
|
||||
gridTemplateAreas="'header actions' 'main main'"
|
||||
gridTemplateAreas={[
|
||||
'\'header header\' \'actions actions\'',
|
||||
'\'header actions\' \'main main\''
|
||||
]}
|
||||
p={2}
|
||||
m={2}
|
||||
>
|
||||
@ -40,10 +44,17 @@ export function PendingDm(props: { ship: string; api: GlobalApi }) {
|
||||
gridArea="actions"
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<StatelessAsyncAction height="auto" primary p="1" onClick={onAccept}>
|
||||
<StatelessAsyncAction
|
||||
backgroundColor="white"
|
||||
height="auto"
|
||||
primary
|
||||
p="1"
|
||||
onClick={onAccept}
|
||||
>
|
||||
Accept
|
||||
</StatelessAsyncAction>
|
||||
<StatelessAsyncAction
|
||||
backgroundColor="white"
|
||||
height="auto"
|
||||
destructive
|
||||
p="1"
|
||||
|
@ -97,13 +97,13 @@ export const GraphNodeContent = ({ post, mod, index, hidden, association }) => {
|
||||
const { contents } = post;
|
||||
const idx = index.slice(1).split('/');
|
||||
const url = getNodeUrl(mod, hidden, association?.group, association?.resource, index);
|
||||
if (mod === 'link' && idx.length === 1) {
|
||||
if (mod === 'graph-validator-link' && idx.length === 1) {
|
||||
const [{ text: title }] = contents;
|
||||
return (
|
||||
<ContentSummary to={url} icon="Links" name={title} author={post.author} />
|
||||
);
|
||||
}
|
||||
if (mod === 'publish' && idx[1] === '1') {
|
||||
if (mod === 'graph-validator-publish' && idx[1] === '1') {
|
||||
const [{ text: title }] = contents;
|
||||
return (
|
||||
<ContentSummary to={url} icon="Note" name={title} author={post.author} />
|
||||
@ -251,12 +251,6 @@ export function GraphNotification(props: {
|
||||
history.push(`/~landscape/messages/dm/~${authors[0]}`);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!(
|
||||
(index.description === 'note' || index.description === 'link') &&
|
||||
index.index === '/'
|
||||
)
|
||||
) {
|
||||
const first = contents[0];
|
||||
history.push(
|
||||
getNodeUrl(
|
||||
@ -267,7 +261,6 @@ export function GraphNotification(props: {
|
||||
first.index
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [api, timebox, index, read, history.push, authors, dm]);
|
||||
|
||||
const authorsInHeader =
|
||||
|
@ -156,7 +156,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => {
|
||||
icon='Chat'
|
||||
size={16}
|
||||
cursor='pointer'
|
||||
onClick={() => history.push(`/~landscape/messages/dm/${ship}`)}
|
||||
onClick={() => history.push(`/~landscape/messages/dm/~${ship}`)}
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
|
@ -100,9 +100,9 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
}
|
||||
Mousetrap.bind('escape', props.toggle);
|
||||
const touchstart = new Event('touchstart');
|
||||
// @ts-ignore
|
||||
// @ts-ignore ref typings
|
||||
inputRef?.current?.input?.dispatchEvent(touchstart);
|
||||
// @ts-ignore
|
||||
// @ts-ignore ref typings
|
||||
inputRef?.current?.input?.focus();
|
||||
return () => {
|
||||
Mousetrap.unbind('escape');
|
||||
@ -150,7 +150,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
}, [query, index]);
|
||||
|
||||
const navigate = useCallback(
|
||||
(app: string, link: string) => {
|
||||
(app: string, link: string, shift: boolean) => {
|
||||
props.toggle();
|
||||
if (
|
||||
defaultApps.includes(app.toLowerCase()) ||
|
||||
@ -162,6 +162,10 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
app === 'home' ||
|
||||
app === 'inbox'
|
||||
) {
|
||||
if(shift && app === 'profile') {
|
||||
// TODO: hacky, fix
|
||||
link = link.replace('~profile', '~landscape/messages/dm');
|
||||
}
|
||||
history.push(link);
|
||||
} else {
|
||||
window.location.href = link;
|
||||
@ -246,13 +250,14 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
if (evt.key === 'Enter') {
|
||||
evt.preventDefault();
|
||||
if (selected.length) {
|
||||
navigate(selected[0], selected[1]);
|
||||
navigate(selected[0], selected[1], evt.shiftKey);
|
||||
} else if (Array.from(results.values()).flat().length === 0) {
|
||||
return;
|
||||
} else {
|
||||
navigate(
|
||||
Array.from(results.values()).flat()[0].app,
|
||||
Array.from(results.values()).flat()[0].link
|
||||
Array.from(results.values()).flat()[0].link,
|
||||
evt.shiftKey
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -335,7 +340,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
subtext={result.host}
|
||||
link={result.link}
|
||||
cursor={leapCursor}
|
||||
navigate={() => navigate(result.app, result.link)}
|
||||
navigate={() => navigate(result.app, result.link, false)}
|
||||
setSelection={() => setSelection(result.app, result.link)}
|
||||
selected={sel}
|
||||
/>
|
||||
|
@ -122,6 +122,7 @@ function stitchInline(a: any, b: any) {
|
||||
}
|
||||
const lastParaIdx = a.children.length - 1;
|
||||
const last = a.children[lastParaIdx];
|
||||
console.log(last);
|
||||
if (last?.children) {
|
||||
const ros = {
|
||||
...a,
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable */
|
||||
/** pulled from remark-parse
|
||||
*
|
||||
* critical change is that blockquotes require a newline to be continued, see
|
||||
@ -106,6 +107,7 @@ function blockquote(eat, value, silent) {
|
||||
|
||||
index = nextIndex + 1
|
||||
}
|
||||
const trailingNewline = value.charAt(nextIndex) === '\n';
|
||||
|
||||
index = -1
|
||||
length = indents.length
|
||||
@ -118,7 +120,9 @@ function blockquote(eat, value, silent) {
|
||||
|
||||
exit = self.enterBlock()
|
||||
contents = self.tokenizeBlock(contents.join(lineFeed), now)
|
||||
console.log(values);
|
||||
exit()
|
||||
|
||||
return add({type: 'blockquote', children: contents})
|
||||
const added = add({type: 'blockquote', children: contents})
|
||||
return trailingNewline ? add({ type: 'paragraph', children: [] }) : added;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ function lineBreak(eat, value: string, silent) {
|
||||
while(++index < length ) {
|
||||
character = value.charAt(index);
|
||||
if(character === '\n') {
|
||||
eat(character)({ type : 'break' });
|
||||
eat(character)({ type: 'paragraph', contents: [{ type: 'break' }] });
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user