mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 21:06:42 +07:00
flow get more
This commit is contained in:
parent
f440a5f4c3
commit
971578bb21
11 changed files with 281 additions and 159 deletions
|
@ -1,29 +1,43 @@
|
|||
import { FLOW_ACTIONS } from './constants';
|
||||
import { IFlowState } from './reducer';
|
||||
import { INode } from '../types';
|
||||
import { FLOW_ACTIONS } from "./constants";
|
||||
import { IFlowState } from "./reducer";
|
||||
import { INode } from "../types";
|
||||
|
||||
export const flowSetNodes = (nodes: IFlowState['nodes']) => ({
|
||||
export const flowSetNodes = (nodes: IFlowState["nodes"]) => ({
|
||||
nodes,
|
||||
type: FLOW_ACTIONS.SET_NODES,
|
||||
type: FLOW_ACTIONS.SET_NODES
|
||||
});
|
||||
|
||||
export const flowSetHeroes = (heroes: IFlowState['heroes']) => ({
|
||||
export const flowSetHeroes = (heroes: IFlowState["heroes"]) => ({
|
||||
heroes,
|
||||
type: FLOW_ACTIONS.SET_HEROES,
|
||||
type: FLOW_ACTIONS.SET_HEROES
|
||||
});
|
||||
|
||||
export const flowSetRecent = (recent: IFlowState['recent']) => ({
|
||||
export const flowSetRecent = (recent: IFlowState["recent"]) => ({
|
||||
recent,
|
||||
type: FLOW_ACTIONS.SET_RECENT,
|
||||
type: FLOW_ACTIONS.SET_RECENT
|
||||
});
|
||||
|
||||
export const flowSetUpdated = (updated: IFlowState['updated']) => ({
|
||||
export const flowSetUpdated = (updated: IFlowState["updated"]) => ({
|
||||
updated,
|
||||
type: FLOW_ACTIONS.SET_UPDATED,
|
||||
type: FLOW_ACTIONS.SET_UPDATED
|
||||
});
|
||||
|
||||
export const flowSetCellView = (id: INode['id'], flow: INode['flow']) => ({
|
||||
export const flowSetCellView = (id: INode["id"], flow: INode["flow"]) => ({
|
||||
type: FLOW_ACTIONS.SET_CELL_VIEW,
|
||||
id,
|
||||
flow,
|
||||
flow
|
||||
});
|
||||
|
||||
export const flowSetRange = (range: IFlowState["range"]) => ({
|
||||
range,
|
||||
type: FLOW_ACTIONS.SET_RANGE
|
||||
});
|
||||
|
||||
export const flowGetMore = () => ({
|
||||
type: FLOW_ACTIONS.GET_MORE
|
||||
});
|
||||
|
||||
export const flowSetFlow = (data: Partial<IFlowState>) => ({
|
||||
type: FLOW_ACTIONS.SET_FLOW,
|
||||
data
|
||||
});
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import { api, configWithToken, resultMiddleware, errorMiddleware } from '~/utils/api';
|
||||
import { INode, IResultWithStatus } from '../types';
|
||||
import { API } from '~/constants/api';
|
||||
import { flowSetCellView } from '~/redux/flow/actions';
|
||||
import {
|
||||
api,
|
||||
configWithToken,
|
||||
resultMiddleware,
|
||||
errorMiddleware
|
||||
} from "~/utils/api";
|
||||
import { INode, IResultWithStatus } from "../types";
|
||||
import { API } from "~/constants/api";
|
||||
import { flowSetCellView } from "~/redux/flow/actions";
|
||||
|
||||
export const postNode = ({
|
||||
access,
|
||||
node,
|
||||
node
|
||||
}: {
|
||||
access: string;
|
||||
node: INode;
|
||||
|
@ -15,24 +20,24 @@ export const postNode = ({
|
|||
.then(resultMiddleware)
|
||||
.catch(errorMiddleware);
|
||||
|
||||
export const getNodes = ({
|
||||
skip = 0,
|
||||
}: {
|
||||
skip: number;
|
||||
}): Promise<IResultWithStatus<{ nodes: INode[] }>> =>
|
||||
api
|
||||
.get(API.NODE.GET, { params: { skip } })
|
||||
.then(resultMiddleware)
|
||||
.catch(errorMiddleware);
|
||||
// export const getNodes = ({
|
||||
// from = null
|
||||
// }: {
|
||||
// from: string;
|
||||
// }): Promise<IResultWithStatus<{ nodes: INode[] }>> =>
|
||||
// api
|
||||
// .get(API.NODE.GET, { params: { from } })
|
||||
// .then(resultMiddleware)
|
||||
// .catch(errorMiddleware);
|
||||
|
||||
export const postCellView = ({
|
||||
id,
|
||||
flow,
|
||||
access,
|
||||
access
|
||||
}: ReturnType<typeof flowSetCellView> & { access: string }): Promise<
|
||||
IResultWithStatus<{ is_liked: INode['is_liked'] }>
|
||||
IResultWithStatus<{ is_liked: INode["is_liked"] }>
|
||||
> =>
|
||||
api
|
||||
.post(API.NODE.SET_CELL_VIEW(id), { flow }, configWithToken(access))
|
||||
.then(resultMiddleware)
|
||||
.catch(errorMiddleware);
|
||||
.catch(errorMiddleware);
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
const prefix = 'FLOW.';
|
||||
const prefix = "FLOW.";
|
||||
|
||||
export const FLOW_ACTIONS = {
|
||||
GET_FLOW: `${prefix}GET_FLOW`,
|
||||
SET_FLOW: `${prefix}SET_FLOW`,
|
||||
SET_NODES: `${prefix}SET_NODES`,
|
||||
SET_HEROES: `${prefix}SET_HEROES`,
|
||||
SET_RECENT: `${prefix}SET_RECENT`,
|
||||
SET_UPDATED: `${prefix}SET_UPDATED`,
|
||||
SET_RANGE: `${prefix}SET_RANGE`,
|
||||
SET_CELL_VIEW: `${prefix}SET_CELL_VIEW`,
|
||||
GET_MORE: `${prefix}GET_MORE`
|
||||
};
|
||||
|
|
|
@ -1,23 +1,53 @@
|
|||
import assocPath from 'ramda/es/assocPath';
|
||||
import { FLOW_ACTIONS } from './constants';
|
||||
import { flowSetNodes, flowSetHeroes, flowSetRecent, flowSetUpdated } from './actions';
|
||||
import { IFlowState } from './reducer';
|
||||
import assocPath from "ramda/es/assocPath";
|
||||
import { FLOW_ACTIONS } from "./constants";
|
||||
import {
|
||||
flowSetNodes,
|
||||
flowSetHeroes,
|
||||
flowSetRecent,
|
||||
flowSetUpdated,
|
||||
flowSetRange,
|
||||
flowSetFlow
|
||||
} from "./actions";
|
||||
import { IFlowState } from "./reducer";
|
||||
|
||||
const setNodes = (state: IFlowState, { nodes }: ReturnType<typeof flowSetNodes>) =>
|
||||
assocPath(['nodes'], nodes, state);
|
||||
const setNodes = (
|
||||
state: IFlowState,
|
||||
{ nodes }: ReturnType<typeof flowSetNodes>
|
||||
) => assocPath(["nodes"], nodes, state);
|
||||
|
||||
const setHeroes = (state: IFlowState, { heroes }: ReturnType<typeof flowSetHeroes>) =>
|
||||
assocPath(['heroes'], heroes, state);
|
||||
const setHeroes = (
|
||||
state: IFlowState,
|
||||
{ heroes }: ReturnType<typeof flowSetHeroes>
|
||||
) => assocPath(["heroes"], heroes, state);
|
||||
|
||||
const setRecent = (state: IFlowState, { recent }: ReturnType<typeof flowSetRecent>) =>
|
||||
assocPath(['recent'], recent, state);
|
||||
const setRecent = (
|
||||
state: IFlowState,
|
||||
{ recent }: ReturnType<typeof flowSetRecent>
|
||||
) => assocPath(["recent"], recent, state);
|
||||
|
||||
const setUpdated = (state: IFlowState, { updated }: ReturnType<typeof flowSetUpdated>) =>
|
||||
assocPath(['updated'], updated, state);
|
||||
const setUpdated = (
|
||||
state: IFlowState,
|
||||
{ updated }: ReturnType<typeof flowSetUpdated>
|
||||
) => assocPath(["updated"], updated, state);
|
||||
|
||||
const setRange = (
|
||||
state: IFlowState,
|
||||
{ range }: ReturnType<typeof flowSetRange>
|
||||
) => assocPath(["range"], range, state);
|
||||
|
||||
const setFlow = (
|
||||
state: IFlowState,
|
||||
{ data }: ReturnType<typeof flowSetFlow>
|
||||
): IFlowState => ({
|
||||
...state,
|
||||
...data
|
||||
});
|
||||
|
||||
export const FLOW_HANDLERS = {
|
||||
[FLOW_ACTIONS.SET_NODES]: setNodes,
|
||||
[FLOW_ACTIONS.SET_HEROES]: setHeroes,
|
||||
[FLOW_ACTIONS.SET_RECENT]: setRecent,
|
||||
[FLOW_ACTIONS.SET_UPDATED]: setUpdated,
|
||||
[FLOW_ACTIONS.SET_RANGE]: setRange,
|
||||
[FLOW_ACTIONS.SET_FLOW]: setFlow
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createReducer } from '~/utils/reducer';
|
||||
import { INode, IError } from '../types';
|
||||
import { FLOW_HANDLERS } from './handlers';
|
||||
import { createReducer } from "~/utils/reducer";
|
||||
import { INode, IError } from "../types";
|
||||
import { FLOW_HANDLERS } from "./handlers";
|
||||
|
||||
export type IFlowState = Readonly<{
|
||||
is_loading: boolean;
|
||||
|
@ -8,6 +8,7 @@ export type IFlowState = Readonly<{
|
|||
heroes: Partial<INode>[];
|
||||
recent: Partial<INode>[];
|
||||
updated: Partial<INode>[];
|
||||
range: [string, string];
|
||||
error: IError;
|
||||
}>;
|
||||
|
||||
|
@ -16,8 +17,9 @@ const INITIAL_STATE: IFlowState = {
|
|||
heroes: [],
|
||||
recent: [],
|
||||
updated: [],
|
||||
range: [null, null], // drop it, we use realtime range calc
|
||||
is_loading: false,
|
||||
error: null,
|
||||
error: null
|
||||
};
|
||||
|
||||
export default createReducer(INITIAL_STATE, FLOW_HANDLERS);
|
||||
|
|
|
@ -1,56 +1,78 @@
|
|||
import { takeLatest, call, put, select } from 'redux-saga/effects';
|
||||
import { REHYDRATE } from 'redux-persist';
|
||||
import { FLOW_ACTIONS } from './constants';
|
||||
import { getNodes } from '../node/api';
|
||||
import {
|
||||
takeLatest,
|
||||
call,
|
||||
put,
|
||||
select,
|
||||
takeLeading,
|
||||
delay
|
||||
} from "redux-saga/effects";
|
||||
import { REHYDRATE } from "redux-persist";
|
||||
import { FLOW_ACTIONS } from "./constants";
|
||||
import { getNodes } from "../node/api";
|
||||
import {
|
||||
flowSetNodes,
|
||||
flowSetCellView,
|
||||
flowSetHeroes,
|
||||
flowSetRecent,
|
||||
flowSetUpdated,
|
||||
} from './actions';
|
||||
import { IResultWithStatus, INode } from '../types';
|
||||
import { selectFlowNodes } from './selectors';
|
||||
import { reqWrapper } from '../auth/sagas';
|
||||
import { postCellView } from './api';
|
||||
import { IFlowState } from './reducer';
|
||||
flowSetFlow
|
||||
} from "./actions";
|
||||
import { IResultWithStatus } from "../types";
|
||||
import { selectFlowNodes } from "./selectors";
|
||||
import { reqWrapper } from "../auth/sagas";
|
||||
import { postCellView } from "./api";
|
||||
import { IFlowState } from "./reducer";
|
||||
|
||||
function* onGetFlow() {
|
||||
yield put(flowSetFlow({ is_loading: true }));
|
||||
|
||||
const {
|
||||
data: { nodes = [], heroes = [], recent = [], updated = [] },
|
||||
data: { nodes = [], heroes = [], recent = [], updated = [], mode }
|
||||
}: IResultWithStatus<{
|
||||
nodes: IFlowState['nodes'];
|
||||
heroes: IFlowState['heroes'];
|
||||
recent: IFlowState['recent'];
|
||||
updated: IFlowState['updated'];
|
||||
nodes: IFlowState["nodes"];
|
||||
heroes: IFlowState["heroes"];
|
||||
recent: IFlowState["recent"];
|
||||
updated: IFlowState["updated"];
|
||||
mode: string;
|
||||
}> = yield call(reqWrapper, getNodes, {});
|
||||
|
||||
// if (!nodes || !nodes.length) {
|
||||
// yield put(flowSetNodes([]));
|
||||
// yield put(flowSetHeroes([]));
|
||||
// yield put(flowSetRecent([]));
|
||||
// yield put(flowSetUpdated([]));
|
||||
// return;
|
||||
// }
|
||||
yield put(flowSetFlow({ is_loading: false, nodes }));
|
||||
|
||||
yield put(flowSetNodes(nodes));
|
||||
yield put(flowSetHeroes(heroes));
|
||||
yield put(flowSetRecent(recent));
|
||||
yield put(flowSetUpdated(updated));
|
||||
if (heroes.length) yield put(flowSetHeroes(heroes));
|
||||
if (recent.length) yield put(flowSetRecent(recent));
|
||||
if (updated.length) yield put(flowSetUpdated(updated));
|
||||
|
||||
document.getElementById('main_loader').style.display = 'none';
|
||||
document.getElementById("main_loader").style.display = "none";
|
||||
}
|
||||
|
||||
function* onSetCellView({ id, flow }: ReturnType<typeof flowSetCellView>) {
|
||||
const nodes = yield select(selectFlowNodes);
|
||||
yield put(flowSetNodes(nodes.map(node => (node.id === id ? { ...node, flow } : node))));
|
||||
yield put(
|
||||
flowSetNodes(nodes.map(node => (node.id === id ? { ...node, flow } : node)))
|
||||
);
|
||||
|
||||
const { data, error } = yield call(reqWrapper, postCellView, { id, flow });
|
||||
}
|
||||
|
||||
console.log({ data, error });
|
||||
function* getMore() {
|
||||
yield put(flowSetFlow({ is_loading: true }));
|
||||
const nodes: IFlowState["nodes"] = yield select(selectFlowNodes);
|
||||
const from =
|
||||
nodes && nodes[nodes.length - 1] && nodes[nodes.length - 1].created_at;
|
||||
|
||||
const { error, data } = yield call(reqWrapper, getNodes, { from });
|
||||
|
||||
if (error || !data || !data.nodes) return;
|
||||
|
||||
yield put(
|
||||
flowSetFlow({ is_loading: false, nodes: [...nodes, ...data.nodes] })
|
||||
);
|
||||
|
||||
yield delay(data.nodes.length > 0 ? 2000 : 30000);
|
||||
}
|
||||
|
||||
export default function* nodeSaga() {
|
||||
yield takeLatest([FLOW_ACTIONS.GET_FLOW, REHYDRATE], onGetFlow);
|
||||
yield takeLatest(FLOW_ACTIONS.SET_CELL_VIEW, onSetCellView);
|
||||
yield takeLeading(FLOW_ACTIONS.GET_MORE, getMore);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
import { api, configWithToken, resultMiddleware, errorMiddleware } from '~/utils/api';
|
||||
import { INode, IResultWithStatus, IComment } from '../types';
|
||||
import { API } from '~/constants/api';
|
||||
import { nodeUpdateTags, nodeLike, nodeStar } from './actions';
|
||||
import { INodeState } from './reducer';
|
||||
import {
|
||||
api,
|
||||
configWithToken,
|
||||
resultMiddleware,
|
||||
errorMiddleware
|
||||
} from "~/utils/api";
|
||||
import { INode, IResultWithStatus, IComment } from "../types";
|
||||
import { API } from "~/constants/api";
|
||||
import { nodeUpdateTags, nodeLike, nodeStar } from "./actions";
|
||||
import { INodeState } from "./reducer";
|
||||
|
||||
export const postNode = ({
|
||||
access,
|
||||
node,
|
||||
node
|
||||
}: {
|
||||
access: string;
|
||||
node: INode;
|
||||
|
@ -18,20 +23,20 @@ export const postNode = ({
|
|||
// .then(console.log);
|
||||
|
||||
export const getNodes = ({
|
||||
skip = 0,
|
||||
access,
|
||||
from = null,
|
||||
access
|
||||
}: {
|
||||
skip?: number;
|
||||
from?: string;
|
||||
access: string;
|
||||
}): Promise<IResultWithStatus<{ nodes: INode[] }>> =>
|
||||
api
|
||||
.get(API.NODE.GET, configWithToken(access, { params: { skip } }))
|
||||
.get(API.NODE.GET, configWithToken(access, { params: { from } }))
|
||||
.then(resultMiddleware)
|
||||
.catch(errorMiddleware);
|
||||
|
||||
export const getNode = ({
|
||||
id,
|
||||
access,
|
||||
access
|
||||
}: {
|
||||
id: string | number;
|
||||
access: string;
|
||||
|
@ -44,7 +49,7 @@ export const getNode = ({
|
|||
export const postNodeComment = ({
|
||||
id,
|
||||
data,
|
||||
access,
|
||||
access
|
||||
}: {
|
||||
access: string;
|
||||
id: number;
|
||||
|
@ -58,11 +63,11 @@ export const postNodeComment = ({
|
|||
export const getNodeComments = ({
|
||||
id,
|
||||
access,
|
||||
order = 'ASC',
|
||||
order = "ASC"
|
||||
}: {
|
||||
id: number;
|
||||
access: string;
|
||||
order: 'ASC' | 'DESC';
|
||||
order: "ASC" | "DESC";
|
||||
}): Promise<IResultWithStatus<{ comments: Comment[] }>> =>
|
||||
api
|
||||
.get(API.NODE.COMMENT(id), configWithToken(access, { params: { order } }))
|
||||
|
@ -71,11 +76,11 @@ export const getNodeComments = ({
|
|||
|
||||
export const getNodeRelated = ({
|
||||
id,
|
||||
access,
|
||||
access
|
||||
}: {
|
||||
id: number;
|
||||
access: string;
|
||||
}): Promise<IResultWithStatus<{ related: INodeState['related'] }>> =>
|
||||
}): Promise<IResultWithStatus<{ related: INodeState["related"] }>> =>
|
||||
api
|
||||
.get(API.NODE.RELATED(id), configWithToken(access))
|
||||
.then(resultMiddleware)
|
||||
|
@ -84,7 +89,7 @@ export const getNodeRelated = ({
|
|||
export const updateNodeTags = ({
|
||||
id,
|
||||
tags,
|
||||
access,
|
||||
access
|
||||
}: ReturnType<typeof nodeUpdateTags> & { access: string }): Promise<
|
||||
IResultWithStatus<{ node: INode }>
|
||||
> =>
|
||||
|
@ -95,9 +100,9 @@ export const updateNodeTags = ({
|
|||
|
||||
export const postNodeLike = ({
|
||||
id,
|
||||
access,
|
||||
access
|
||||
}: ReturnType<typeof nodeLike> & { access: string }): Promise<
|
||||
IResultWithStatus<{ is_liked: INode['is_liked'] }>
|
||||
IResultWithStatus<{ is_liked: INode["is_liked"] }>
|
||||
> =>
|
||||
api
|
||||
.post(API.NODE.POST_LIKE(id), {}, configWithToken(access))
|
||||
|
@ -106,9 +111,9 @@ export const postNodeLike = ({
|
|||
|
||||
export const postNodeStar = ({
|
||||
id,
|
||||
access,
|
||||
access
|
||||
}: ReturnType<typeof nodeStar> & { access: string }): Promise<
|
||||
IResultWithStatus<{ is_liked: INode['is_liked'] }>
|
||||
IResultWithStatus<{ is_liked: INode["is_liked"] }>
|
||||
> =>
|
||||
api
|
||||
.post(API.NODE.POST_STAR(id), {}, configWithToken(access))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue