mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 13:54:20 +03:00
hark: add publish support
This commit is contained in:
parent
13fe6c3ad1
commit
04c1ad6653
@ -3,6 +3,14 @@
|
||||
++ grow
|
||||
|%
|
||||
++ noun i
|
||||
:: +notification-kind
|
||||
:: Ignore all containers, only notify on content
|
||||
::
|
||||
++ notification-kind
|
||||
?+ index.p.i ~
|
||||
[@ %1 @ ~] `%note
|
||||
[@ %2 @ ~] `%comment
|
||||
==
|
||||
--
|
||||
++ grab
|
||||
|%
|
||||
|
@ -354,3 +354,7 @@ export function usePreventWindowUnload(shouldPreventDefault: boolean, message =
|
||||
}
|
||||
}, [shouldPreventDefault]);
|
||||
}
|
||||
|
||||
export function pluralize(text: string, isPlural = false, vowel = false) {
|
||||
return isPlural ? `${text}s`: `${vowel ? 'an' : 'a'} ${text}`;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { ReactNode, useCallback } from "react";
|
||||
import moment from "moment";
|
||||
import { Row, Box, Col, Text, Anchor, Icon, Action } from "@tlon/indigo-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import _ from "lodash";
|
||||
import {
|
||||
Post,
|
||||
@ -11,10 +12,13 @@ import {
|
||||
Rolodex,
|
||||
} from "~/types";
|
||||
import { Header } from "./header";
|
||||
import { cite, deSig } from "~/logic/lib/util";
|
||||
import { cite, deSig, pluralize } from "~/logic/lib/util";
|
||||
import { Sigil } from "~/logic/lib/sigil";
|
||||
import RichText from "~/views/components/RichText";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { getSnippet } from "~/logic/lib/publish";
|
||||
import styled from "styled-components";
|
||||
|
||||
function getGraphModuleIcon(module: string) {
|
||||
if (module === "link") {
|
||||
@ -23,12 +27,22 @@ function getGraphModuleIcon(module: string) {
|
||||
return _.capitalize(module);
|
||||
}
|
||||
|
||||
const FilterBox = styled(Box)`
|
||||
background: linear-gradient(
|
||||
${(p) => p.theme.colors.scales.white10} 0%,
|
||||
${(p) => p.theme.colors.scales.white60} 40%,
|
||||
${(p) => p.theme.colors.scales.white100} 100%
|
||||
);
|
||||
`;
|
||||
|
||||
function describeNotification(description: string, plural: boolean) {
|
||||
switch (description) {
|
||||
case "link":
|
||||
return `added ${plural ? "new links" : "a new link"} to`;
|
||||
return `added ${pluralize("new link", plural)} to`;
|
||||
case "comment":
|
||||
return `left ${plural ? "comments" : "a comment"} on`;
|
||||
return `left ${pluralize("comment", plural)} on`;
|
||||
case "note":
|
||||
return `posted ${pluralize("note", plural)} to`;
|
||||
case "mention":
|
||||
return "mentioned you on";
|
||||
default:
|
||||
@ -45,21 +59,71 @@ const GraphUrl = ({ url, title }) => (
|
||||
</Box>
|
||||
);
|
||||
|
||||
const GraphNodeContent = ({ contents, module, description, index }) => {
|
||||
if (module === "link") {
|
||||
const lent = index.slice(1).split("/").length;
|
||||
if (lent === 1) {
|
||||
const GraphNodeContent = ({ contents, mod, description, index }) => {
|
||||
const idx = index.slice(1).split("/");
|
||||
if (mod === "link") {
|
||||
if (idx.length === 1) {
|
||||
const [{ text }, { url }] = contents;
|
||||
return <GraphUrl title={text} url={url} />;
|
||||
} else if (lent === 2) {
|
||||
} else if (idx.length === 2) {
|
||||
const [{ text }] = contents;
|
||||
return <RichText>{text}</RichText>;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (mod === "publish") {
|
||||
if (idx.length !== 3) {
|
||||
return null;
|
||||
} else if (idx[1] === "2") {
|
||||
const [{ text }] = contents;
|
||||
return <RichText>{text}</RichText>;
|
||||
} else if (idx[1] === "1") {
|
||||
const [{ text: header }, { text: body }] = contents;
|
||||
const snippet = getSnippet(body);
|
||||
return (
|
||||
<Col>
|
||||
<Box mb="2" fontWeight="500">
|
||||
{header}
|
||||
</Box>
|
||||
<Box overflow="hidden" maxHeight="400px">
|
||||
{snippet}
|
||||
<FilterBox
|
||||
width="100%"
|
||||
zIndex="1"
|
||||
height="calc(100% - 2em)"
|
||||
bottom="0px"
|
||||
position="absolute"
|
||||
/>
|
||||
</Box>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const GraphNode = ({ contents, author, module, description, time, index }) => {
|
||||
|
||||
function getNodeUrl(mod: string, group: string, graph: string, index: string) {
|
||||
const graphUrl = `/~landscape${group}/resource/${mod}${graph}`;
|
||||
const idx = index.slice(1).split("/");
|
||||
if (mod === "publish") {
|
||||
const [noteId] = idx;
|
||||
return `${graphUrl}/note/${noteId}`;
|
||||
} else if (mod === "link") {
|
||||
const [linkId] = idx;
|
||||
return `${graphUrl}/-${linkId}`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
const GraphNode = ({
|
||||
contents,
|
||||
author,
|
||||
mod,
|
||||
description,
|
||||
time,
|
||||
index,
|
||||
graph,
|
||||
group,
|
||||
}) => {
|
||||
author = deSig(author);
|
||||
|
||||
const img = (
|
||||
@ -72,34 +136,38 @@ const GraphNode = ({ contents, author, module, description, time, index }) => {
|
||||
/>
|
||||
);
|
||||
|
||||
const nodeUrl = getNodeUrl(mod, group, graph, index);
|
||||
|
||||
return (
|
||||
<Row gapX="2" py="2">
|
||||
<Col>{img}</Col>
|
||||
<Col alignItems="flex-start">
|
||||
<Row
|
||||
mb="2"
|
||||
height="16px"
|
||||
alignItems="center"
|
||||
p="1"
|
||||
backgroundColor="white"
|
||||
>
|
||||
<Text mono title={author}>
|
||||
{cite(author)}
|
||||
</Text>
|
||||
<Text ml="2" gray>
|
||||
{moment(time).format("HH:mm")}
|
||||
</Text>
|
||||
</Row>
|
||||
<Row p="1">
|
||||
<GraphNodeContent
|
||||
contents={contents}
|
||||
module={module}
|
||||
description={description}
|
||||
index={index}
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Link to={nodeUrl}>
|
||||
<Row gapX="2" py="2">
|
||||
<Col>{img}</Col>
|
||||
<Col alignItems="flex-start">
|
||||
<Row
|
||||
mb="2"
|
||||
height="16px"
|
||||
alignItems="center"
|
||||
p="1"
|
||||
backgroundColor="white"
|
||||
>
|
||||
<Text mono title={author}>
|
||||
{cite(author)}
|
||||
</Text>
|
||||
<Text ml="2" gray>
|
||||
{moment(time).format("HH:mm")}
|
||||
</Text>
|
||||
</Row>
|
||||
<Row p="1">
|
||||
<GraphNodeContent
|
||||
contents={contents}
|
||||
mod={mod}
|
||||
description={description}
|
||||
index={index}
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
@ -149,14 +217,15 @@ export function GraphNotification(props: {
|
||||
<GraphNode
|
||||
author={content.author}
|
||||
contents={content.contents}
|
||||
module={index.module}
|
||||
mod={index.module}
|
||||
time={content["time-sent"]}
|
||||
description={index.description}
|
||||
index={content.index}
|
||||
graph={graph}
|
||||
group={group}
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ function DaySection({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box position="sticky" zIndex="2" top="0px" bg="white">
|
||||
<Box position="sticky" zIndex="3" top="-1px" bg="white">
|
||||
<Box p="2" bg="scales.black05">
|
||||
{moment(daToUnix(timeboxes[0][0])).calendar(null, calendar)}
|
||||
</Box>
|
||||
|
@ -6,6 +6,7 @@ import { Dropdown } from "~/views/components/Dropdown";
|
||||
import { Association, NotificationGraphConfig } from "~/types";
|
||||
import GlobalApi from "~/logic/api/global";
|
||||
import { StatelessAsyncAction } from "~/views/components/StatelessAsyncAction";
|
||||
import {appIsGraph} from "~/logic/lib/util";
|
||||
|
||||
const ChannelMenuItem = ({
|
||||
icon,
|
||||
@ -99,7 +100,7 @@ export function ChannelMenu(props: ChannelMenuProps) {
|
||||
borderRadius={1}
|
||||
borderColor="lightGray"
|
||||
>
|
||||
{metadata.module === "link" && (
|
||||
{appIsGraph(metadata.module) && (
|
||||
<ChannelMenuItem color="blue" icon="Inbox">
|
||||
<StatelessAsyncAction
|
||||
m="2"
|
||||
|
Loading…
Reference in New Issue
Block a user