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