mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-05-03 00:26:41 +07:00
made tags panel
This commit is contained in:
parent
f2289f4530
commit
c4f60f3d81
31 changed files with 552 additions and 75 deletions
|
@ -1,5 +1,5 @@
|
|||
import { FC, ReactElement } from 'react';
|
||||
import { INode, ValueOf, IComment } from '../types';
|
||||
import { FC } from 'react';
|
||||
import { IComment, INode, ValueOf } from '../types';
|
||||
import { NodeImageSlideBlock } from '~/components/node/NodeImageSlideBlock';
|
||||
import { NodeTextBlock } from '~/components/node/NodeTextBlock';
|
||||
import { NodeAudioBlock } from '~/components/node/NodeAudioBlock';
|
||||
|
@ -12,7 +12,6 @@ import { AudioEditor } from '~/components/editors/AudioEditor';
|
|||
import { EditorImageUploadButton } from '~/components/editors/EditorImageUploadButton';
|
||||
import { EditorAudioUploadButton } from '~/components/editors/EditorAudioUploadButton';
|
||||
import { EditorUploadCoverButton } from '~/components/editors/EditorUploadCoverButton';
|
||||
import { Filler } from '~/components/containers/Filler';
|
||||
import { modalShowPhotoswipe } from '../modal/actions';
|
||||
import { IEditorComponentProps } from '~/redux/node/types';
|
||||
import { EditorFiller } from '~/components/editors/EditorFiller';
|
||||
|
|
|
@ -34,6 +34,9 @@ import borisSaga from './boris/sagas';
|
|||
import messages, { IMessagesState } from './messages';
|
||||
import messagesSaga from './messages/sagas';
|
||||
|
||||
import tag, { ITagState } from './tag';
|
||||
import tagSaga from './tag/sagas';
|
||||
|
||||
const authPersistConfig: PersistConfig = {
|
||||
key: 'auth',
|
||||
whitelist: ['token', 'user', 'updates'],
|
||||
|
@ -62,6 +65,7 @@ export interface IState {
|
|||
player: IPlayerState;
|
||||
boris: IBorisState;
|
||||
messages: IMessagesState;
|
||||
tag: ITagState;
|
||||
}
|
||||
|
||||
export const sagaMiddleware = createSagaMiddleware();
|
||||
|
@ -83,6 +87,7 @@ export const store = createStore(
|
|||
flow: persistReducer(flowPersistConfig, flow),
|
||||
player: persistReducer(playerPersistConfig, player),
|
||||
messages,
|
||||
tag: tag,
|
||||
}),
|
||||
composeEnhancers(applyMiddleware(routerMiddleware(history), sagaMiddleware))
|
||||
);
|
||||
|
@ -99,6 +104,7 @@ export function configureStore(): {
|
|||
sagaMiddleware.run(modalSaga);
|
||||
sagaMiddleware.run(borisSaga);
|
||||
sagaMiddleware.run(messagesSaga);
|
||||
sagaMiddleware.run(tagSaga);
|
||||
|
||||
window.addEventListener('message', message => {
|
||||
if (message && message.data && message.data.type === 'oauth_login' && message.data.token)
|
||||
|
|
12
src/redux/tag/actions.ts
Normal file
12
src/redux/tag/actions.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { ITagState } from '~/redux/tag/index';
|
||||
import { TAG_ACTIONS } from '~/redux/tag/constants';
|
||||
|
||||
export const tagSetNodes = (nodes: Partial<ITagState['nodes']>) => ({
|
||||
type: TAG_ACTIONS.SET_TAG_NODES,
|
||||
nodes,
|
||||
});
|
||||
|
||||
export const tagLoadNodes = (tag: string) => ({
|
||||
type: TAG_ACTIONS.LOAD_TAG_NODES,
|
||||
tag,
|
||||
});
|
19
src/redux/tag/api.ts
Normal file
19
src/redux/tag/api.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { INode, IResultWithStatus } from '~/redux/types';
|
||||
import { api, configWithToken, errorMiddleware, resultMiddleware } from '~/utils/api';
|
||||
import { API } from '~/constants/api';
|
||||
|
||||
export const getTagNodes = ({
|
||||
access,
|
||||
tag,
|
||||
offset,
|
||||
limit,
|
||||
}: {
|
||||
access: string;
|
||||
tag: string;
|
||||
offset: number;
|
||||
limit: number;
|
||||
}): Promise<IResultWithStatus<{ nodes: INode[]; count: number }>> =>
|
||||
api
|
||||
.get(API.TAG.NODES, configWithToken(access, { params: { name: tag, offset, limit } }))
|
||||
.then(resultMiddleware)
|
||||
.catch(errorMiddleware);
|
6
src/redux/tag/constants.ts
Normal file
6
src/redux/tag/constants.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
const prefix = 'TAG.';
|
||||
|
||||
export const TAG_ACTIONS = {
|
||||
LOAD_TAG_NODES: `${prefix}LOAD_TAG_NODES`,
|
||||
SET_TAG_NODES: `${prefix}SET_TAG_NODES`,
|
||||
};
|
15
src/redux/tag/handlers.ts
Normal file
15
src/redux/tag/handlers.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { TAG_ACTIONS } from '~/redux/tag/constants';
|
||||
import { ITagState } from '~/redux/tag/index';
|
||||
import { tagSetNodes } from '~/redux/tag/actions';
|
||||
|
||||
const setNodes = (state: ITagState, { nodes }: ReturnType<typeof tagSetNodes>) => ({
|
||||
...state,
|
||||
nodes: {
|
||||
...state.nodes,
|
||||
...nodes,
|
||||
},
|
||||
});
|
||||
|
||||
export const TAG_HANDLERS = {
|
||||
[TAG_ACTIONS.SET_TAG_NODES]: setNodes,
|
||||
};
|
21
src/redux/tag/index.ts
Normal file
21
src/redux/tag/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { createReducer } from '~/utils/reducer';
|
||||
import { INode } from '~/redux/types';
|
||||
import { TAG_HANDLERS } from '~/redux/tag/handlers';
|
||||
|
||||
export interface ITagState {
|
||||
nodes: {
|
||||
list: INode[];
|
||||
count: number;
|
||||
isLoading: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
const INITIAL_STATE: ITagState = {
|
||||
nodes: {
|
||||
list: [],
|
||||
count: 0,
|
||||
isLoading: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(INITIAL_STATE, TAG_HANDLERS);
|
31
src/redux/tag/sagas.ts
Normal file
31
src/redux/tag/sagas.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { TAG_ACTIONS } from '~/redux/tag/constants';
|
||||
import { call, put, select, takeLatest } from 'redux-saga/effects';
|
||||
import { tagLoadNodes, tagSetNodes } from '~/redux/tag/actions';
|
||||
import { reqWrapper } from '~/redux/auth/sagas';
|
||||
import { selectTagNodes } from '~/redux/tag/selectors';
|
||||
import { getTagNodes } from '~/redux/tag/api';
|
||||
import { Unwrap } from '~/redux/types';
|
||||
|
||||
function* loadTagNodes({ tag }: ReturnType<typeof tagLoadNodes>) {
|
||||
yield put(tagSetNodes({ isLoading: true }));
|
||||
|
||||
try {
|
||||
const { list }: ReturnType<typeof selectTagNodes> = yield select(selectTagNodes);
|
||||
const { data, error }: Unwrap<ReturnType<typeof getTagNodes>> = yield call(
|
||||
reqWrapper,
|
||||
getTagNodes,
|
||||
{ tag, limit: 18, offset: list.length }
|
||||
);
|
||||
|
||||
if (error) throw new Error(error);
|
||||
|
||||
yield put(tagSetNodes({ isLoading: false, list: [...list, ...data.nodes], count: data.count }));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
yield put(tagSetNodes({ isLoading: false }));
|
||||
}
|
||||
}
|
||||
|
||||
export default function* tagSaga() {
|
||||
yield takeLatest(TAG_ACTIONS.LOAD_TAG_NODES, loadTagNodes);
|
||||
}
|
4
src/redux/tag/selectors.ts
Normal file
4
src/redux/tag/selectors.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { IState } from '~/redux/store';
|
||||
|
||||
export const selectTag = (state: IState) => state.tag;
|
||||
export const selectTagNodes = (state: IState) => state.tag.nodes;
|
Loading…
Add table
Add a link
Reference in a new issue