diff options
Diffstat (limited to 'frontend/app/site')
| -rw-r--r-- | frontend/app/site/actions.js | 19 | ||||
| -rw-r--r-- | frontend/app/site/app.js | 33 | ||||
| -rw-r--r-- | frontend/app/site/index.js | 17 | ||||
| -rw-r--r-- | frontend/app/site/site/site.actions.js | 11 | ||||
| -rw-r--r-- | frontend/app/site/site/site.reducer.js | 36 | ||||
| -rw-r--r-- | frontend/app/site/store.js | 37 | ||||
| -rw-r--r-- | frontend/app/site/types.js | 11 | ||||
| -rw-r--r-- | frontend/app/site/viewer/viewer.container.js | 96 |
8 files changed, 260 insertions, 0 deletions
diff --git a/frontend/app/site/actions.js b/frontend/app/site/actions.js new file mode 100644 index 0000000..e672028 --- /dev/null +++ b/frontend/app/site/actions.js @@ -0,0 +1,19 @@ +import { bindActionCreators } from 'redux' +// import { actions as crudActions } from './api' + +import * as siteActions from './site/site.actions' + +import { store } from './store' + +export default + // Object.keys(crudActions) + // .map(a => [a, crudActions[a]]) + // .concat( + [ + ['site', siteActions], + ] //) + .map(p => [p[0], bindActionCreators(p[1], store.dispatch)]) + .concat([ + // ['socket', socketActions], + ]) + .reduce((a,b) => (a[b[0]] = b[1])&&a,{})
\ No newline at end of file diff --git a/frontend/app/site/app.js b/frontend/app/site/app.js new file mode 100644 index 0000000..cf52460 --- /dev/null +++ b/frontend/app/site/app.js @@ -0,0 +1,33 @@ +import React, { Component } from 'react' +import { ConnectedRouter } from 'connected-react-router' +import { Route } from 'react-router' + +import ViewerContainer from './viewer/viewer.container' +import actions from './actions' + +export default class App extends Component { + componentDidMount() { + const path_partz = window.location.pathname.split('/') + const graph_name = path_partz[1] + let path_name = null + if (path_partz.length > 2) { + path_name = path_partz[2] + } + // console.log('loading', graph_name, path_name) + actions.site.loadSite(graph_name, path_name) + } + + render() { + return ( + <ConnectedRouter history={this.props.history}> + <div className='app'> + <Route path={'/:graph_name/:page_name'} component={ViewerContainer} exact /> + <Route exact key='root' path='/' render={() => { + // setTimeout(() => this.props.history.push('/'), 10) + return null + }} /> + </div> + </ConnectedRouter> + ) + } +} diff --git a/frontend/app/site/index.js b/frontend/app/site/index.js new file mode 100644 index 0000000..6f1a0a5 --- /dev/null +++ b/frontend/app/site/index.js @@ -0,0 +1,17 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import { Provider } from 'react-redux' + +import App from './app' + +import { store, history } from './store' + +const container = document.createElement('div') +container.classList.add('container') +document.body.appendChild(container) + +ReactDOM.render( + <Provider store={store}> + <App history={history} /> + </Provider>, container +) diff --git a/frontend/app/site/site/site.actions.js b/frontend/app/site/site/site.actions.js new file mode 100644 index 0000000..2eea442 --- /dev/null +++ b/frontend/app/site/site/site.actions.js @@ -0,0 +1,11 @@ +import * as types from 'app/types' +import { api } from 'app/utils' + +export const setSiteTitle = title => dispatch => { + document.querySelector('title').innerText = title + dispatch({ type: types.site.set_site_title, payload: title }) +} + +export const loadSite = (graph_name, path_name) => dispatch => ( + api(dispatch, types.site, 'site', '/' + graph_name + '/index.json') +) diff --git a/frontend/app/site/site/site.reducer.js b/frontend/app/site/site/site.reducer.js new file mode 100644 index 0000000..85c3486 --- /dev/null +++ b/frontend/app/site/site/site.reducer.js @@ -0,0 +1,36 @@ +import * as types from '../types' + +const initialState = { + siteTitle: 'swimmer', + graph: { + loading: true, + } +} + +export default function siteReducer(state = initialState, action) { + console.log(action.type, action) + switch (action.type) { + case types.site.set_site_title: + return { + ...state, + siteTitle: action.payload, + } + + case types.site.loaded: + return { + ...state, + graph: action.data.graph, + } + + case '@@router/LOCATION_CHANGE': + return { + ...state, + graph: { + ...state.graph, + } + } + + default: + return state + } +} diff --git a/frontend/app/site/store.js b/frontend/app/site/store.js new file mode 100644 index 0000000..a228e2b --- /dev/null +++ b/frontend/app/site/store.js @@ -0,0 +1,37 @@ +import { applyMiddleware, compose, combineReducers, createStore } from 'redux' +import { connectRouter, routerMiddleware } from 'connected-react-router' +import { createBrowserHistory } from 'history' +import thunk from 'redux-thunk' + +import siteReducer from './site/site.reducer' + +const createRootReducer = history => ( + combineReducers({ + auth: (state = {}) => state, + router: connectRouter(history), + site: siteReducer, + }) +) + +const configureStore = (initialState = {}, history) => { + const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose + + const store = createStore( + createRootReducer(history), + initialState, + composeEnhancers( + applyMiddleware( + thunk, + routerMiddleware(history) + ), + ), + ) + + return store +} + +const history = createBrowserHistory() +const store = configureStore({}, history) +const { dispatch } = store + +export { store, history, dispatch } diff --git a/frontend/app/site/types.js b/frontend/app/site/types.js new file mode 100644 index 0000000..23bed98 --- /dev/null +++ b/frontend/app/site/types.js @@ -0,0 +1,11 @@ +import { with_type, crud_type } from 'app/api/crud.types' + +export const site = with_type('site', [ + 'set_site_title', 'loading', 'loaded', 'error', +]) + +export const system = with_type('system', [ + 'load_site', +]) + +export const init = '@@INIT' diff --git a/frontend/app/site/viewer/viewer.container.js b/frontend/app/site/viewer/viewer.container.js new file mode 100644 index 0000000..42ce6c2 --- /dev/null +++ b/frontend/app/site/viewer/viewer.container.js @@ -0,0 +1,96 @@ +import React, { Component } from 'react' +import { Route } from 'react-router-dom' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import actions from '../actions' +import { Loader } from 'app/common/loader.component' +import TileHandle from 'app/views/page/components/tile.handle' + +import '../../views/page/page.css' + +class ViewerContainer extends Component { + state = { + page: {}, + } + + constructor(props) { + super(props) + this.pageRef = React.createRef() + this.handleMouseDown = this.handleMouseDown.bind(this) + } + + componentDidUpdate(prevProps) { + // console.log('didUpdate', this.props.graph !== prevProps.graph, this.props.location.pathname !== prevProps.location.pathname) + if (this.props.graph !== prevProps.graph || this.props.location.pathname !== prevProps.location.pathname) { + this.load() + } + } + + load() { + const { graph_name, page_name } = this.props.match.params + const page_path = ["", graph_name, page_name].join('/') + const { pages, home_page } = this.props.graph + const page = pages[page_path] + if (!page) { + // console.log('-> home page') + console.log(page_path) + const { home_page } = this.props.graph + this.setState({ page: pages[home_page] }) + } else { + // console.log(page) + console.log(page_path) + this.setState({ page }) + } + } + + handleMouseDown(e, tile) { + // console.log(tile) + } + + render() { + const { page } = this.state + if (this.props.graph.loading || !page.id) { + return ( + <div> + <div className='body'> + <div className='page loading'> + <Loader /> + </div> + </div> + </div> + ) + } + const { settings } = page + const pageStyle = { backgroundColor: settings ? settings.background_color : '#000000' } + // console.log(page) + return ( + <div className='body'> + <div className='page' ref={this.pageRef} style={pageStyle}> + {page.tiles.map(tile => { + return ( + <TileHandle + viewing + key={tile.id} + tile={tile} + bounds={this.state.bounds} + onMouseDown={e => this.handleMouseDown(e, tile)} + onDoubleClick={e => {}} + /> + ) + })} + </div> + </div> + ) + } +} + +const mapStateToProps = state => ({ + site: state.site, + graph: state.site.graph, +}) + +const mapDispatchToProps = dispatch => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(ViewerContainer) |
