From 2e9c8beae98f7c8248865a623eaa81e69d8a46b7 Mon Sep 17 00:00:00 2001 From: Dwayne Harris Date: Sun, 3 Nov 2019 16:57:30 -0500 Subject: [PATCH] WIP --- src/actions/posts.ts | 41 ++++++++++++-- src/components/app.tsx | 4 ++ src/components/composer.tsx | 27 +++++++-- src/components/pages/home.tsx | 12 +++- src/components/pages/view-post.tsx | 90 ++++++++++++++++++++++++++++++ src/components/post-list.tsx | 30 +++++++--- src/components/post.tsx | 89 +++++++++++++++++++++-------- src/selectors/posts.ts | 14 ++--- src/styles/app.scss | 20 ++++++- src/types/entities.ts | 12 ++-- src/utils/normalization.ts | 8 --- 11 files changed, 284 insertions(+), 63 deletions(-) create mode 100644 src/components/pages/view-post.tsx diff --git a/src/actions/posts.ts b/src/actions/posts.ts index 94d757a..f65817a 100644 --- a/src/actions/posts.ts +++ b/src/actions/posts.ts @@ -7,7 +7,7 @@ import { startRequest, finishRequest } from 'src/actions/requests' import { objectToQuerystring } from 'src/utils' import { normalize } from 'src/utils/normalization' -import { AppThunkAction, Entity, RequestKey, EntityType, User, Post, EntityListKey } from 'src/types' +import { AppThunkAction, Entity, RequestKey, EntityType, User, Post, Attachment, EntityListKey } from 'src/types' interface CreatePostResponse { id: string @@ -17,13 +17,14 @@ interface CreatePostOptions { visible: boolean text?: string cover?: string + attachments: Attachment[] data?: object parent?: string } export const createPost = (options: CreatePostOptions): AppThunkAction => { return async dispatch => { - const { visible, text, cover, data, parent } = options + const { visible, text, cover, attachments, data, parent } = options dispatch(startRequest(RequestKey.CreatePost)) try { @@ -34,6 +35,7 @@ export const createPost = (options: CreatePostOptions): AppThunkAction = visible, text, cover, + attachments, data, parent, }, @@ -48,18 +50,49 @@ export const createPost = (options: CreatePostOptions): AppThunkAction = } } +interface FetchPostResponse { + post: Post, + parents: Post[], + children: Post[], + users: User[], +} + export const fetchPost = (id: string): AppThunkAction => { return async dispatch => { dispatch(startRequest(RequestKey.FetchPost)) try { - const post = await apiFetch({ + const response = await apiFetch({ path: `/api/post/${id}` }) - const posts = normalize([post], EntityType.Post) + const parents = normalize(response.parents.map(p => ({ + ...p, + user: response.users.find(u => u.id === p.userId), + userId: undefined, + })), EntityType.Post) + + dispatch(setEntities(parents.entities)) + dispatch(listSet(`post:${id}:parents`, parents.keys)) + + const children = normalize(response.children.map(p => ({ + ...p, + user: response.users.find(u => u.id === p.userId), + userId: undefined, + })), EntityType.Post) + dispatch(setEntities(children.entities)) + dispatch(listSet(`post:${id}:children`, children.keys)) + + const post: Entity = { + ...response.post, + user: response.users.find(u => u.id === response.post.userId), + userId: undefined, + } + + const posts = normalize([post], EntityType.Post) dispatch(setEntities(posts.entities)) + dispatch(finishRequest(RequestKey.FetchPost, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchPost, false)) diff --git a/src/components/app.tsx b/src/components/app.tsx index ad188d0..a53a8ea 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -32,6 +32,7 @@ import RegisterGroup from './pages/register-group' import Self from './pages/self' import ViewApp from './pages/view-app' import ViewGroup from './pages/view-group' +import ViewPost from './pages/view-post' import ViewUser from './pages/view-user' import '../styles/app.scss' @@ -101,6 +102,9 @@ const App: FC = () => { + + + diff --git a/src/components/composer.tsx b/src/components/composer.tsx index f7d5111..462c3ac 100644 --- a/src/components/composer.tsx +++ b/src/components/composer.tsx @@ -6,16 +6,21 @@ import { getOrigin } from 'src/utils' import { useConfig, useDeepCompareEffect } from 'src/hooks' import { fetchInstallations, setSelectedInstallation, setHeight as setComposerHeight, setError as setComposerError } from 'src/actions/composer' import { showNotification } from 'src/actions/notifications' -import { createPost, fetchTimeline } from 'src/actions/posts' +import { createPost } from 'src/actions/posts' import { getInstallations, getSelectedInstallation, getError, getHeight as getComposerHeight } from 'src/selectors/composer' -import { AppState, Installation, ClassDictionary, AppThunkDispatch, NotificationType } from 'src/types' +import { AppState, Installation, ClassDictionary, AppThunkDispatch, NotificationType, Post } from 'src/types' import { IncomingMessageData, OutgoingMessageData } from 'src/types/communicator' interface LimiterCollection { [key: string]: number } -const Composer: FC = () => { +interface Props { + parent?: Post + onPost?: () => void +} + +const Composer: FC = ({ parent, onPost }) => { const installations = useSelector(getInstallations) const installation = useSelector(getSelectedInstallation) const height = useSelector(getComposerHeight) @@ -96,6 +101,13 @@ const Composer: FC = () => { content: { installationId: installation.id, settings: installation.settings, + parent: parent ? { + text: parent.text, + cover: parent.cover, + attachments: parent.attachments, + data: parent.data, + created: parent.created, + } : undefined, }, }) @@ -106,6 +118,7 @@ const Composer: FC = () => { postMessage({ name: data.name, + content: {}, }) break @@ -116,7 +129,9 @@ const Composer: FC = () => { visible: content.visible, text: content.text, cover: content.cover, + attachments: content.attachments, data: content.data, + parent: parent ? parent.id : undefined, })) postMessage({ @@ -127,7 +142,7 @@ const Composer: FC = () => { }) dispatch(showNotification(NotificationType.Success, `Posted!`)) - dispatch(fetchTimeline()) + if (onPost) onPost() } catch (err) { postMessage({ name, @@ -147,7 +162,7 @@ const Composer: FC = () => { return () => { window.removeEventListener('message', listener, false) } - }, [installation, error]) + }, [installation, parent, error]) const handleClick = (id: string) => { if (installation && installation.id === id) { @@ -162,7 +177,7 @@ const Composer: FC = () => {
{showComposer && -