[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

239 lines
6.8 KiB

import { Action } from 'redux'
import { apiFetch } from 'src/api'
import { setEntity, 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 } from 'src/types'
export interface AppendGroupsAction extends Action {
type: 'GROUPS_APPEND_GROUPS'
payload: {
items: string[]
continuation?: string
}
}
export interface ClearGroupsAction extends Action {
type: 'GROUPS_CLEAR_GROUPS'
}
export interface AppendLogsAction extends Action {
type: 'GROUPS_APPEND_LOGS'
payload: {
items: string[]
continuation?: string
}
}
export interface ClearLogsAction extends Action {
type: 'GROUPS_CLEAR_LOGS'
}
export interface AppendInvitationsAction extends Action {
type: 'GROUPS_APPEND_INVITATIONS'
payload: {
items: string[]
continuation?: string
}
}
export interface ClearInvitationsAction extends Action {
type: 'GROUPS_CLEAR_INVITATIONS'
}
export type GroupsActions = AppendGroupsAction | ClearGroupsAction | AppendLogsAction | ClearLogsAction | AppendInvitationsAction | ClearInvitationsAction
export const appendGroups = (groups: string[], continuation?: string): AppendGroupsAction => ({
type: 'GROUPS_APPEND_GROUPS',
payload: {
items: groups,
continuation,
},
})
export const clearGroups = (): ClearGroupsAction => ({
type: 'GROUPS_CLEAR_GROUPS',
})
export const appendLogs = (logs: string[], continuation?: string): AppendLogsAction => ({
type: 'GROUPS_APPEND_LOGS',
payload: {
items: logs,
continuation,
},
})
export const clearLogs = (): ClearLogsAction => ({
type: 'GROUPS_CLEAR_LOGS',
})
export const appendInvitations = (invitations: string[], continuation?: string): AppendInvitationsAction => ({
type: 'GROUPS_APPEND_INVITATIONS',
payload: {
items: invitations,
continuation,
},
})
export const clearInvitations = (): ClearInvitationsAction => ({
type: 'GROUPS_CLEAR_INVITATIONS',
})
export const fetchGroup = (id: string): AppThunkAction => {
return async dispatch => {
dispatch(startRequest(RequestKey.FetchGroup))
try {
const group = await apiFetch<Entity>({
path: `/api/group/${id}`
})
const groups = normalize([group], EntityType.Group)
dispatch(setEntities(groups.entities))
dispatch(finishRequest(RequestKey.FetchGroup, true))
} catch (err) {
dispatch(finishRequest(RequestKey.FetchGroup, false))
throw err
}
}
}
interface GroupsResponse {
groups: Entity[]
continuation?: string
}
export const fetchGroups = (sort?: string, continuation?: string): AppThunkAction => async dispatch => {
dispatch(startRequest(RequestKey.FetchGroups))
try {
const response = await apiFetch<GroupsResponse>({
path: `/api/groups?${objectToQuerystring({ sort, continuation })}`,
})
const groups = normalize(response.groups, EntityType.Group)
dispatch(setEntities(groups.entities))
dispatch(appendGroups(groups.keys, response.continuation))
dispatch(finishRequest(RequestKey.FetchGroups, true))
} catch (err) {
dispatch(finishRequest(RequestKey.FetchGroups, false))
throw err
}
}
interface GroupMembersResponse {
members: User[]
continuation?: string
}
export const fetchGroupMembers = (id: string, type?: string, continuation?: string): AppThunkAction => async dispatch => {
dispatch(startRequest(RequestKey.FetchGroupMembers))
try {
const response = await apiFetch<GroupMembersResponse>({
path: `/api/group/${id}/members?${objectToQuerystring({ type, continuation })}`,
})
const users = normalize(response.members, EntityType.User)
dispatch(setEntities(users.entities))
dispatch(finishRequest(RequestKey.FetchGroupMembers, true))
} catch (err) {
dispatch(finishRequest(RequestKey.FetchGroupMembers, false))
throw err
}
}
interface GroupLogsResponse {
logs: Entity[]
continuation?: string
}
export const fetchLogs = (id: string, continuation?: string): AppThunkAction => async dispatch => {
dispatch(startRequest(RequestKey.FetchGroupLogs))
try {
const response = await apiFetch<GroupLogsResponse>({
path: `/api/group/${id}/logs?${objectToQuerystring({ continuation })}`,
})
const users = normalize(response.logs, EntityType.Log)
dispatch(setEntities(users.entities))
dispatch(appendLogs(users.keys, response.continuation))
dispatch(finishRequest(RequestKey.FetchGroupLogs, true))
} catch (err) {
dispatch(finishRequest(RequestKey.FetchGroupLogs, false))
throw err
}
}
interface CreateInvitationResponse {
code: string
}
export const createInvitation = (id: string, expiration?: number, limit?: number): AppThunkAction<string> => async dispatch => {
dispatch(startRequest(RequestKey.CreateInvitation))
try {
const response = await apiFetch<CreateInvitationResponse>({
path: `/api/group/${id}/invitation`,
method: 'post',
body: {
expiration,
limit,
}
})
dispatch(finishRequest(RequestKey.CreateInvitation, true))
return response.code
} catch (err) {
dispatch(finishRequest(RequestKey.CreateInvitation, false))
throw err
}
}
interface InvitationsResponse {
invitations: Entity[]
continuation?: string
}
export const fetchInvitations = (id: string): AppThunkAction => async dispatch => {
dispatch(startRequest(RequestKey.FetchInvitations))
try {
const response = await apiFetch<InvitationsResponse>({
path: `/api/group/${id}/invitations`,
})
const invitations = normalize(response.invitations, EntityType.Invitation)
dispatch(setEntities(invitations.entities))
dispatch(appendInvitations(invitations.keys, response.continuation))
dispatch(finishRequest(RequestKey.FetchInvitations, true))
} catch (err) {
dispatch(finishRequest(RequestKey.FetchInvitations, false))
throw err
}
}
export const updateGroup = (id: string, updates: object): AppThunkAction => async dispatch => {
dispatch(startRequest(RequestKey.UpdateGroup))
try {
await apiFetch({
path: `/api/group/${id}`,
method: 'put',
body: updates,
})
dispatch(finishRequest(RequestKey.UpdateGroup, true))
} catch (err) {
dispatch(finishRequest(RequestKey.UpdateGroup, false))
throw err
}
}