mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-09-21 15:38:59 +03:00
publish: rewrite note components for graph-store
This commit is contained in:
parent
393f9fd53c
commit
2160bed3ca
@ -10,7 +10,6 @@ import ContactsApi from './contacts';
|
|||||||
import GroupsApi from './groups';
|
import GroupsApi from './groups';
|
||||||
import LaunchApi from './launch';
|
import LaunchApi from './launch';
|
||||||
import LinksApi from './links';
|
import LinksApi from './links';
|
||||||
import PublishApi from './publish';
|
|
||||||
import GraphApi from './graph';
|
import GraphApi from './graph';
|
||||||
import S3Api from './s3';
|
import S3Api from './s3';
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ export default class GlobalApi extends BaseApi<StoreState> {
|
|||||||
groups = new GroupsApi(this.ship, this.channel, this.store);
|
groups = new GroupsApi(this.ship, this.channel, this.store);
|
||||||
launch = new LaunchApi(this.ship, this.channel, this.store);
|
launch = new LaunchApi(this.ship, this.channel, this.store);
|
||||||
links = new LinksApi(this.ship, this.channel, this.store);
|
links = new LinksApi(this.ship, this.channel, this.store);
|
||||||
publish = new PublishApi(this.ship, this.channel, this.store);
|
|
||||||
s3 = new S3Api(this.ship, this.channel, this.store);
|
s3 = new S3Api(this.ship, this.channel, this.store);
|
||||||
graph = new GraphApi(this.ship, this.channel, this.store);
|
graph = new GraphApi(this.ship, this.channel, this.store);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import GlobalApi from "~/logic/api/global";
|
|||||||
import { Button, Box, Row, Text } from "@tlon/indigo-react";
|
import { Button, Box, Row, Text } from "@tlon/indigo-react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Author } from "./Author";
|
import { Author } from "./Author";
|
||||||
|
import {GraphNode, TextContent} from "~/types/graph-update";
|
||||||
|
|
||||||
const ClickBox = styled(Box)`
|
const ClickBox = styled(Box)`
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -17,48 +18,36 @@ const ClickBox = styled(Box)`
|
|||||||
|
|
||||||
interface CommentItemProps {
|
interface CommentItemProps {
|
||||||
pending?: boolean;
|
pending?: boolean;
|
||||||
comment: Comment;
|
comment: GraphNode;
|
||||||
contacts: Contacts;
|
contacts: Contacts;
|
||||||
book: string;
|
book: string;
|
||||||
ship: string;
|
ship: string;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
note: NoteId;
|
|
||||||
hideNicknames: boolean;
|
hideNicknames: boolean;
|
||||||
hideAvatars: boolean;
|
hideAvatars: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CommentItem(props: CommentItemProps) {
|
export function CommentItem(props: CommentItemProps) {
|
||||||
const { ship, contacts, book, note, api } = props;
|
const { ship, contacts, book, api } = props;
|
||||||
const [editing, setEditing] = useState<boolean>(false);
|
const [editing, setEditing] = useState<boolean>(false);
|
||||||
const commentPath = Object.keys(props.comment)[0];
|
const commentData = props.comment?.post;
|
||||||
const commentData = props.comment[commentPath];
|
const comment = commentData.contents[0] as TextContent;
|
||||||
const content = commentData.content.split("\n").map((line, i) => {
|
const content = comment.text.split("\n").map((line, i) => {
|
||||||
return (
|
return (
|
||||||
<Text className="mb2" key={i}>
|
<Text mb="2" key={i}>
|
||||||
{line}
|
{line}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const disabled = props.pending || window.ship !== commentData.author.slice(1);
|
const disabled = props.pending || window.ship !== commentData.author;
|
||||||
|
|
||||||
const onUpdate = async ({ comment }) => {
|
|
||||||
await api.publish.updateComment(
|
|
||||||
ship.slice(1),
|
|
||||||
book,
|
|
||||||
note,
|
|
||||||
commentPath,
|
|
||||||
comment
|
|
||||||
);
|
|
||||||
setEditing(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDelete = async () => {
|
const onDelete = async () => {
|
||||||
await api.publish.deleteComment(ship.slice(1), book, note, commentPath);
|
await api.graph.removeNodes(ship, book, [commentData?.index]);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box mb={4} opacity={props.pending ? "60%" : "100%"}>
|
<Box mb={4} opacity={commentData?.pending ? "60%" : "100%"}>
|
||||||
<Row bg="white" my={3}>
|
<Row bg="white" my={3}>
|
||||||
<Author
|
<Author
|
||||||
showImage
|
showImage
|
||||||
@ -68,32 +57,17 @@ export function CommentItem(props: CommentItemProps) {
|
|||||||
hideAvatars={props.hideAvatars}
|
hideAvatars={props.hideAvatars}
|
||||||
hideNicknames={props.hideNicknames}
|
hideNicknames={props.hideNicknames}
|
||||||
>
|
>
|
||||||
{!disabled && !editing && (
|
{!disabled && (
|
||||||
<>
|
<>
|
||||||
<ClickBox color="green" onClick={() => setEditing(true)}>
|
|
||||||
Edit
|
|
||||||
</ClickBox>
|
|
||||||
<ClickBox color="red" onClick={onDelete}>
|
<ClickBox color="red" onClick={onDelete}>
|
||||||
Delete
|
Delete
|
||||||
</ClickBox>
|
</ClickBox>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{editing && (
|
|
||||||
<ClickBox onClick={() => setEditing(false)} color="red">
|
|
||||||
Cancel
|
|
||||||
</ClickBox>
|
|
||||||
)}
|
|
||||||
</Author>
|
</Author>
|
||||||
</Row>
|
</Row>
|
||||||
<Box mb={2}>
|
<Box mb={2}>
|
||||||
{!editing && content}
|
{!editing && content}
|
||||||
{editing && (
|
|
||||||
<CommentInput
|
|
||||||
onSubmit={onUpdate}
|
|
||||||
initial={commentData.content}
|
|
||||||
label="Update"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -8,50 +8,34 @@ import { Contacts } from "~/types/contact-update";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import GlobalApi from "~/logic/api/global";
|
import GlobalApi from "~/logic/api/global";
|
||||||
import { FormikHelpers } from "formik";
|
import { FormikHelpers } from "formik";
|
||||||
|
import {GraphNode, Graph} from "~/types/graph-update";
|
||||||
|
import {createPost} from "~/logic/api/graph";
|
||||||
|
|
||||||
interface CommentsProps {
|
interface CommentsProps {
|
||||||
comments: Comment[];
|
comments: Graph;
|
||||||
book: string;
|
book: string;
|
||||||
noteId: NoteId;
|
note: GraphNode;
|
||||||
note: Note;
|
|
||||||
ship: string;
|
ship: string;
|
||||||
contacts: Contacts;
|
contacts: Contacts;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
numComments: number;
|
|
||||||
enabled: boolean;
|
|
||||||
hideAvatars: boolean;
|
hideAvatars: boolean;
|
||||||
hideNicknames: boolean;
|
hideNicknames: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Comments(props: CommentsProps) {
|
export function Comments(props: CommentsProps) {
|
||||||
const { comments, ship, book, note, api, noteId, numComments } = props;
|
const { comments, ship, book, note, api } = props;
|
||||||
const [pending, setPending] = useState<string[]>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
_.forEach(comments, (comment: Comment) => {
|
|
||||||
const { content } = comment[Object.keys(comment)[0]];
|
|
||||||
setPending((p) => p.filter((p) => p !== content));
|
|
||||||
});
|
|
||||||
}, [numComments]);
|
|
||||||
|
|
||||||
const onSubmit = async (
|
const onSubmit = async (
|
||||||
{ comment },
|
{ comment },
|
||||||
actions: FormikHelpers<{ comment: string }>
|
actions: FormikHelpers<{ comment: string }>
|
||||||
) => {
|
) => {
|
||||||
setPending((p) => [...p, comment]);
|
|
||||||
const action = {
|
|
||||||
"new-comment": {
|
|
||||||
who: ship.slice(1),
|
|
||||||
book: book,
|
|
||||||
note: noteId,
|
|
||||||
body: comment,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
try {
|
try {
|
||||||
await api.publish.publishAction(action);
|
const post = createPost([{ text: comment }], note?.post?.index);
|
||||||
|
await api.graph.addPost(ship, book, post)
|
||||||
actions.resetForm();
|
actions.resetForm();
|
||||||
actions.setStatus({ success: null });
|
actions.setStatus({ success: null });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
actions.setStatus({ error: e.message });
|
actions.setStatus({ error: e.message });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -59,37 +43,14 @@ export function Comments(props: CommentsProps) {
|
|||||||
return (
|
return (
|
||||||
<Col>
|
<Col>
|
||||||
<CommentInput onSubmit={onSubmit} />
|
<CommentInput onSubmit={onSubmit} />
|
||||||
{Array.from(pending).map((com, i) => {
|
{Array.from(comments).reverse().map(([idx, comment]) => (
|
||||||
const da = dateToDa(new Date());
|
|
||||||
const ship = `~${window.ship}`;
|
|
||||||
const comment = {
|
|
||||||
[da]: {
|
|
||||||
author: ship,
|
|
||||||
content: com,
|
|
||||||
"date-created": Math.round(new Date().getTime()),
|
|
||||||
},
|
|
||||||
} as Comment;
|
|
||||||
return (
|
|
||||||
<CommentItem
|
<CommentItem
|
||||||
comment={comment}
|
comment={comment}
|
||||||
key={i}
|
key={idx}
|
||||||
contacts={props.contacts}
|
|
||||||
ship={ship}
|
|
||||||
pending={true}
|
|
||||||
hideNicknames={props.hideNicknames}
|
|
||||||
hideAvatars={props.hideAvatars}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{props.comments.map((com, i) => (
|
|
||||||
<CommentItem
|
|
||||||
comment={com}
|
|
||||||
key={i}
|
|
||||||
contacts={props.contacts}
|
contacts={props.contacts}
|
||||||
api={api}
|
api={api}
|
||||||
book={book}
|
book={book}
|
||||||
ship={ship}
|
ship={ship}
|
||||||
note={note["note-id"]}
|
|
||||||
hideNicknames={props.hideNicknames}
|
hideNicknames={props.hideNicknames}
|
||||||
hideAvatars={props.hideAvatars}
|
hideAvatars={props.hideAvatars}
|
||||||
/>
|
/>
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
import React, { Component } from "react";
|
import React from "react";
|
||||||
import { PostFormSchema, PostForm } from "./NoteForm";
|
import { PostFormSchema, PostForm } from "./NoteForm";
|
||||||
import { Note } from "../../../../types/publish-update";
|
|
||||||
import { FormikHelpers } from "formik";
|
import { FormikHelpers } from "formik";
|
||||||
import GlobalApi from "../../../../api/global";
|
import GlobalApi from "~/logic/api/global";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
|
import { GraphNode, TextContent } from "~/types";
|
||||||
interface EditPostProps {
|
interface EditPostProps {
|
||||||
ship: string;
|
ship: string;
|
||||||
noteId: string;
|
noteId: number;
|
||||||
note: Note;
|
note: GraphNode;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
book: string;
|
book: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EditPost(props: EditPostProps & RouteComponentProps) {
|
export function EditPost(props: EditPostProps & RouteComponentProps) {
|
||||||
const { note, book, noteId, api, ship, history } = props;
|
const { note, book, noteId, api, ship, history } = props;
|
||||||
const body = note.file.slice(note.file.indexOf(";>") + 2);
|
const [title, file] = note.post.contents as TextContent[];
|
||||||
|
const body = file.text.slice(file.text.indexOf(";>") + 2);
|
||||||
const initial: PostFormSchema = {
|
const initial: PostFormSchema = {
|
||||||
title: note.title,
|
title: title.text,
|
||||||
body,
|
body,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,11 +26,11 @@ export function EditPost(props: EditPostProps & RouteComponentProps) {
|
|||||||
actions: FormikHelpers<PostFormSchema>
|
actions: FormikHelpers<PostFormSchema>
|
||||||
) => {
|
) => {
|
||||||
const { title, body } = values;
|
const { title, body } = values;
|
||||||
const host = ship.slice(1);
|
|
||||||
try {
|
try {
|
||||||
await api.publish.editNote(host, book, noteId, title, body);
|
// graph-store does not support editing nodes
|
||||||
history.push(`/~publish/notebook/${ship}/${book}/note/${noteId}`);
|
throw new Error("Unsupported");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
actions.setStatus({ error: "Failed to edit notebook" });
|
actions.setStatus({ error: "Failed to edit notebook" });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -38,7 +39,7 @@ export function EditPost(props: EditPostProps & RouteComponentProps) {
|
|||||||
<PostForm
|
<PostForm
|
||||||
initial={initial}
|
initial={initial}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
submitLabel={`Update ${note.title}`}
|
submitLabel={`Update ${title.text}`}
|
||||||
loadingText="Updating..."
|
loadingText="Updating..."
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -5,21 +5,15 @@ import { Link, RouteComponentProps } from "react-router-dom";
|
|||||||
import { Spinner } from "~/views/components/Spinner";
|
import { Spinner } from "~/views/components/Spinner";
|
||||||
import { Comments } from "./Comments";
|
import { Comments } from "./Comments";
|
||||||
import { NoteNavigation } from "./NoteNavigation";
|
import { NoteNavigation } from "./NoteNavigation";
|
||||||
import {
|
|
||||||
NoteId,
|
|
||||||
Note as INote,
|
|
||||||
Notebook,
|
|
||||||
} from "~/types/publish-update";
|
|
||||||
import { Contacts } from "~/types/contact-update";
|
|
||||||
import GlobalApi from "~/logic/api/global";
|
import GlobalApi from "~/logic/api/global";
|
||||||
import { Author } from "./Author";
|
import { Author } from "./Author";
|
||||||
|
import { Contacts, GraphNode, Graph} from "~/types";
|
||||||
|
|
||||||
interface NoteProps {
|
interface NoteProps {
|
||||||
ship: string;
|
ship: string;
|
||||||
book: string;
|
book: string;
|
||||||
noteId: NoteId;
|
note: GraphNode;
|
||||||
note: INote;
|
notebook: Graph;
|
||||||
notebook: Notebook;
|
|
||||||
contacts: Contacts;
|
contacts: Contacts;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
hideAvatars: boolean;
|
hideAvatars: boolean;
|
||||||
@ -28,31 +22,27 @@ interface NoteProps {
|
|||||||
|
|
||||||
export function Note(props: NoteProps & RouteComponentProps) {
|
export function Note(props: NoteProps & RouteComponentProps) {
|
||||||
const [deleting, setDeleting] = useState(false);
|
const [deleting, setDeleting] = useState(false);
|
||||||
const { notebook, note, contacts, ship, book, noteId, api } = props;
|
const { contacts, ship, notebook, book, api, note } = props;
|
||||||
useEffect(() => {
|
|
||||||
api.publish.fetchNote(ship, book, noteId);
|
|
||||||
}, [ship, book, noteId]);
|
|
||||||
|
|
||||||
const baseUrl = `/~publish/notebook/${props.ship}/${props.book}`;
|
const baseUrl = `/~publish/notebook/ship/${props.ship}/${props.book}`;
|
||||||
|
|
||||||
const deletePost = async () => {
|
const deletePost = async () => {
|
||||||
setDeleting(true);
|
setDeleting(true);
|
||||||
await api.publish.delNote(ship.slice(1), book, noteId);
|
const indices = [note.post.index]
|
||||||
|
await api.graph.removeNodes(ship, book, indices);
|
||||||
props.history.push(baseUrl);
|
props.history.push(baseUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
const comments = note?.comments || [];
|
const comments = note?.children
|
||||||
const file = note?.file;
|
const file = note?.post?.contents[1]?.text || "";
|
||||||
const newfile = file ? file.slice(file.indexOf(";>") + 2) : "";
|
const newfile = file ? file.slice(file.indexOf(";>") + 2) : "";
|
||||||
|
|
||||||
let editPost: JSX.Element | null = null;
|
const noteId = parseInt(note.post.index.split('/')[1], 10);
|
||||||
const editUrl = props.location.pathname + "/edit";
|
|
||||||
if (`~${window.ship}` === note?.author) {
|
let adminLinks: JSX.Element | null = null;
|
||||||
editPost = (
|
if (window.ship === note?.post?.author) {
|
||||||
|
adminLinks = (
|
||||||
<Box display="inline-block">
|
<Box display="inline-block">
|
||||||
<Link to={editUrl}>
|
|
||||||
<Text color="green">Edit</Text>
|
|
||||||
</Link>
|
|
||||||
<Text
|
<Text
|
||||||
className="dib f9 red2 ml2 pointer"
|
className="dib f9 red2 ml2 pointer"
|
||||||
color="red"
|
color="red"
|
||||||
@ -81,16 +71,16 @@ export function Note(props: NoteProps & RouteComponentProps) {
|
|||||||
<Text>{"<- Notebook Index"}</Text>
|
<Text>{"<- Notebook Index"}</Text>
|
||||||
</Link>
|
</Link>
|
||||||
<Col>
|
<Col>
|
||||||
<Text display="block" mb={2}>{note?.title || ""}</Text>
|
<Text display="block" mb={2}>{note?.post?.contents[0]?.text || ""}</Text>
|
||||||
<Box display="flex">
|
<Box display="flex">
|
||||||
<Author
|
<Author
|
||||||
hideNicknames={props.hideNicknames}
|
hideNicknames={props.hideNicknames}
|
||||||
hideAvatars={props.hideAvatars}
|
hideAvatars={props.hideAvatars}
|
||||||
ship={note?.author}
|
ship={note?.post?.author}
|
||||||
contacts={contacts}
|
contacts={contacts}
|
||||||
date={note?.["date-created"]}
|
date={note?.post?.["time-sent"]}
|
||||||
/>
|
/>
|
||||||
<Text ml={2}>{editPost}</Text>
|
<Text ml={2}>{adminLinks}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</Col>
|
</Col>
|
||||||
<Box color="black" className="md" style={{ overflowWrap: "break-word" }}>
|
<Box color="black" className="md" style={{ overflowWrap: "break-word" }}>
|
||||||
@ -98,25 +88,20 @@ export function Note(props: NoteProps & RouteComponentProps) {
|
|||||||
</Box>
|
</Box>
|
||||||
<NoteNavigation
|
<NoteNavigation
|
||||||
notebook={notebook}
|
notebook={notebook}
|
||||||
prevId={note?.["prev-note"] || undefined}
|
noteId={noteId}
|
||||||
nextId={note?.["next-note"] || undefined}
|
|
||||||
ship={props.ship}
|
ship={props.ship}
|
||||||
book={props.book}
|
book={props.book}
|
||||||
/>
|
/>
|
||||||
{notebook.comments && (
|
|
||||||
<Comments
|
<Comments
|
||||||
ship={ship}
|
ship={ship}
|
||||||
book={props.book}
|
book={props.book}
|
||||||
noteId={props.noteId}
|
|
||||||
note={props.note}
|
note={props.note}
|
||||||
comments={comments}
|
comments={comments}
|
||||||
numComments={props.note["num-comments"]}
|
|
||||||
contacts={props.contacts}
|
contacts={props.contacts}
|
||||||
api={props.api}
|
api={props.api}
|
||||||
hideNicknames={props.hideNicknames}
|
hideNicknames={props.hideNicknames}
|
||||||
hideAvatars={props.hideAvatars}
|
hideAvatars={props.hideAvatars}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
<Spinner
|
<Spinner
|
||||||
text="Deleting post..."
|
text="Deleting post..."
|
||||||
awaiting={deleting}
|
awaiting={deleting}
|
||||||
|
@ -2,7 +2,7 @@ import React, { Component } from "react";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Box } from "@tlon/indigo-react";
|
import { Box } from "@tlon/indigo-react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Notebook } from "../../../../types/publish-update";
|
import {Graph, GraphNode} from "~/types";
|
||||||
|
|
||||||
function NavigationItem(props: {
|
function NavigationItem(props: {
|
||||||
url: string;
|
url: string;
|
||||||
@ -10,7 +10,7 @@ function NavigationItem(props: {
|
|||||||
date: number;
|
date: number;
|
||||||
prev?: boolean;
|
prev?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const date = moment(date).fromNow();
|
const date = moment(props.date).fromNow();
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
justifySelf={props.prev ? "start" : "end"}
|
justifySelf={props.prev ? "start" : "end"}
|
||||||
@ -30,12 +30,19 @@ function NavigationItem(props: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAdjacentId(graph: Graph, child: number, backwards = false): number | null {
|
||||||
|
const children = Array.from(graph);
|
||||||
|
const i = children.findIndex(([index]) => index === child);
|
||||||
|
const target = children[backwards ? i-1 : i+1];
|
||||||
|
return target?.[0] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
interface NoteNavigationProps {
|
interface NoteNavigationProps {
|
||||||
book: string;
|
book: string;
|
||||||
nextId?: string;
|
noteId: number;
|
||||||
prevId?: string;
|
|
||||||
ship: string;
|
ship: string;
|
||||||
notebook: Notebook;
|
notebook: Graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NoteNavigation(props: NoteNavigationProps) {
|
export function NoteNavigation(props: NoteNavigationProps) {
|
||||||
@ -43,32 +50,39 @@ export function NoteNavigation(props: NoteNavigationProps) {
|
|||||||
let prevComponent = <Box />;
|
let prevComponent = <Box />;
|
||||||
let nextUrl = "";
|
let nextUrl = "";
|
||||||
let prevUrl = "";
|
let prevUrl = "";
|
||||||
const { nextId, prevId, notebook } = props;
|
const { noteId, notebook } = props;
|
||||||
const next =
|
if(!notebook) {
|
||||||
nextId && nextId in notebook?.notes ? notebook?.notes[nextId] : null;
|
return null;
|
||||||
|
}
|
||||||
|
const nextId = getAdjacentId(notebook, noteId);
|
||||||
|
const prevId = getAdjacentId(notebook, noteId, true);
|
||||||
|
const next = nextId && notebook.get(nextId);
|
||||||
|
const prev = prevId && notebook.get(prevId);
|
||||||
|
|
||||||
const prev =
|
|
||||||
prevId && prevId in notebook?.notes ? notebook?.notes[prevId] : null;
|
|
||||||
if (!next && !prev) {
|
if (!next && !prev) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next) {
|
if (next) {
|
||||||
nextUrl = `/~publish/notebook/${props.ship}/${props.book}/note/${props.nextId}`;
|
nextUrl = `/~publish/notebook/ship/${props.ship}/${props.book}/note/${nextId}`;
|
||||||
|
const title = next.post.contents[0]?.text;
|
||||||
|
const date = next.post['time-sent'];
|
||||||
nextComponent = (
|
nextComponent = (
|
||||||
<NavigationItem
|
<NavigationItem
|
||||||
title={next.title}
|
title={title}
|
||||||
date={next["date-created"]}
|
date={date}
|
||||||
url={nextUrl}
|
url={nextUrl}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prevUrl = `/~publish/notebook/${props.ship}/${props.book}/note/${props.prevId}`;
|
prevUrl = `/~publish/notebook/ship/${props.ship}/${props.book}/note/${prevId}`;
|
||||||
|
const title = prev.post.contents[0]?.text;
|
||||||
|
const date = prev.post['time-sent'];
|
||||||
prevComponent = (
|
prevComponent = (
|
||||||
<NavigationItem
|
<NavigationItem
|
||||||
title={prev.title}
|
title={title}
|
||||||
date={prev["date-created"]}
|
date={date}
|
||||||
url={prevUrl}
|
url={prevUrl}
|
||||||
prev
|
prev
|
||||||
/>
|
/>
|
||||||
|
@ -1,27 +1,29 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Route, Switch } from "react-router-dom";
|
import { Route, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import { NoteId, Note as INote, Notebook } from "~/types/publish-update";
|
|
||||||
import { Contacts } from "~/types/contact-update";
|
|
||||||
import GlobalApi from "~/logic/api/global";
|
import GlobalApi from "~/logic/api/global";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import Note from "./Note";
|
import Note from "./Note";
|
||||||
import { EditPost } from "./EditPost";
|
import { EditPost } from "./EditPost";
|
||||||
|
|
||||||
|
import { GraphNode, Graph, Contacts } from "~/types";
|
||||||
|
|
||||||
interface NoteRoutesProps {
|
interface NoteRoutesProps {
|
||||||
ship: string;
|
ship: string;
|
||||||
book: string;
|
book: string;
|
||||||
noteId: NoteId;
|
note: GraphNode;
|
||||||
note: INote;
|
noteId: number;
|
||||||
notebook: Notebook;
|
notebook: Graph;
|
||||||
contacts: Contacts;
|
contacts: Contacts;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
|
hideAvatars: boolean;
|
||||||
|
hideNicknames: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NoteRoutes(props: NoteRoutesProps & RouteComponentProps) {
|
export function NoteRoutes(props: NoteRoutesProps & RouteComponentProps) {
|
||||||
const { ship, book, noteId } = props;
|
const { ship, book, noteId } = props;
|
||||||
|
|
||||||
const baseUrl = `/~publish/notebook/${ship}/${book}/note/${noteId}`;
|
const baseUrl = `/~publish/notebook/ship/${ship}/${book}/note/${noteId}`;
|
||||||
|
|
||||||
const relativePath = (path: string) => `${baseUrl}${path}`;
|
const relativePath = (path: string) => `${baseUrl}${path}`;
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user