settings on redux; some fix with theme
This commit is contained in:
+10
-6
@@ -26,11 +26,13 @@ import Users from "../Users/Users";
|
|||||||
import {getVersion, version} from "../../api/api";
|
import {getVersion, version} from "../../api/api";
|
||||||
import Settings from "../User/Settings/Settings";
|
import Settings from "../User/Settings/Settings";
|
||||||
import {setUser} from "../../store/ducks/currentUser";
|
import {setUser} from "../../store/ducks/currentUser";
|
||||||
|
import {setSettings} from "../../store/ducks/userSettings";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
notifications: React.ReactNode[]
|
notifications: React.ReactNode[]
|
||||||
setUser: (user: UserType) => void
|
|
||||||
modal: React.ReactNode
|
modal: React.ReactNode
|
||||||
|
setUser: SetUser
|
||||||
|
setSettings: SetSettings
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {}
|
type State = {}
|
||||||
@@ -45,10 +47,11 @@ class App extends React.Component<Props, State> {
|
|||||||
if(cachedTheme)
|
if(cachedTheme)
|
||||||
document.body.setAttribute('theme', cachedTheme);
|
document.body.setAttribute('theme', cachedTheme);
|
||||||
|
|
||||||
const { setUser } = props;
|
const { setUser, setSettings } = props;
|
||||||
fetchCurrentUser().then((user: UserType) => {
|
fetchCurrentUser().then(user => {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
fetchUserSettings().then((settings: UserSettingsType) => {
|
fetchUserSettings().then(settings => {
|
||||||
|
setSettings(settings);
|
||||||
if(settings.theme !== cachedTheme) {
|
if(settings.theme !== cachedTheme) {
|
||||||
localStorage.setItem('theme', settings.theme);
|
localStorage.setItem('theme', settings.theme);
|
||||||
document.body.setAttribute('theme', settings.theme);
|
document.body.setAttribute('theme', settings.theme);
|
||||||
@@ -64,7 +67,7 @@ class App extends React.Component<Props, State> {
|
|||||||
|
|
||||||
getVersion().then(res => {
|
getVersion().then(res => {
|
||||||
if(version !== res.version) {
|
if(version !== res.version) {
|
||||||
console.log(`Current back-end version: ${res.version}. Clearing cache`);
|
console.debug(`Current back-end version: ${res.version}. Clearing cache`);
|
||||||
|
|
||||||
caches.keys().then(names => {
|
caches.keys().then(names => {
|
||||||
names.forEach(name => caches.delete(name).catch(console.error))
|
names.forEach(name => caches.delete(name).catch(console.error))
|
||||||
@@ -130,6 +133,7 @@ export default connect(
|
|||||||
modal: state.modal
|
modal: state.modal
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
setUser: (userData: UserType) => dispatch(setUser(userData))
|
setUser: (userData: UserType) => dispatch(setUser(userData)),
|
||||||
|
setSettings: (settings: UserSettingsType) => dispatch(setSettings(settings))
|
||||||
})
|
})
|
||||||
)(App);
|
)(App);
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ import Input from "../../ui/Input/Input";
|
|||||||
import {setUser} from "../../store/ducks/currentUser";
|
import {setUser} from "../../store/ducks/currentUser";
|
||||||
import {addNotification} from "../../store/ducks/notifications";
|
import {addNotification} from "../../store/ducks/notifications";
|
||||||
import {hideModal, setModal} from "../../store/ducks/modal";
|
import {hideModal, setModal} from "../../store/ducks/modal";
|
||||||
|
import {fetchUserSettings} from "../../api/users";
|
||||||
|
import {setSettings} from "../../store/ducks/userSettings";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setUser: (user: UserType) => void
|
setUser: SetUser
|
||||||
addNotification: (notification: React.ReactNode) => void
|
addNotification: AddNotification
|
||||||
setModal: (modal: React.ReactNode | null) => void
|
setModal: SetModal
|
||||||
hideModal: () => void
|
hideModal: HideModal
|
||||||
|
setSettings: SetSettings
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -36,7 +39,7 @@ class LoginModal extends React.Component<Props, State> {
|
|||||||
|
|
||||||
loginAndFetchToken = (event: FormEvent) => {
|
loginAndFetchToken = (event: FormEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const { setUser, addNotification, setModal } = this.props;
|
const { setUser, addNotification, setModal, setSettings } = this.props;
|
||||||
const { login: log, password, recaptcha } = this.state;
|
const { login: log, password, recaptcha } = this.state;
|
||||||
|
|
||||||
login(log, password, recaptcha).then(user => {
|
login(log, password, recaptcha).then(user => {
|
||||||
@@ -50,8 +53,13 @@ class LoginModal extends React.Component<Props, State> {
|
|||||||
);
|
);
|
||||||
addNotification(successful);
|
addNotification(successful);
|
||||||
setModal(null);
|
setModal(null);
|
||||||
})
|
|
||||||
.catch((r: ApiError) => {
|
fetchUserSettings().then(settings => {
|
||||||
|
localStorage.setItem('theme', settings.theme);
|
||||||
|
document.body.setAttribute('theme', settings.theme);
|
||||||
|
setSettings(settings);
|
||||||
|
});
|
||||||
|
}).catch((r: ApiError) => {
|
||||||
this.setState({ error: errors[r.code] });
|
this.setState({ error: errors[r.code] });
|
||||||
if(r.code === 9) this.setState({ recaptchaNeeded: true });
|
if(r.code === 9) this.setState({ recaptchaNeeded: true });
|
||||||
});
|
});
|
||||||
@@ -105,6 +113,7 @@ class LoginModal extends React.Component<Props, State> {
|
|||||||
export default connect(null,
|
export default connect(null,
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
setUser: (user: UserType) => dispatch(setUser(user)),
|
setUser: (user: UserType) => dispatch(setUser(user)),
|
||||||
|
setSettings: (settings: UserSettingsType) => dispatch(setSettings(settings)),
|
||||||
addNotification: (notification: React.ReactNode) => dispatch(addNotification(notification)),
|
addNotification: (notification: React.ReactNode) => dispatch(addNotification(notification)),
|
||||||
setModal: (modal: React.ReactNode | null) => dispatch(setModal(modal)),
|
setModal: (modal: React.ReactNode | null) => dispatch(setModal(modal)),
|
||||||
hideModal: () => dispatch(hideModal())
|
hideModal: () => dispatch(hideModal())
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ class Navbar extends React.Component<Props, State> {
|
|||||||
logout = () => {
|
logout = () => {
|
||||||
this.props.logout();
|
this.props.logout();
|
||||||
localStorage.removeItem('user');
|
localStorage.removeItem('user');
|
||||||
userLogout().then();
|
localStorage.removeItem('theme');
|
||||||
|
document.querySelector('body')!!.removeAttribute('theme');
|
||||||
|
userLogout().catch(() => {});
|
||||||
};
|
};
|
||||||
|
|
||||||
changeSize = () => {
|
changeSize = () => {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import Button from "../../../ui/Button/Button";
|
import Button from "../../../ui/Button/Button";
|
||||||
import Group from "../../../ui/Group/Group";
|
import Group from "../../../ui/Group/Group";
|
||||||
import React, {FormEvent} from "react";
|
import React, {FormEvent} from "react";
|
||||||
import {fetchUserSettings, updateUserAppearanceSettings} from "../../../api/users";
|
import {updateUserAppearanceSettings} from "../../../api/users";
|
||||||
import {connect} from "react-redux";
|
import {connect} from "react-redux";
|
||||||
import {setUser} from "../../../store/ducks/currentUser";
|
import {setUser} from "../../../store/ducks/currentUser";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setUser: SetUser
|
setUser: SetUser
|
||||||
|
settings: UserSettingsType
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -15,13 +16,7 @@ type State = {
|
|||||||
|
|
||||||
class Appearance extends React.Component<Props, State> {
|
class Appearance extends React.Component<Props, State> {
|
||||||
state: State = {
|
state: State = {
|
||||||
theme: 'dark'
|
theme: this.props.settings.theme
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
fetchUserSettings().then(settings => {
|
|
||||||
this.setState({ theme: settings.theme })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveTheme = (event: FormEvent) => {
|
saveTheme = (event: FormEvent) => {
|
||||||
@@ -59,7 +54,10 @@ class Appearance extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(null,
|
export default connect(
|
||||||
|
(state: StoreState) => ({
|
||||||
|
settings: state.userSettings
|
||||||
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
setUser: (user: UserType) => dispatch(setUser(user))
|
setUser: (user: UserType) => dispatch(setUser(user))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React, {ChangeEvent, FormEvent} from "react";
|
import React, {ChangeEvent, FormEvent} from "react";
|
||||||
import Button from "../../../ui/Button/Button";
|
import Button from "../../../ui/Button/Button";
|
||||||
import Group from "../../../ui/Group/Group";
|
import Group from "../../../ui/Group/Group";
|
||||||
import {fetchUserSettings, updateUserGeneralSettings, uploadAvatar} from "../../../api/users";
|
import {updateUserGeneralSettings, uploadAvatar} from "../../../api/users";
|
||||||
|
import {connect} from "react-redux";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setUser: (user: UserType) => void
|
setUser: SetUser
|
||||||
|
settings: UserSettingsType
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -15,13 +17,7 @@ type State = {
|
|||||||
|
|
||||||
class General extends React.Component<Props, State> {
|
class General extends React.Component<Props, State> {
|
||||||
state: State = {
|
state: State = {
|
||||||
useGravatar: false, avatar: null
|
useGravatar: this.props.settings.use_gravatar, avatar: null
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
fetchUserSettings().then(settings => {
|
|
||||||
this.setState({ useGravatar: settings.use_gravatar })
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeAvatar = (event: ChangeEvent<HTMLInputElement>) => {
|
onChangeAvatar = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -62,4 +58,8 @@ class General extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default General;
|
export default connect(
|
||||||
|
(state: StoreState) => ({
|
||||||
|
settings: state.userSettings
|
||||||
|
})
|
||||||
|
)(General);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class Security extends React.Component<{}, State> {
|
|||||||
placeholder={'Новый E-mail ещё раз'}
|
placeholder={'Новый E-mail ещё раз'}
|
||||||
type={'email'}
|
type={'email'}
|
||||||
value={email2}
|
value={email2}
|
||||||
onChange={e => this.setState({ email1: e.target.value })}
|
onChange={e => this.setState({ email2: e.target.value })}
|
||||||
/>
|
/>
|
||||||
<Button>Сохранить</Button>
|
<Button>Сохранить</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ import {combineReducers} from "redux";
|
|||||||
import currentUser from './currentUser'
|
import currentUser from './currentUser'
|
||||||
import modal from "./modal";
|
import modal from "./modal";
|
||||||
import notifications from './notifications'
|
import notifications from './notifications'
|
||||||
|
import userSettings from './userSettings';
|
||||||
|
|
||||||
export default combineReducers({ currentUser, modal, notifications })
|
export default combineReducers({ currentUser, modal, notifications, userSettings })
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const SET_SETTINGS = 'unmei/userSettings/SET_SETTINGS';
|
||||||
|
|
||||||
|
const reducer = (state={}, action: Action<{settings: UserSettingsType}>) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case SET_SETTINGS:
|
||||||
|
state = Object.assign({}, state, action.payload.settings);
|
||||||
|
return state;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSettings = (settings: UserSettingsType) => ({
|
||||||
|
type: SET_SETTINGS,
|
||||||
|
payload: { settings }
|
||||||
|
});
|
||||||
|
|
||||||
|
export default reducer;
|
||||||
|
export { setSettings }
|
||||||
Vendored
+7
@@ -1,11 +1,18 @@
|
|||||||
type StoreState = {
|
type StoreState = {
|
||||||
currentUser: UserType
|
currentUser: UserType
|
||||||
|
userSettings: UserSettingsType
|
||||||
notifications: React.ReactNode[]
|
notifications: React.ReactNode[]
|
||||||
modal: React.ReactNode
|
modal: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Action<T> = {
|
||||||
|
type: string
|
||||||
|
payload: T
|
||||||
|
}
|
||||||
|
|
||||||
type SetUser = (user: UserType) => void
|
type SetUser = (user: UserType) => void
|
||||||
type LogoutUser = () => void
|
type LogoutUser = () => void
|
||||||
|
type SetSettings = (settings: UserSettingsType) => void
|
||||||
type SetModal = (modal: React.ReactNode | null) => void
|
type SetModal = (modal: React.ReactNode | null) => void
|
||||||
type HideModal = () => void
|
type HideModal = () => void
|
||||||
type AddNotification = (notification: React.ReactNode) => void
|
type AddNotification = (notification: React.ReactNode) => void
|
||||||
|
|||||||
Reference in New Issue
Block a user