1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-26 05:16:41 +07:00

added initial profile dialog

This commit is contained in:
Fedor Katurov 2019-11-11 16:01:21 +07:00
parent f6baedc4cd
commit 618c2e3275
28 changed files with 315 additions and 58 deletions

View file

@ -19,8 +19,8 @@ export const authSetToken = (token: IAuthState['token']) => ({
token,
});
export const gotPostMessage = ({ token }: { token: string }) => ({
type: AUTH_USER_ACTIONS.GOT_POST_MESSAGE,
export const gotAuthPostMessage = ({ token }: { token: string }) => ({
type: AUTH_USER_ACTIONS.GOT_AUTH_POST_MESSAGE,
token,
});
@ -32,3 +32,13 @@ export const authSetUser = (profile: Partial<IUser>) => ({
export const authLogout = () => ({
type: AUTH_USER_ACTIONS.LOGOUT,
});
export const authOpenProfile = (username: string) => ({
type: AUTH_USER_ACTIONS.OPEN_PROFILE,
username,
});
export const authSetProfile = (profile: Partial<IAuthState['profile']>) => ({
type: AUTH_USER_ACTIONS.SET_PROFILE,
profile,
});

View file

@ -22,3 +22,12 @@ export const apiAuthGetUser = ({ access }): Promise<IResultWithStatus<{ user: IU
.get(API.USER.ME, configWithToken(access))
.then(resultMiddleware)
.catch(errorMiddleware);
export const apiAuthGetUserProfile = ({
access,
username,
}): Promise<IResultWithStatus<{ user: IUser }>> =>
api
.get(API.USER.PROFILE(username), configWithToken(access))
.then(resultMiddleware)
.catch(errorMiddleware);

View file

@ -8,7 +8,9 @@ export const AUTH_USER_ACTIONS = {
LOGOUT: 'LOGOUT',
GOT_POST_MESSAGE: 'GOT_POST_MESSAGE',
GOT_AUTH_POST_MESSAGE: 'GOT_POST_MESSAGE',
OPEN_PROFILE: 'OPEN_PROFILE',
SET_PROFILE: 'SET_PROFILE',
};
export const USER_ERRORS = {

View file

@ -14,23 +14,32 @@ const setLoginError: ActionHandler<typeof ActionCreators.userSetLoginError> = (
login: {
...state.login,
error,
}
},
});
const setUser: ActionHandler<typeof ActionCreators.authSetUser> = (state, { profile }) => ({
...state,
user: {
...state.user,
...profile
}
...profile,
},
});
const setToken: ActionHandler<typeof ActionCreators.authSetToken> = (state, { token }) => ({
...state, token,
...state,
token,
});
const setProfile: ActionHandler<typeof ActionCreators.authSetProfile> = (state, { profile }) => ({
...state,
profile: {
...state.profile,
...profile,
},
});
export const AUTH_USER_HANDLERS = {
[AUTH_USER_ACTIONS.SET_LOGIN_ERROR]: setLoginError,
[AUTH_USER_ACTIONS.SET_USER]: setUser,
[AUTH_USER_ACTIONS.SET_TOKEN]: setToken,
[AUTH_USER_ACTIONS.SET_PROFILE]: setProfile,
};

View file

@ -10,10 +10,16 @@ const HANDLERS = {
const INITIAL_STATE: IAuthState = {
token: null,
user: { ...EMPTY_USER },
login: {
error: null,
is_loading: false,
},
profile: {
is_loading: true,
user: null,
},
};
export default createReducer(INITIAL_STATE, HANDLERS);

View file

@ -1,19 +1,20 @@
import { call, put, takeLatest, select } from 'redux-saga/effects';
import { call, put, takeLatest, select, delay } from 'redux-saga/effects';
import { AUTH_USER_ACTIONS, EMPTY_USER, USER_ERRORS } from '~/redux/auth/constants';
import {
authSetToken,
userSetLoginError,
authSetUser,
userSendLoginRequest,
gotPostMessage,
gotAuthPostMessage,
authOpenProfile,
authSetProfile,
} from '~/redux/auth/actions';
import { apiUserLogin, apiAuthGetUser } from '~/redux/auth/api';
import { modalSetShown } from '~/redux/modal/actions';
import { apiUserLogin, apiAuthGetUser, apiAuthGetUserProfile } from '~/redux/auth/api';
import { modalSetShown, modalShowDialog } from '~/redux/modal/actions';
import { selectToken } from './selectors';
import { IResultWithStatus } from '../types';
import { IUser } from './types';
import { REHYDRATE, RehydrateAction } from 'redux-persist';
import path from 'ramda/es/path';
import { selectModal } from '../modal/selectors';
import { IModalState } from '../modal/reducer';
import { DIALOGS } from '../modal/constants';
@ -76,7 +77,7 @@ function* checkUserSaga({ key }: RehydrateAction) {
yield call(refreshUser);
}
function* gotPostMessageSaga({ token }: ReturnType<typeof gotPostMessage>) {
function* gotPostMessageSaga({ token }: ReturnType<typeof gotAuthPostMessage>) {
yield put(authSetToken(token));
yield call(refreshUser);
@ -90,11 +91,29 @@ function* logoutSaga() {
yield put(authSetUser({ ...EMPTY_USER }));
}
function* openProfile({ username }: ReturnType<typeof authOpenProfile>) {
yield put(modalShowDialog(DIALOGS.PROFILE));
yield put(authSetProfile({ is_loading: true }));
const {
error,
data: { user },
} = yield call(reqWrapper, apiAuthGetUserProfile, { username });
if (error || !user) {
return yield put(modalSetShown(false));
}
yield put(authSetProfile({ is_loading: false }));
console.log({ username, user });
}
function* authSaga() {
yield takeLatest(REHYDRATE, checkUserSaga);
yield takeLatest(AUTH_USER_ACTIONS.LOGOUT, logoutSaga);
yield takeLatest(AUTH_USER_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga);
yield takeLatest(AUTH_USER_ACTIONS.GOT_POST_MESSAGE, gotPostMessageSaga);
yield takeLatest(AUTH_USER_ACTIONS.GOT_AUTH_POST_MESSAGE, gotPostMessageSaga);
yield takeLatest(AUTH_USER_ACTIONS.OPEN_PROFILE, openProfile);
}
export default authSaga;

View file

@ -4,3 +4,4 @@ export const selectAuth = (state: IState): IState['auth'] => state.auth;
export const selectUser = (state: IState): IState['auth']['user'] => state.auth.user;
export const selectToken = (state: IState): IState['auth']['token'] => state.auth.token;
export const selectAuthLogin = (state: IState): IState['auth']['login'] => state.auth.login;
export const selectAuthProfile = (state: IState): IState['auth']['profile'] => state.auth.profile;

View file

@ -26,4 +26,9 @@ export type IAuthState = Readonly<{
error: string;
is_loading: boolean;
};
profile: {
is_loading: boolean;
user: IUser;
};
}>;

View file

@ -7,6 +7,7 @@ import { EditorDialogVideo } from '~/containers/editors/EditorDialogVideo';
import { EditorDialogAudio } from '~/containers/editors/EditorDialogAudio';
import { NODE_TYPES } from '../node/constants';
import { TestDialog } from '~/containers/dialogs/TestDialog';
import { ProfileDialog } from '~/containers/dialogs/ProfileDialog';
export const MODAL_ACTIONS = {
SET_SHOWN: 'MODAL.SET_SHOWN',
@ -21,6 +22,7 @@ export const DIALOGS = {
EDITOR_AUDIO: 'EDITOR_AUDIO',
LOGIN: 'LOGIN',
LOADING: 'LOADING',
PROFILE: 'PROFILE',
TEST: 'TEST',
};
@ -32,6 +34,7 @@ export const DIALOG_CONTENT = {
[DIALOGS.LOGIN]: LoginDialog,
[DIALOGS.LOADING]: LoadingDialog,
[DIALOGS.TEST]: TestDialog,
[DIALOGS.PROFILE]: ProfileDialog,
};
export const NODE_EDITOR_DIALOGS = {

View file

@ -25,7 +25,7 @@ import playerSaga from '~/redux/player/sagas';
import { IAuthState } from '~/redux/auth/types';
import modalReducer, { IModalState } from '~/redux/modal/reducer';
import { gotPostMessage } from './auth/actions';
import { gotAuthPostMessage, authOpenProfile } from './auth/actions';
const authPersistConfig: PersistConfig = {
key: 'auth',
@ -46,6 +46,13 @@ export interface IState {
export const sagaMiddleware = createSagaMiddleware();
export const history = createBrowserHistory();
history.listen(({ pathname }) => {
if (pathname.match(/~([\wа-яА-Я]+)/)) {
const [, username] = pathname.match(/~([\wа-яА-Я]+)/);
window.postMessage({ type: 'username', username }, '*');
}
});
const composeEnhancers =
typeof window === 'object' && (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
@ -72,9 +79,11 @@ export function configureStore(): { store: Store<IState>; persistor: Persistor }
sagaMiddleware.run(playerSaga);
window.addEventListener('message', message => {
if (!message || !message.data || message.data.type !== 'oauth_login' || !message.data.token)
return;
store.dispatch(gotPostMessage({ token: message.data.token }));
if (message && message.data && message.data.type === 'oauth_login' && message.data.token)
return store.dispatch(gotAuthPostMessage({ token: message.data.token }));
if (message && message.data && message.data.type === 'username' && message.data.username)
return store.dispatch(authOpenProfile(message.data.username));
});
const persistor = persistStore(store);