Dwayne Harris
5 years ago
7 changed files with 281 additions and 14 deletions
-
2src/actions/groups.ts
-
146src/actions/posts.ts
-
59src/components/composer.tsx
-
14src/components/pages/view-user.tsx
-
28src/types/entities.ts
-
4src/types/store.ts
-
42src/utils/normalization.ts
@ -0,0 +1,146 @@ |
|||
import { Action } from 'redux' |
|||
|
|||
import { apiFetch } from 'src/api' |
|||
import { setEntities } from 'src/actions/entities' |
|||
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 } from 'src/types' |
|||
|
|||
export interface AppendPostsAction extends Action { |
|||
type: 'POSTS_APPEND_POSTS' |
|||
payload: { |
|||
items: string[] |
|||
continuation?: string |
|||
} |
|||
} |
|||
|
|||
export interface ClearPostsAction extends Action { |
|||
type: 'POSTS_CLEAR_POSTS' |
|||
} |
|||
|
|||
export type PostsActions = AppendPostsAction | ClearPostsAction |
|||
|
|||
export const appendPosts = (posts: string[], continuation?: string): AppendPostsAction => ({ |
|||
type: 'POSTS_APPEND_POSTS', |
|||
payload: { |
|||
items: posts, |
|||
continuation, |
|||
}, |
|||
}) |
|||
|
|||
export const clearPosts = (): ClearPostsAction => ({ |
|||
type: 'POSTS_CLEAR_POSTS', |
|||
}) |
|||
|
|||
interface CreatePostResponse { |
|||
id: string |
|||
} |
|||
|
|||
interface CreatePostOptions { |
|||
visible: boolean |
|||
text?: string |
|||
cover?: string |
|||
data?: object |
|||
parent?: string |
|||
} |
|||
|
|||
export const createPost = (options: CreatePostOptions): AppThunkAction<string> => { |
|||
return async dispatch => { |
|||
const { visible, text, cover, data, parent } = options |
|||
dispatch(startRequest(RequestKey.CreatePost)) |
|||
|
|||
try { |
|||
const post = await apiFetch<CreatePostResponse>({ |
|||
path: `/api/post`, |
|||
method: 'post', |
|||
body: { |
|||
visible, |
|||
text, |
|||
cover, |
|||
data, |
|||
parent, |
|||
}, |
|||
}) |
|||
|
|||
dispatch(finishRequest(RequestKey.CreatePost, true)) |
|||
return post.id |
|||
} catch (err) { |
|||
dispatch(finishRequest(RequestKey.CreatePost, false)) |
|||
throw err |
|||
} |
|||
} |
|||
} |
|||
|
|||
export const fetchPost = (id: string): AppThunkAction => { |
|||
return async dispatch => { |
|||
dispatch(startRequest(RequestKey.FetchPost)) |
|||
|
|||
try { |
|||
const post = await apiFetch<Entity>({ |
|||
path: `/api/post/${id}` |
|||
}) |
|||
|
|||
const posts = normalize([post], EntityType.Post) |
|||
|
|||
dispatch(setEntities(posts.entities)) |
|||
dispatch(finishRequest(RequestKey.FetchPost, true)) |
|||
} catch (err) { |
|||
dispatch(finishRequest(RequestKey.FetchPost, false)) |
|||
throw err |
|||
} |
|||
} |
|||
} |
|||
|
|||
interface TimelineResponse { |
|||
posts: Entity[] |
|||
continuation?: string |
|||
} |
|||
|
|||
export const fetchTimeline = (continuation?: string): AppThunkAction => async dispatch => { |
|||
dispatch(startRequest(RequestKey.FetchTimeline)) |
|||
|
|||
try { |
|||
const response = await apiFetch<TimelineResponse>({ |
|||
path: `/api/timeline?${objectToQuerystring({ continuation })}`, |
|||
}) |
|||
|
|||
const posts = normalize(response.posts, EntityType.Group) |
|||
|
|||
dispatch(setEntities(posts.entities)) |
|||
dispatch(appendPosts(posts.keys, response.continuation)) |
|||
dispatch(finishRequest(RequestKey.FetchTimeline, true)) |
|||
} catch (err) { |
|||
dispatch(finishRequest(RequestKey.FetchTimeline, false)) |
|||
throw err |
|||
} |
|||
} |
|||
|
|||
interface UserPostsResponse { |
|||
user: User |
|||
posts: Post[] |
|||
continuation?: string |
|||
} |
|||
|
|||
export const fetchUserPosts = (id: string, continuation?: string): AppThunkAction => async dispatch => { |
|||
dispatch(startRequest(RequestKey.FetchUserPosts)) |
|||
|
|||
try { |
|||
const response = await apiFetch<UserPostsResponse>({ |
|||
path: `/api/user/${id}/posts?${objectToQuerystring({ continuation })}`, |
|||
}) |
|||
|
|||
const posts = normalize(response.posts.map(p => ({ |
|||
...p, |
|||
user: response.user, |
|||
})), EntityType.Post) |
|||
|
|||
dispatch(setEntities(posts.entities)) |
|||
dispatch(appendPosts(posts.keys, response.continuation)) |
|||
dispatch(finishRequest(RequestKey.FetchUserPosts, true)) |
|||
} catch (err) { |
|||
dispatch(finishRequest(RequestKey.FetchUserPosts, false)) |
|||
throw err |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue