mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
now user can login
This commit is contained in:
parent
e7960a6bf8
commit
e19001ca82
25 changed files with 493 additions and 32844 deletions
71
package-lock.json
generated
71
package-lock.json
generated
|
@ -8034,6 +8034,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz",
|
||||
"integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
|
@ -10204,6 +10209,19 @@
|
|||
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==",
|
||||
"dev": true
|
||||
},
|
||||
"ramda": {
|
||||
"version": "0.24.1",
|
||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz",
|
||||
"integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc="
|
||||
},
|
||||
"ramdasauce": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ramdasauce/-/ramdasauce-2.1.0.tgz",
|
||||
"integrity": "sha512-BdHm//tlCCmeXxY5EvIvlczuWvZU5QcRybdxZ4mkDOIasWzbBs+bjt3iEVsThKCMWLIiFZpggtQmIyjtL7eOvA==",
|
||||
"requires": {
|
||||
"ramda": "^0.24.1"
|
||||
}
|
||||
},
|
||||
"randomatic": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
|
||||
|
@ -10337,6 +10355,24 @@
|
|||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
|
||||
"integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.5.0",
|
||||
"invariant": "^2.0.0",
|
||||
"lodash": "^4.17.5",
|
||||
"lodash-es": "^4.17.5",
|
||||
"loose-envify": "^1.1.0",
|
||||
"prop-types": "^15.6.0"
|
||||
}
|
||||
},
|
||||
"react-router-redux": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz",
|
||||
"integrity": "sha1-InQDWWtRUeGCN32rg1tdRfD4BU4="
|
||||
},
|
||||
"read-chunk": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
|
||||
|
@ -10476,6 +10512,41 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"redux": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.0.tgz",
|
||||
"integrity": "sha512-NnnHF0h0WVE/hXyrB6OlX67LYRuaf/rJcbWvnHHEPCF/Xa/AZpwhs/20WyqzQae5x4SD2F9nPObgBh2rxAgLiA==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"symbol-observable": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"redux-persist": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-5.10.0.tgz",
|
||||
"integrity": "sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg=="
|
||||
},
|
||||
"redux-saga": {
|
||||
"version": "0.16.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-0.16.0.tgz",
|
||||
"integrity": "sha1-CiMdsKFIkwHdmA9vL4jYztQY9yQ="
|
||||
},
|
||||
"reduxsauce": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/reduxsauce/-/reduxsauce-1.0.0.tgz",
|
||||
"integrity": "sha512-+HXHbr9Xq9VRFRXAt/LTcNpQf3wix/ynPyVnTLAJYEULwRUylZZJaid5TAVzdBUtAp6V00bukKItLxxEVbGxvg==",
|
||||
"requires": {
|
||||
"ramda": "^0.24.1",
|
||||
"ramdasauce": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
"react": "^16.3.2",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-hot-loader": "^4.1.1",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"redux": "^4.0.0",
|
||||
"redux-persist": "^5.10.0",
|
||||
"redux-saga": "^0.16.0",
|
||||
"reduxsauce": "^1.0.0",
|
||||
"regenerator-runtime": "^0.11.1",
|
||||
"scrypt": "^6.0.3",
|
||||
"styled-components": "^3.2.6",
|
||||
|
|
|
@ -39,16 +39,6 @@ export class EditorPanel extends React.PureComponent {
|
|||
|
||||
<LogoPreview logo={logo} />
|
||||
|
||||
<div className="panel">
|
||||
<div className="control-bar">
|
||||
<button
|
||||
onClick={this.startShotterMode}
|
||||
>
|
||||
<span>РЕДАКТОР</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="panel right">
|
||||
<div className="control-dist">
|
||||
{totalDistance} км
|
||||
|
|
79
src/components/panels/UserPanel.jsx
Normal file
79
src/components/panels/UserPanel.jsx
Normal file
|
@ -0,0 +1,79 @@
|
|||
import React from 'react';
|
||||
|
||||
import { GuestButton } from '$components/user/GuestButton';
|
||||
import { SERVER } from '$constants/api';
|
||||
import { DEFAULT_USER, ROLES } from '$constants/auth';
|
||||
import { UserButton } from '$components/user/UserButton';
|
||||
import { Icon } from '$components/panels/Icon';
|
||||
|
||||
export class UserPanel extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
window.doLogin = console.log;
|
||||
|
||||
window.addEventListener('message', e => {
|
||||
const { data } = e;
|
||||
|
||||
if (!data || !data.type || data.type !== 'oauth_login' || !data.user || !data.user.id || !data.user.token) return;
|
||||
|
||||
const {
|
||||
id, token, role = 'vk', name = '', ip = '', photo = '', agent = '',
|
||||
} = data.user;
|
||||
|
||||
const user = {
|
||||
...DEFAULT_USER,
|
||||
role,
|
||||
id,
|
||||
token,
|
||||
userdata: {
|
||||
name,
|
||||
ip,
|
||||
agent,
|
||||
photo,
|
||||
}
|
||||
};
|
||||
|
||||
this.props.setUser(user);
|
||||
});
|
||||
}
|
||||
|
||||
openOauthFrame = () => {
|
||||
const width = parseInt(window.innerWidth, 10);
|
||||
const height = parseInt(window.innerHeight, 10);
|
||||
const top = (height - 370) / 2;
|
||||
const left = (width - 700) / 2;
|
||||
|
||||
window.open(
|
||||
`https://oauth.vk.com/authorize?client_id=5987644&scope=&redirect_uri=${SERVER}/engine/oauthOrchid.php&response_type=code`,
|
||||
'socialPopupWindow',
|
||||
`location=no,width=700,height=370,scrollbars=no,top=${top},left=${left},resizable=no`
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
user
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="panel">
|
||||
<div className="control-bar">
|
||||
<button
|
||||
onClick={this.startShotterMode}
|
||||
>
|
||||
<Icon icon="icon-poly" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="control-sep" />
|
||||
|
||||
{
|
||||
!user || user.role === ROLES.guest
|
||||
? <GuestButton onClick={this.openOauthFrame} />
|
||||
: <UserButton user={user} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
11
src/components/user/GuestButton.jsx
Normal file
11
src/components/user/GuestButton.jsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
export const GuestButton = ({ onClick }) => (
|
||||
<div className="control-bar user-bar">
|
||||
<button
|
||||
onClick={onClick}
|
||||
>
|
||||
<span>ВОЙТИ</span>
|
||||
</button>
|
||||
</div>
|
||||
);
|
23
src/components/user/UserButton.jsx
Normal file
23
src/components/user/UserButton.jsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import { UserPicture } from '$components/user/UserPicture';
|
||||
|
||||
export const UserButton = ({
|
||||
user: {
|
||||
id,
|
||||
userdata: {
|
||||
name,
|
||||
photo,
|
||||
}
|
||||
}
|
||||
}) => (
|
||||
<div className="control-bar user-bar">
|
||||
<div className="user-button">
|
||||
<UserPicture photo={photo} />
|
||||
|
||||
<div className="user-button-fields">
|
||||
<div className="user-button-name">{(name || id || '...')}</div>
|
||||
<div className="user-button-text">{(id || 'пользователь')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
10
src/components/user/UserPicture.jsx
Normal file
10
src/components/user/UserPicture.jsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import React from 'react';
|
||||
|
||||
export const UserPicture = ({ photo }) => (
|
||||
<div
|
||||
className="user-button-picture"
|
||||
style={{
|
||||
backgroundImage: `url(${photo})`
|
||||
}}
|
||||
/>
|
||||
);
|
5
src/constants/api.js
Normal file
5
src/constants/api.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
export const SERVER = 'http://alpha-map.vault48.org';
|
||||
export const API = {
|
||||
COMPOSE: `${SERVER}/engine/composerOrchid.php`,
|
||||
GET_GUEST: `${SERVER}/engine/auth.php`,
|
||||
};
|
19
src/constants/auth.js
Normal file
19
src/constants/auth.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
export const ROLES = {
|
||||
guest: 'guest',
|
||||
vk: 'vk',
|
||||
};
|
||||
|
||||
export const DEFAULT_USER = {
|
||||
new_messages: 0,
|
||||
place_types: {},
|
||||
random_url: '',
|
||||
role: ROLES.guest,
|
||||
routes: [],
|
||||
success: false,
|
||||
userdata: {
|
||||
name: '',
|
||||
agent: '',
|
||||
ip: '',
|
||||
photo: '',
|
||||
}
|
||||
};
|
|
@ -5,6 +5,10 @@ import { EditorPanel } from '$components/panels/EditorPanel';
|
|||
import { Fills } from '$components/Fills';
|
||||
import { DEFAULT_LOGO } from '$constants/logos';
|
||||
import { UserLocation } from '$components/UserLocation';
|
||||
import { DEFAULT_USER } from '$constants/auth';
|
||||
import { getGuestToken, checkUserToken } from '$utils/api';
|
||||
import { storeData, getData } from '$utils/storage';
|
||||
import { UserPanel } from '$components/panels/UserPanel';
|
||||
|
||||
export class App extends React.Component {
|
||||
state = {
|
||||
|
@ -14,8 +18,15 @@ export class App extends React.Component {
|
|||
totalDistance: 0,
|
||||
estimateTime: 0,
|
||||
activeSticker: null,
|
||||
user: {
|
||||
...DEFAULT_USER,
|
||||
},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.authInit();
|
||||
}
|
||||
|
||||
setMode = mode => {
|
||||
this.setState({ mode });
|
||||
};
|
||||
|
@ -48,11 +59,54 @@ export class App extends React.Component {
|
|||
setLogo: this.setLogo,
|
||||
});
|
||||
|
||||
authInit = () => {
|
||||
const user = this.getUserData();
|
||||
|
||||
const { id, token } = (user || {});
|
||||
const fallback = () => getGuestToken({ callback: this.setUser });
|
||||
|
||||
if (id && token) {
|
||||
console.log('checking');
|
||||
checkUserToken({
|
||||
callback: this.setUser,
|
||||
fallback,
|
||||
id,
|
||||
token
|
||||
});
|
||||
} else {
|
||||
getGuestToken({ callback: fallback });
|
||||
}
|
||||
};
|
||||
|
||||
setUser = user => {
|
||||
console.log('hup', user);
|
||||
if (!user.token || !user.id) return;
|
||||
|
||||
console.log('setting', user);
|
||||
|
||||
this.setState({
|
||||
user: {
|
||||
...DEFAULT_USER,
|
||||
...user,
|
||||
}
|
||||
});
|
||||
|
||||
this.storeUserData();
|
||||
};
|
||||
|
||||
storeUserData = () => {
|
||||
storeData('user', this.state.user);
|
||||
};
|
||||
|
||||
getUserData = () => {
|
||||
return getData('user') || null;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
editor,
|
||||
state: {
|
||||
mode, routerPoints, totalDistance, estimateTime, activeSticker, logo,
|
||||
mode, routerPoints, totalDistance, estimateTime, activeSticker, logo, user,
|
||||
},
|
||||
} = this;
|
||||
|
||||
|
@ -63,6 +117,11 @@ export class App extends React.Component {
|
|||
|
||||
<UserLocation editor={editor} />
|
||||
|
||||
<UserPanel
|
||||
user={user}
|
||||
setUser={this.setUser}
|
||||
/>
|
||||
|
||||
<EditorPanel
|
||||
editor={editor}
|
||||
mode={mode}
|
||||
|
@ -71,6 +130,7 @@ export class App extends React.Component {
|
|||
estimateTime={estimateTime}
|
||||
activeSticker={activeSticker}
|
||||
logo={logo}
|
||||
user={user}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { App } from '$containers/App';
|
||||
|
||||
import { App } from '$containers/App';
|
||||
import '$styles/main.less';
|
||||
|
||||
// import { Provider } from 'react-redux';
|
||||
// import { ConnectedRouter } from 'react-router-redux';
|
||||
// import { PersistGate } from 'redux-persist/integration/react';
|
||||
// import configureStore, { history } from '$redux/store';
|
||||
// const { store, persistor } = configureStore();
|
||||
|
||||
export const Index = () => (
|
||||
<App />
|
||||
);
|
||||
|
|
|
@ -46,6 +46,9 @@ export class Editor {
|
|||
},
|
||||
[MODES.STICKERS]: {
|
||||
toggle: this.clearSticker,
|
||||
},
|
||||
[MODES.TRASH]: {
|
||||
toggle: this.clearAll,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ export class Map {
|
|||
constructor({ container }) {
|
||||
this.map = map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
this.tileLayer = tileLayer(providers.dgis, {
|
||||
this.tileLayer = tileLayer(providers.default, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { getMergedImage } from '$utils/api';
|
||||
|
||||
export class Shotter {
|
||||
constructor({ map }) {
|
||||
|
@ -54,13 +55,8 @@ export class Shotter {
|
|||
}
|
||||
|
||||
makeShot = () => {
|
||||
// console.log('shot', this.getTilePlacement());
|
||||
const placement = this.getTilePlacement();
|
||||
|
||||
axios.get('http://alpha-map.vault48.org/engine/composerOrchid.php', {
|
||||
params: { placement }
|
||||
})
|
||||
.then(console.log)
|
||||
.catch(console.warn);
|
||||
getMergedImage(placement);
|
||||
}
|
||||
}
|
||||
|
|
0
src/redux/auth/actions.js
Normal file
0
src/redux/auth/actions.js
Normal file
15
src/redux/auth/constants.js
Normal file
15
src/redux/auth/constants.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
export const AUTH_ACTIONS = {
|
||||
|
||||
};
|
||||
|
||||
export const ROLES = {
|
||||
guest: 'guest',
|
||||
vk: 'vk',
|
||||
};
|
||||
|
||||
export const EMPTY_USER = {
|
||||
token: '',
|
||||
name: '',
|
||||
role: ROLES.guest,
|
||||
picture: '',
|
||||
};
|
12
src/redux/auth/reducer.js
Normal file
12
src/redux/auth/reducer.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { createReducer } from 'reduxsauce';
|
||||
import { AUTH_ACTIONS, EMPTY_USER } from '$redux/auth/constants';
|
||||
|
||||
const HANDLERS = {
|
||||
|
||||
};
|
||||
|
||||
export const INITIAL_STATE = {
|
||||
...EMPTY_USER
|
||||
};
|
||||
|
||||
export const authReducer = createReducer(INITIAL_STATE, HANDLERS);
|
4
src/redux/auth/sagas.js
Normal file
4
src/redux/auth/sagas.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
export function* authSaga() {
|
||||
// Login
|
||||
// yield takeLatest(AUTH_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga);
|
||||
}
|
50
src/redux/store.js
Normal file
50
src/redux/store.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
|
||||
|
||||
import { persistStore, persistReducer } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import createSagaMiddleware from 'redux-saga';
|
||||
import createHistory from 'history/createBrowserHistory';
|
||||
import { routerReducer, routerMiddleware } from 'react-router-redux';
|
||||
|
||||
import { authReducer } from '$redux/auth/reducer';
|
||||
import { authSaga } from '$redux/auth/sagas';
|
||||
|
||||
const authPersistConfig = {
|
||||
key: 'auth',
|
||||
blacklist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
// create the saga middleware
|
||||
export const sagaMiddleware = createSagaMiddleware();
|
||||
|
||||
// redux extension composer
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
const composeEnhancers =
|
||||
typeof window === 'object' &&
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
|
||||
: compose;
|
||||
/* eslint-enable no-underscore-dangle */
|
||||
|
||||
export const history = createHistory();
|
||||
|
||||
export const store = createStore(
|
||||
combineReducers({
|
||||
auth: persistReducer(authPersistConfig, authReducer),
|
||||
routing: routerReducer
|
||||
}),
|
||||
composeEnhancers(applyMiddleware(routerMiddleware(history), sagaMiddleware))
|
||||
);
|
||||
|
||||
export default function configureStore() {
|
||||
// run sagas
|
||||
sagaMiddleware.run(authSaga);
|
||||
|
||||
const persistor = persistStore(store);
|
||||
|
||||
return {
|
||||
store,
|
||||
persistor
|
||||
};
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
@import 'stickers.less';
|
||||
@import 'button.less';
|
||||
@import 'logo.less';
|
||||
@import 'user-button.less';
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
|
|
52
src/styles/user-button.less
Normal file
52
src/styles/user-button.less
Normal file
|
@ -0,0 +1,52 @@
|
|||
.user-bar {
|
||||
width: 200px;
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.user-button {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.user-button-picture {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
background: rgba(0,0,0,0.3);
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
.user-button-fields {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 0 10px 0 10px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
|
||||
div {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.user-button-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-button-text {
|
||||
font-size: 12px;
|
||||
opacity: 0.5;
|
||||
padding-top: 2px;
|
||||
font-weight: 200;
|
||||
}
|
33
src/utils/api.js
Normal file
33
src/utils/api.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import axios from 'axios/index';
|
||||
|
||||
import { API } from '$constants/api';
|
||||
|
||||
const report = console.warn;
|
||||
|
||||
export const checkUserToken = ({
|
||||
callback, fallback, id, token
|
||||
}) => (
|
||||
axios.get(API.GET_GUEST, {
|
||||
params: { action: 'check_token', id, token }
|
||||
})
|
||||
.then(result => (result && result.data))
|
||||
.then(data => ({ ...data, id, token }))
|
||||
.then(callback)
|
||||
.catch(fallback)
|
||||
);
|
||||
export const getGuestToken = ({ callback }) => (
|
||||
axios.get(API.GET_GUEST, {
|
||||
params: { action: 'gen_guest_token' }
|
||||
})
|
||||
.then(result => (result && result.data))
|
||||
.then(callback)
|
||||
.catch(report)
|
||||
);
|
||||
|
||||
export const getMergedImage = ({ placement, callback }) => (
|
||||
axios.get(API.COMPOSE, {
|
||||
params: { placement }
|
||||
})
|
||||
.then(callback)
|
||||
.catch(report)
|
||||
);
|
25
src/utils/storage.js
Normal file
25
src/utils/storage.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const canStore = typeof window.localStorage !== 'undefined'
|
||||
|
||||
export const storeData = (key, data) => {
|
||||
if (!canStore) return;
|
||||
|
||||
const value = JSON.stringify(data);
|
||||
|
||||
localStorage.setItem(key, value);
|
||||
};
|
||||
|
||||
export const getData = key => {
|
||||
if (!canStore) return;
|
||||
|
||||
let result = null;
|
||||
|
||||
try {
|
||||
result = JSON.parse(localStorage.getItem(key));
|
||||
} catch(e) {
|
||||
result = null;
|
||||
}
|
||||
|
||||
if (!result) return;
|
||||
|
||||
return result;
|
||||
};
|
32826
stats.json
32826
stats.json
File diff suppressed because one or more lines are too long
|
@ -50,7 +50,7 @@ const resolve = {
|
|||
module.exports = () => {
|
||||
/* Export */
|
||||
const plugins = [
|
||||
concatPlugin,
|
||||
// concatPlugin,
|
||||
htmlPlugin,
|
||||
// flowPlugin,
|
||||
gitPlugin,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue