Wiring up React Router routing and condensing entry points into SPA
This commit is contained in:
parent
a5043b3ea1
commit
a212863bf3
|
@ -2,10 +2,7 @@ from flask import Flask
|
|||
from flask_webpack import Webpack
|
||||
from werkzeug.serving import run_simple
|
||||
|
||||
from blueprints.reader import reader
|
||||
from blueprints.notes import notes
|
||||
from blueprints.editor import editor
|
||||
from blueprints.search import search
|
||||
from blueprints.joyce import joyce
|
||||
from blueprints.api import api
|
||||
|
||||
# Initialize application
|
||||
|
@ -25,11 +22,8 @@ webpack = Webpack()
|
|||
webpack.init_app(application)
|
||||
|
||||
# Register blueprints
|
||||
application.register_blueprint(reader)
|
||||
application.register_blueprint(editor, url_prefix='/edit')
|
||||
application.register_blueprint(joyce)
|
||||
application.register_blueprint(api, url_prefix='/api')
|
||||
application.register_blueprint(search, url_prefix='/search')
|
||||
application.register_blueprint(notes, url_prefix='/notes')
|
||||
|
||||
if __name__ == "__main__":
|
||||
# application.debug=True
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
from flask import Blueprint, render_template, abort
|
||||
from jinja2 import TemplateNotFound
|
||||
|
||||
editor = Blueprint('editor', __name__)
|
||||
|
||||
@editor.route('/')
|
||||
def show_reader():
|
||||
return render_template('editor.html')
|
|
@ -0,0 +1,11 @@
|
|||
from flask import Blueprint, render_template, abort, redirect
|
||||
from jinja2 import TemplateNotFound
|
||||
|
||||
joyce = Blueprint('joyce', __name__)
|
||||
|
||||
@joyce.route('/', defaults={'path': ''})
|
||||
def redirect_root(path):
|
||||
return redirect('/1')
|
||||
@joyce.route('/<path:path>')
|
||||
def show_joyce(path):
|
||||
return render_template('joyce.html')
|
|
@ -1,8 +0,0 @@
|
|||
from flask import Blueprint, render_template, abort
|
||||
from jinja2 import TemplateNotFound
|
||||
|
||||
notes = Blueprint('notes', __name__)
|
||||
|
||||
@notes.route('/')
|
||||
def show_reader():
|
||||
return render_template('notes.html')
|
|
@ -1,11 +0,0 @@
|
|||
from flask import Blueprint, render_template, abort, redirect
|
||||
from jinja2 import TemplateNotFound
|
||||
|
||||
reader = Blueprint('reader', __name__)
|
||||
|
||||
@reader.route('/', defaults={'path': ''})
|
||||
def redirect_root(path):
|
||||
return redirect('/1')
|
||||
@reader.route('/<path:path>')
|
||||
def show_reader(path):
|
||||
return render_template('reader.html')
|
|
@ -1,8 +0,0 @@
|
|||
from flask import Blueprint, render_template, abort
|
||||
from jinja2 import TemplateNotFound
|
||||
|
||||
search = Blueprint('search', __name__)
|
||||
|
||||
@search.route('/')
|
||||
def show_search():
|
||||
return render_template('search.html')
|
|
@ -19,9 +19,9 @@ export const ReaderAnnotateButton = ({onClick}) =>
|
|||
</button>
|
||||
</div>
|
||||
|
||||
export const ChapterButton = ({chapter, currentChapter, onClick}) =>
|
||||
export const ChapterButton = ({chapter, currentChapter, path}) =>
|
||||
<div className ='chapter_button text-center'>
|
||||
<Link to={'/'+ chapter.number} className={currentChapter.id === chapter.id ? 'btn btn-dark btn-lg active_button' : 'btn btn-outline-dark btn-lg inactive_button'}>
|
||||
<Link to={path + chapter.number} className={currentChapter.id === chapter.id ? 'btn btn-dark btn-lg active_button' : 'btn btn-outline-dark btn-lg inactive_button'}>
|
||||
{romanize(chapter.number)}. {chapter.title}
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import React from 'react'
|
||||
import { ChapterButton, NoteButton } from './button'
|
||||
|
||||
export const DocumentList = ({notes, chapters, currentDocument, onDocumentClick, docType}) =>
|
||||
export const DocumentList = ({notes, chapters, currentDocument, onDocumentClick, path, docType}) =>
|
||||
<div id='document_list'>
|
||||
{(docType === 'chapters' && chapters.length > 0) &&
|
||||
<ChapterList chapters={chapters} currentChapter={currentDocument} onChapterClick={onDocumentClick}/>
|
||||
<ChapterList chapters={chapters} currentChapter={currentDocument} path={path}/>
|
||||
}
|
||||
{(docType === 'notes' && notes.length > 0) &&
|
||||
<NoteList notes={notes} currentNote={currentDocument} onNoteClick={onDocumentClick}/>
|
||||
}
|
||||
</div>
|
||||
|
||||
export const ChapterList = ({chapters, currentChapter, onChapterClick}) =>
|
||||
export const ChapterList = ({chapters, currentChapter, path}) =>
|
||||
<div>
|
||||
{chapters.map(chapter =>
|
||||
<ChapterButton key={chapter.id} currentChapter={currentChapter} chapter={chapter} onClick={()=>onChapterClick(chapter.id, 'chapters')}/>
|
||||
<ChapterButton key={chapter.id} currentChapter={currentChapter} chapter={chapter} path={path}/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const Navbar = () =>
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
const Navbar = ({currentDocument}) =>
|
||||
<nav className='navbar navbar-dark navbar-static-top navbar-expand-lg'>
|
||||
<a className='navbar-brand' href='/'>The Joyce Project</a>
|
||||
<button className='navbar-toggler' type='button' data-toggle='collapse' data-target='#navbarItems'>
|
||||
|
@ -9,18 +12,24 @@ const Navbar = () =>
|
|||
<div id='navbarItems' className='collapse navbar-collapse'>
|
||||
<ul className='navbar-nav mr-auto'>
|
||||
<li className='nav-item'>
|
||||
<a className='nav-link' href='/edit'>Edit</a>
|
||||
<Link to='/edit' className='nav-link'>Edit</Link>
|
||||
</li>
|
||||
<li className='nav-item'>
|
||||
<a className='nav-link' href='/notes'>Notes</a>
|
||||
<Link to='/notes' className='nav-link'>Notes</Link>
|
||||
</li>
|
||||
<li className='nav-item'>
|
||||
<a className='nav-link' href='/search'>Search</a>
|
||||
<Link to='/search' className='nav-link'>Search</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
const string = "<li className='nav-item'><a className='nav-link' href='/search'>Search</a></li><li className='nav-item'><a className='nav-link' href='/about'>About</a></li>"
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
currentDocument: state.currentDocument,
|
||||
}
|
||||
}
|
||||
|
||||
const JoyceReaderPageContainer = connect(mapStateToProps)(JoyceReaderPage)
|
||||
|
||||
export default Navbar
|
|
@ -3,38 +3,28 @@ import { connect } from 'react-redux'
|
|||
import { EditorState } from 'draft-js'
|
||||
|
||||
import { deleteCurrentDocument, submitAnnotation, selectAnnotationNote } from '../actions/userActions'
|
||||
import Navbar from '../components/navbar'
|
||||
import Content from '../components/content'
|
||||
import DeleteConfirmModal from '../components/deleteConfirmModal'
|
||||
import AnnotateModal from '../components/annotateModal'
|
||||
import AnnotationModal from '../components/annotationModal'
|
||||
import { EditorWelcome } from '../components/welcome'
|
||||
import LoadingSpinner from '../components/loadingSpinner'
|
||||
import JoyceEditorSidebarContainer from '../containers/joyceEditorSidebarContainer'
|
||||
import JoyceEditorContentContainer from '../containers/joyceEditorContentContainer'
|
||||
|
||||
const JoyceEditorPage = ({notes, currentDocument, docType, annotationNote, onDeleteClick, onSubmitAnnotationClick, selectAnnotationNote, selectionState, editorState, loadingToggle}) =>
|
||||
<div>
|
||||
<Navbar />
|
||||
<div id='joyce_reader' className='container-fluid'>
|
||||
<div className="row">
|
||||
<JoyceEditorSidebarContainer />
|
||||
<Content>
|
||||
{loadingToggle === true &&
|
||||
<LoadingSpinner size={4} />
|
||||
}
|
||||
{(Object.keys(currentDocument).length > 0 && loadingToggle === false) &&
|
||||
<JoyceEditorContentContainer />
|
||||
}
|
||||
{(Object.keys(currentDocument).length === 0 && loadingToggle === false) &&
|
||||
<EditorWelcome />
|
||||
}
|
||||
</Content>
|
||||
</div>
|
||||
<div id='joyce_reader' className='container-fluid'>
|
||||
<div className="row">
|
||||
<JoyceEditorSidebarContainer />
|
||||
<Content>
|
||||
{loadingToggle === true &&
|
||||
<LoadingSpinner size={4} />
|
||||
}
|
||||
{(Object.keys(currentDocument).length > 0 && loadingToggle === false) &&
|
||||
<JoyceEditorContentContainer />
|
||||
}
|
||||
{(Object.keys(currentDocument).length === 0 && loadingToggle === false) &&
|
||||
<EditorWelcome />
|
||||
}
|
||||
</Content>
|
||||
</div>
|
||||
<DeleteConfirmModal onDeleteClick={()=>onDeleteClick(currentDocument.id, docType)}/>
|
||||
<AnnotateModal notes={notes} annotationNote={annotationNote} onSubmitClick={()=>onSubmitAnnotationClick(annotationNote, selectionState, editorState)} selectAnnotationNote={selectAnnotationNote} />
|
||||
<AnnotationModal annotationNote={annotationNote} />
|
||||
</div>
|
||||
|
||||
const mapStateToProps = state => {
|
||||
|
|
|
@ -13,7 +13,7 @@ const JoyceEditorSidebar = ({notes, chapters, docType, currentDocument, onDocume
|
|||
<SidebarSpacer />
|
||||
<NewDocumentButton onClick={()=>onNewDocumentClick(docType)} docType={docType}/>
|
||||
<SidebarSpacer />
|
||||
<DocumentList notes={notes} chapters={chapters} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} />
|
||||
<DocumentList notes={notes} chapters={chapters} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} path={'/edit/'}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -22,7 +22,7 @@ const mapStateToProps = state => {
|
|||
notes: state.notes,
|
||||
chapters: state.chapters,
|
||||
docType: state.docType,
|
||||
currentDocument: state.currentDocument
|
||||
currentDocument: state.currentDocument,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,44 +1,35 @@
|
|||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Route } from 'react-router'
|
||||
import { EditorState } from 'draft-js'
|
||||
|
||||
import Navbar from '../components/navbar'
|
||||
import Content from '../components/content'
|
||||
import AnnotationModal from '../components/annotationModal'
|
||||
import { ReaderWelcome } from '../components/welcome'
|
||||
import LoadingSpinner from '../components/loadingSpinner'
|
||||
import JoyceReaderSidebarContainer from '../containers/joyceReaderSidebarContainer'
|
||||
import JoyceReaderContentContainer from '../containers/joyceReaderContentContainer'
|
||||
|
||||
const JoyceReaderPage = ({currentDocument, loadingToggle, annotationNote}) =>
|
||||
<div>
|
||||
<Navbar />
|
||||
<div id='joyce_reader' className='container-fluid'>
|
||||
<Route path='/'>
|
||||
<div className="row">
|
||||
<JoyceReaderSidebarContainer />
|
||||
<Content>
|
||||
{loadingToggle === true &&
|
||||
<LoadingSpinner size={4} />
|
||||
}
|
||||
{(Object.keys(currentDocument).length > 0 && loadingToggle === false) &&
|
||||
<JoyceReaderContentContainer />
|
||||
}
|
||||
{(Object.keys(currentDocument).length === 0 && loadingToggle === false) &&
|
||||
<ReaderWelcome />
|
||||
}
|
||||
</Content>
|
||||
</div>
|
||||
</Route>
|
||||
const JoyceReaderPage = ({currentDocument, loadingToggle}) =>
|
||||
<div id='joyce_reader' className='container-fluid'>
|
||||
<div className="row">
|
||||
<JoyceReaderSidebarContainer />
|
||||
<Content>
|
||||
{loadingToggle === true &&
|
||||
<LoadingSpinner size={4} />
|
||||
}
|
||||
{(Object.keys(currentDocument).length > 0 && loadingToggle === false) &&
|
||||
<JoyceReaderContentContainer />
|
||||
}
|
||||
{(Object.keys(currentDocument).length === 0 && loadingToggle === false) &&
|
||||
<ReaderWelcome />
|
||||
}
|
||||
</Content>
|
||||
</div>
|
||||
<AnnotationModal annotationNote={annotationNote} />
|
||||
</div>
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
loadingToggle: state.loadingToggle,
|
||||
currentDocument: state.currentDocument,
|
||||
annotationNote: state.annotationNote
|
||||
loadingToggle: state.loadingToggle
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ const JoyceReaderSidebar = ({chapters, notes, currentDocument, onDocumentClick,
|
|||
<div>
|
||||
<HighlightButton highlightToggle={highlightToggle} onClick={onHighlightClick}/>
|
||||
<SidebarSpacer />
|
||||
<DocumentList chapters={chapters} notes={notes} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} />
|
||||
<DocumentList chapters={chapters} notes={notes} currentDocument={currentDocument} onDocumentClick={onDocumentClick} docType={docType} path={'/'}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const Navbar = () =>
|
||||
<nav className='navbar navbar-dark navbar-static-top navbar-expand-lg'>
|
||||
<a className='navbar-brand' href='/'>The Joyce Project</a>
|
||||
<button className='navbar-toggler' type='button' data-toggle='collapse' data-target='#navbarItems'>
|
||||
<span className='navbar-toggler-icon'></span>
|
||||
</button>
|
||||
<div id='navbarItems' className='collapse navbar-collapse'>
|
||||
<ul className='navbar-nav mr-auto'>
|
||||
<li className='nav-item'>
|
||||
<Link to='/edit' className='nav-link'>Edit</Link>
|
||||
</li>
|
||||
<li className='nav-item'>
|
||||
<Link to='/notes' className='nav-link'>Notes</Link>
|
||||
</li>
|
||||
<li className='nav-item'>
|
||||
<Link to='/search' className='nav-link'>Search</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
export default Navbar
|
|
@ -1,42 +0,0 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import 'bootstrap'
|
||||
|
||||
import reduceEditor from './reducers/reduceEditor'
|
||||
import { getDocumentList } from './actions/apiActions'
|
||||
import { setCurrentDocument, setDocType } from './actions/userActions'
|
||||
import { joyceAPI, logger } from './middleware/'
|
||||
import { getFirstDocument } from './mixins/firstDocument'
|
||||
import JoyceEditorPageContainer from './containers/joyceEditorPageContainer'
|
||||
|
||||
const docType = 'chapters'
|
||||
const store = createStore(reduceEditor, applyMiddleware(joyceAPI, logger))
|
||||
store.dispatch(setDocType(docType))
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<JoyceEditorPageContainer />
|
||||
</Provider>,
|
||||
document.getElementById('wrapper')
|
||||
)
|
||||
|
||||
store.dispatch(getDocumentList({docType: 'notes'}))
|
||||
store.dispatch(getDocumentList({
|
||||
docType: docType,
|
||||
state: 'currentDocType'
|
||||
}))
|
||||
|
||||
// TODO: Remove when
|
||||
// API can handle number lookups
|
||||
// Routing can handle / => /1
|
||||
setTimeout(
|
||||
() => {
|
||||
const firstDocument = getFirstDocument(store, docType)
|
||||
if (firstDocument) {
|
||||
store.dispatch(setCurrentDocument(firstDocument.id, docType))
|
||||
}
|
||||
},
|
||||
1000
|
||||
)
|
|
@ -0,0 +1,71 @@
|
|||
// node_modules
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import { Route, Redirect } from 'react-router'
|
||||
import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux'
|
||||
import createHistory from 'history/createBrowserHistory'
|
||||
import 'bootstrap'
|
||||
|
||||
// src packages
|
||||
import Navbar from './containers/navbar'
|
||||
import reduceReader from './reducers/reduceReader'
|
||||
import { selectAnnotationNote } from './actions/userActions'
|
||||
import { getDocumentList } from './actions/apiActions'
|
||||
import DeleteConfirmModal from './components/deleteConfirmModal'
|
||||
import AnnotateModal from './components/annotateModal'
|
||||
import AnnotationModal from './components/annotationModal'
|
||||
import { setCurrentDocument, setDocType } from './actions/userActions'
|
||||
import { logger, joyceAPI } from './middleware/'
|
||||
import { getFirstDocument } from './mixins/firstDocument'
|
||||
import JoyceReaderPageContainer from './containers/joyceReaderPageContainer'
|
||||
import JoyceEditorPageContainer from './containers/joyceEditorPageContainer'
|
||||
|
||||
// TODO: Pass routing from Flask?
|
||||
|
||||
const history = createHistory()
|
||||
const router = routerMiddleware(history)
|
||||
|
||||
const docType = 'chapters'
|
||||
const store = createStore(reduceReader, applyMiddleware(logger, joyceAPI, router))
|
||||
store.dispatch(setDocType(docType))
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<div>
|
||||
<Navbar />
|
||||
<Route exact path='/edit' render={() => {
|
||||
const currentDocument = store.getState().currentDocument
|
||||
if (store.getState().docType === 'chapters') {
|
||||
if (currentDocument.id) {
|
||||
return <Redirect to={'/edit/' + currentDocument.number}/>
|
||||
} else {
|
||||
return <Redirect to={'/edit/1'}/>
|
||||
}
|
||||
}
|
||||
}}/>
|
||||
<Route exact path='/notes' render={() => {
|
||||
if (store.getState().notes[0]) {
|
||||
return <Redirect to={'/notes/' + store.getState().notes[0].id} />
|
||||
}
|
||||
return <JoyceReaderPageContainer />
|
||||
}}/>
|
||||
<Route exact path='/notes/:id' component={JoyceReaderPageContainer} />
|
||||
<Route exact path='/edit/:id' component={JoyceEditorPageContainer} />
|
||||
<Route exact path='/:id' component={JoyceReaderPageContainer} />
|
||||
<DeleteConfirmModal onDeleteClick={()=>onDeleteClick(currentDocument.id, docType)}/>
|
||||
<AnnotateModal notes={store.getState().notes} annotationNote={store.getState().annotationNote} onSubmitClick={()=>onSubmitAnnotationClick(store.getState().annotationNote, store.getState().selectionState, store.getState().editorState)} selectAnnotationNote={selectAnnotationNote} />
|
||||
<AnnotationModal annotationNote={store.getState().annotationNote} />
|
||||
</div>
|
||||
</ConnectedRouter>
|
||||
</Provider>,
|
||||
document.getElementById('wrapper')
|
||||
)
|
||||
|
||||
store.dispatch(getDocumentList({
|
||||
docType: docType,
|
||||
state: 'initialPageLoad'
|
||||
}))
|
||||
store.dispatch(getDocumentList({docType: 'notes'}))
|
|
@ -58,10 +58,17 @@ const selectChapterIDByNumber = (store, number) => {
|
|||
}
|
||||
|
||||
const parseNumberFromPath = path => {
|
||||
const match = /^\/([0-9]*)/.exec(path)
|
||||
const number = Number(match[1])
|
||||
console.log('Hey!', number)
|
||||
return number
|
||||
const match = /\/([0-9]*)$/.exec(path)
|
||||
if (match) {
|
||||
if (parseInt(match[1])) {
|
||||
const number = Number(match[1])
|
||||
return number
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// API Middleware
|
||||
|
@ -75,12 +82,14 @@ export const joyceAPI = store => next => action => {
|
|||
store.dispatch(getDocumentList(response))
|
||||
)
|
||||
}
|
||||
if (action.status === 'success' && action.state === 'initialPageLoad') {
|
||||
HTTPGetDocumentList(action.docType, action.state).then(response => {
|
||||
const pathName = store.getState().routerReducer.location.pathname
|
||||
store.dispatch(setCurrentDocument(selectChapterIDByNumber(store, parseNumberFromPath(pathName)), action.docType))
|
||||
})
|
||||
}
|
||||
if (action.status === 'success' && action.docType === store.getState().docType && !store.getState().currentDocument.id) {
|
||||
if (action.docType === 'chapters') {
|
||||
const pathNumber = parseNumberFromPath(store.getState().routerReducer.location.pathname)
|
||||
store.dispatch(setCurrentDocument(selectChapterIDByNumber(store, pathNumber), action.docType))
|
||||
} else if (action.docType === 'notes') {
|
||||
store.dispatch(setCurrentDocument(store.getState().notes[0].id, action.docType))
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'GET_DOCUMENT_TEXT':
|
||||
if (action.status === 'request') {
|
||||
|
@ -167,9 +176,10 @@ export const joyceAPI = store => next => action => {
|
|||
}
|
||||
break
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
if (/^\/[0-9]*/.test(action.payload.pathname)) {
|
||||
const pathNumber = parseNumberFromPath(action.payload.pathname)
|
||||
if (pathNumber) {
|
||||
for (const chapter of store.getState().chapters) {
|
||||
if (action.payload.pathname === '/' + chapter.number) {
|
||||
if (pathNumber === chapter.number) {
|
||||
store.dispatch(setCurrentDocument(chapter.id, 'chapters'))
|
||||
}
|
||||
}
|
||||
|
|
39
src/notes.js
39
src/notes.js
|
@ -1,39 +0,0 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import 'bootstrap'
|
||||
|
||||
import reduceReader from './reducers/reduceReader'
|
||||
import { getDocumentList } from './actions/apiActions'
|
||||
import { setCurrentDocument, setDocType } from './actions/userActions'
|
||||
import { logger, joyceAPI } from './middleware/'
|
||||
import { getFirstDocument } from './mixins/firstDocument'
|
||||
import JoyceReaderPageContainer from './containers/joyceReaderPageContainer'
|
||||
|
||||
// TODO: Pass routing from Flask?
|
||||
|
||||
let docType = 'notes'
|
||||
let store = createStore(reduceReader, applyMiddleware(logger, joyceAPI))
|
||||
store.dispatch(setDocType(docType))
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<JoyceReaderPageContainer />
|
||||
</Provider>,
|
||||
document.getElementById('wrapper')
|
||||
)
|
||||
|
||||
store.dispatch(getDocumentList({docType: docType}))
|
||||
|
||||
// Hacky way to fetch first chapter after async call above has completed.
|
||||
// TODO: Add number lookup to API?
|
||||
setTimeout(
|
||||
() => {
|
||||
const firstDocument = getFirstDocument(store, docType)
|
||||
if (firstDocument) {
|
||||
store.dispatch(setCurrentDocument(firstDocument.id, docType))
|
||||
}
|
||||
},
|
||||
1000
|
||||
)
|
|
@ -1,42 +0,0 @@
|
|||
// node_modules
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux'
|
||||
import createHistory from 'history/createBrowserHistory'
|
||||
// import 'bootstrap'
|
||||
|
||||
// src packages
|
||||
import reduceReader from './reducers/reduceReader'
|
||||
import { getDocumentList } from './actions/apiActions'
|
||||
import { setCurrentDocument, setDocType } from './actions/userActions'
|
||||
import { logger, joyceAPI } from './middleware/'
|
||||
import { getFirstDocument } from './mixins/firstDocument'
|
||||
import JoyceReaderPageContainer from './containers/joyceReaderPageContainer'
|
||||
import JoyceEditorPageContainer from './containers/joyceEditorPageContainer'
|
||||
|
||||
// TODO: Pass routing from Flask?
|
||||
|
||||
const history = createHistory()
|
||||
const router = routerMiddleware(history)
|
||||
|
||||
const docType = 'chapters'
|
||||
const store = createStore(reduceReader, applyMiddleware(logger, joyceAPI, router))
|
||||
store.dispatch(setDocType(docType))
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<div>
|
||||
<JoyceReaderPageContainer />
|
||||
</div>
|
||||
</ConnectedRouter>
|
||||
</Provider>,
|
||||
document.getElementById('wrapper')
|
||||
)
|
||||
|
||||
store.dispatch(getDocumentList({
|
||||
docType: docType,
|
||||
state: 'initialPageLoad'
|
||||
}))
|
|
@ -2,6 +2,11 @@ const docType = (state=null, action) => {
|
|||
switch(action.type) {
|
||||
case 'SET_DOC_TYPE':
|
||||
return action.docType
|
||||
case '@@router/LOCATION_CHANGE':
|
||||
const path = action.payload.pathname
|
||||
if (/^\/(notes).*/.exec(path)) {
|
||||
return 'notes'
|
||||
} else { return state }
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import { combineReducers } from 'redux'
|
||||
|
||||
import notes from './notes'
|
||||
import chapters from './chapters'
|
||||
import currentDocument from './currentDocument'
|
||||
import docType from './docType'
|
||||
import mode from './mode'
|
||||
import documentTitleInput from './documentTitleInput'
|
||||
import editorState from './editorState'
|
||||
import selectionState from './selectionState'
|
||||
import annotationNote from './annotationNote'
|
||||
import loadingToggle from './loadingToggle'
|
||||
|
||||
const reduceDocuments = combineReducers({
|
||||
notes,
|
||||
chapters,
|
||||
currentDocument,
|
||||
annotationNote,
|
||||
mode,
|
||||
documentTitleInput,
|
||||
editorState,
|
||||
docType,
|
||||
selectionState,
|
||||
loadingToggle
|
||||
})
|
||||
|
||||
export default reduceDocuments
|
|
@ -9,7 +9,8 @@ import highlightToggle from './highlightToggle'
|
|||
import loadingToggle from './loadingToggle'
|
||||
import docType from './docType'
|
||||
import { routerReducer } from 'react-router-redux'
|
||||
|
||||
import mode from './mode'
|
||||
import documentTitleInput from './documentTitleInput'
|
||||
|
||||
const reduceReader = combineReducers({
|
||||
chapters,
|
||||
|
@ -20,7 +21,9 @@ const reduceReader = combineReducers({
|
|||
currentDocument,
|
||||
highlightToggle,
|
||||
loadingToggle,
|
||||
routerReducer
|
||||
routerReducer,
|
||||
mode,
|
||||
documentTitleInput
|
||||
})
|
||||
|
||||
export default reduceReader
|
|
@ -1,22 +0,0 @@
|
|||
@import "variables";
|
||||
@import "window";
|
||||
@import "navbar";
|
||||
@import "sidebar";
|
||||
@import "page";
|
||||
@import "node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
$fa-font-path: "../../node_modules/font-awesome/fonts";
|
||||
@import "node_modules/font-awesome/scss/font-awesome";
|
||||
|
||||
#joyce_reader {
|
||||
overflow: hidden;
|
||||
width: 95%;
|
||||
height: 100%;
|
||||
background-color: rgba(256,256,256,0.5);
|
||||
border-left: 1px solid $border_color;
|
||||
border-right: 1px solid $border_color;
|
||||
}
|
||||
|
||||
#joyce_reader > div {
|
||||
margin-top: 0.5em;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<!doctype html>
|
||||
<head>
|
||||
<title>Joyce - Editor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
<link rel="icon" href="{{ url_for('static', filename='icon.png') }}" type="image/png">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Reader Layout -->
|
||||
<div id="wrapper">
|
||||
</div>
|
||||
<!-- Scripts -->
|
||||
<script src="{{asset_url_for('editor.js')}}"></script>
|
||||
</body>
|
|
@ -11,5 +11,5 @@
|
|||
<div id="wrapper">
|
||||
</div>
|
||||
<!-- Scripts -->
|
||||
<script src="{{asset_url_for('reader.js')}}"></script>
|
||||
<script src="{{asset_url_for('joyce.js')}}"></script>
|
||||
</body>
|
|
@ -1,15 +0,0 @@
|
|||
<!doctype html>
|
||||
<head>
|
||||
<title>Joyce - Notes</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="manifest" href="static/manifest.json">
|
||||
<link rel="icon" href="{{ url_for('static', filename='icon.png') }}" type="image/png">
|
||||
<link rel="icon" type="image/png" href="static/image/icon.png">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Reader Layout -->
|
||||
<div id="wrapper">
|
||||
</div>
|
||||
<!-- Scripts -->
|
||||
<script src="{{asset_url_for('notes.js')}}"></script>
|
||||
</body>
|
|
@ -1,14 +0,0 @@
|
|||
<!doctype html>
|
||||
<head>
|
||||
<title>Joyce - Search</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="{{ url_for('static', filename='icon.png') }}" type="image/png">
|
||||
<link rel="manifest" href="static/manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Reader Layout -->
|
||||
<div id="wrapper">
|
||||
</div>
|
||||
<!-- Scripts -->
|
||||
<script src="{{asset_url_for('search.js')}}"></script>
|
||||
</body>
|
|
@ -7,21 +7,9 @@ const rootAssetPath = './src/'
|
|||
|
||||
module.exports = {
|
||||
entry: {
|
||||
reader: [
|
||||
rootAssetPath + 'reader',
|
||||
rootAssetPath + 'stylesheets/' + 'reader.scss'
|
||||
],
|
||||
editor: [
|
||||
rootAssetPath + 'editor',
|
||||
rootAssetPath + 'stylesheets/' + 'editor.scss'
|
||||
],
|
||||
notes: [
|
||||
rootAssetPath + 'notes',
|
||||
rootAssetPath + 'stylesheets/' + 'reader.scss'
|
||||
],
|
||||
search: [
|
||||
rootAssetPath + 'search',
|
||||
rootAssetPath + 'stylesheets/' + 'search.scss'
|
||||
joyce: [
|
||||
rootAssetPath + 'joyce',
|
||||
rootAssetPath + 'stylesheets/' + 'joyce.scss'
|
||||
]
|
||||
},
|
||||
module : {
|
||||
|
@ -78,11 +66,12 @@ module.exports = {
|
|||
new ManifestRevisionPlugin(path.join('static/', 'manifest.json'), {
|
||||
rootAssetPath: rootAssetPath
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
jQuery: 'jquery',
|
||||
'window.jQuery': 'jquery',
|
||||
Popper: ['popper.js', 'default']
|
||||
}),
|
||||
// new webpack.ProvidePlugin({
|
||||
// bootstrap: 'bootstrap'
|
||||
// $: 'jquery',
|
||||
// jQuery: 'jquery',
|
||||
// 'window.jQuery': 'jquery',
|
||||
// Popper: ['popper.js', 'default']
|
||||
// }),
|
||||
],
|
||||
};
|
Loading…
Reference in New Issue