Incorporated DraftJS and refactored the reducers
This commit is contained in:
parent
7e2ec994f7
commit
287f15380a
20
TODO.txt
20
TODO.txt
|
@ -6,8 +6,20 @@
|
||||||
+ Front-End Dependency Manager +
|
+ Front-End Dependency Manager +
|
||||||
- Wire React to ES API
|
- Wire React to ES API
|
||||||
- Simple CRUID interface
|
- Simple CRUID interface
|
||||||
- Orchestrate Environment Configs
|
|
||||||
- Basic Testing
|
Short List:
|
||||||
|
- Some Testing
|
||||||
|
- Env Configs
|
||||||
|
- Collapsable Button Lists
|
||||||
|
- Draft.JS
|
||||||
|
- DRY up Sass Modules
|
||||||
|
- Async API Middleware
|
||||||
|
- CombineReducers in App.js
|
||||||
|
- Import Actions into Reducers
|
||||||
|
- PropTypes
|
||||||
|
|
||||||
|
- Loading Indicators
|
||||||
|
|
||||||
|
|
||||||
- v0.2 Reader
|
- v0.2 Reader
|
||||||
- Reader UX
|
- Reader UX
|
||||||
|
@ -20,7 +32,7 @@
|
||||||
|
|
||||||
- Error Handling
|
- Error Handling
|
||||||
- Unit Testing
|
- Unit Testing
|
||||||
- Remove Flask-Webpack
|
- Remove Flask-Webpack?
|
||||||
- Admin Access Restrictions (OAuth?)
|
- Admin Access Restrictions (OAuth?)
|
||||||
- Admin Page
|
- Admin Page
|
||||||
- Search Functionality
|
- Search Functionality
|
||||||
|
@ -35,3 +47,5 @@
|
||||||
- Maintain old version of Joyce Project? (unlikely)
|
- Maintain old version of Joyce Project? (unlikely)
|
||||||
- Weed out unneeded dependencies
|
- Weed out unneeded dependencies
|
||||||
- Implement a pixel to track usage
|
- Implement a pixel to track usage
|
||||||
|
- Default Pagination?
|
||||||
|
- ARIA compliance
|
|
@ -12,6 +12,7 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "^4.0.0-beta.2",
|
"bootstrap": "^4.0.0-beta.2",
|
||||||
|
"draft-js": "^0.10.4",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"popper.js": "^1.12.6",
|
"popper.js": "^1.12.6",
|
||||||
"react": "^16.0.0",
|
"react": "^16.0.0",
|
||||||
|
|
|
@ -4,12 +4,19 @@ const setCurrentChapter = id =>
|
||||||
id: id
|
id: id
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleHighlight = id =>
|
const toggleHighlight = () =>
|
||||||
({
|
({
|
||||||
type: 'TOGGLE_HIGHLIGHT'
|
type: 'TOGGLE_HIGHLIGHT'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const updateEditorState = editorState =>
|
||||||
|
({
|
||||||
|
type: 'UPDATE_EDITOR_STATE',
|
||||||
|
payload: editorState
|
||||||
|
})
|
||||||
|
|
||||||
export {
|
export {
|
||||||
setCurrentChapter,
|
setCurrentChapter,
|
||||||
toggleHighlight
|
toggleHighlight,
|
||||||
|
updateEditorState
|
||||||
}
|
}
|
|
@ -1,8 +1,17 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
|
const ChapterNavButton = () =>
|
||||||
|
<div className='nav_button text-center'>
|
||||||
|
<button onClick='' className='btn btn-outline-primary btn-lg'>
|
||||||
|
Chapters
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
const ChapterButton = ({chapter, onClick}) =>
|
const ChapterButton = ({chapter, onClick}) =>
|
||||||
<div className ='chapter_button text-center'>
|
<div className ='chapter_button text-center'>
|
||||||
<button onClick={onClick} className='btn btn-outline-dark btn-lg'>{chapter.name}</button>
|
<button onClick={onClick} className='btn btn-outline-dark btn-lg'>
|
||||||
|
{chapter.name}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
export default ChapterButton
|
export default ChapterButton
|
|
@ -1,9 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PageContainer from '../containers/pageContainer'
|
|
||||||
|
|
||||||
const Content = () =>
|
const Content = (props) =>
|
||||||
<div id='content_window' className='col-md-8'>
|
<div id='content_window' className='col-md-8'>
|
||||||
<PageContainer />
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
export default Content
|
export default Content
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const EditorButtonGroup = () =>
|
||||||
|
<div className='editor_button_group'>
|
||||||
|
<div className='btn-group' role='group'>
|
||||||
|
<button type='button' className='btn btn-secondary'>Bold</span></button>
|
||||||
|
<button type='button' className='btn btn-secondary'>Italics</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
export default EditorButtonGroup
|
|
@ -1,4 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
|
import TextEditorContainer from '../containers/textEditorContainer'
|
||||||
import Navbar from '../components/navbar'
|
import Navbar from '../components/navbar'
|
||||||
import Sidebar from '../components/sidebar'
|
import Sidebar from '../components/sidebar'
|
||||||
import Content from '../components/content'
|
import Content from '../components/content'
|
||||||
|
@ -8,9 +10,10 @@ const EditorContainer = () =>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div id='joyce_editor' className='container-fluid'>
|
<div id='joyce_editor' className='container-fluid'>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{console.log('Hey you')}
|
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<Content />
|
<Content>
|
||||||
|
<TextEditorContainer />
|
||||||
|
</Content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,9 +3,10 @@ import { connect } from 'react-redux'
|
||||||
|
|
||||||
import { setCurrentChapter } from '../actions/actions'
|
import { setCurrentChapter } from '../actions/actions'
|
||||||
|
|
||||||
|
import PageContainer from '../containers/pageContainer'
|
||||||
|
import Content from '../components/content'
|
||||||
import Navbar from '../components/navbar'
|
import Navbar from '../components/navbar'
|
||||||
import Sidebar from '../components/sidebar'
|
import Sidebar from '../components/sidebar'
|
||||||
import Content from '../components/content'
|
|
||||||
|
|
||||||
class Reader extends React.Component {
|
class Reader extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
@ -15,7 +16,9 @@ class Reader extends React.Component {
|
||||||
<div id='joyce_reader' className='container-fluid'>
|
<div id='joyce_reader' className='container-fluid'>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<Content />
|
<Content>
|
||||||
|
<PageContainer />
|
||||||
|
</Content>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { updateEditorState } from '../actions/actions'
|
||||||
|
|
||||||
|
import { Editor, convertToRaw } from 'draft-js';
|
||||||
|
|
||||||
|
import EditorButtonGroup from '../components/editorButtonGroup'
|
||||||
|
|
||||||
|
const TextEditor = ({editorState, onSaveEditorState}) =>
|
||||||
|
<div id="text_editor">
|
||||||
|
<EditorButtonGroup />
|
||||||
|
<Editor editorState={editorState} onChange={onSaveEditorState} />
|
||||||
|
{JSON.stringify(editorState.getSelection())}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
return {
|
||||||
|
editorState: state.editorState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
onSaveEditorState: editorState => {
|
||||||
|
dispatch(updateEditorState(editorState))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TextEditorContainer = connect(mapStateToProps, mapDispatchToProps)(TextEditor)
|
||||||
|
|
||||||
|
export default TextEditorContainer
|
|
@ -1,13 +1,20 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { createStore, applyMiddleware } from 'redux'
|
import { createStore, combineReducers, applyMiddleware } from 'redux'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import 'bootstrap'
|
import 'bootstrap'
|
||||||
|
|
||||||
import reduceEditor from './reducers/editor'
|
import { chapters, highlightActive, currentChapter, editorState } from './reducers/editor'
|
||||||
import joyceAPIService from './middleware'
|
import joyceAPIService from './middleware'
|
||||||
import EditorContainer from './containers/editorContainer'
|
import EditorContainer from './containers/editorContainer'
|
||||||
|
|
||||||
|
const reduceEditor = combineReducers({
|
||||||
|
chapters,
|
||||||
|
currentChapter,
|
||||||
|
highlightActive,
|
||||||
|
editorState
|
||||||
|
})
|
||||||
|
|
||||||
let store = createStore(reduceEditor, applyMiddleware(joyceAPIService))
|
let store = createStore(reduceEditor, applyMiddleware(joyceAPIService))
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
@ -16,5 +23,3 @@ ReactDOM.render(
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById('wrapper')
|
document.getElementById('wrapper')
|
||||||
)
|
)
|
||||||
store.dispatch({type: 'GET_CHAPTER_DATA'})
|
|
||||||
store.dispatch({type: 'GET_TEXT_DATA', id: 1})
|
|
|
@ -1,13 +1,19 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { createStore, applyMiddleware } from 'redux'
|
import { createStore, combineReducers, applyMiddleware } from 'redux'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import 'bootstrap'
|
import 'bootstrap'
|
||||||
|
|
||||||
import reduceReader from './reducers/reader'
|
import { chapters, currentChapter, highlightActive } from './reducers/reader'
|
||||||
import joyceAPIService from './middleware'
|
import joyceAPIService from './middleware'
|
||||||
import { ReaderContainer } from './containers/readerContainer'
|
import { ReaderContainer } from './containers/readerContainer'
|
||||||
|
|
||||||
|
const reduceReader = combineReducers({
|
||||||
|
chapters,
|
||||||
|
currentChapter,
|
||||||
|
highlightActive
|
||||||
|
})
|
||||||
|
|
||||||
let store = createStore(reduceReader, applyMiddleware(joyceAPIService))
|
let store = createStore(reduceReader, applyMiddleware(joyceAPIService))
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { combineReducers } from 'redux'
|
import { EditorState } from 'draft-js'
|
||||||
import objectAssign from 'object-assign' // Object.assign() polyfill for older browsers
|
import objectAssign from 'object-assign' // Object.assign() polyfill for older browsers
|
||||||
|
import actions from '../actions/actions'
|
||||||
|
|
||||||
const chapters = (state=[], action) => {
|
const chapters = (state=[], action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
|
@ -28,10 +29,19 @@ const currentChapter = (state={}, action) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reduceEditor = combineReducers({
|
const editorState = (state=(EditorState.createEmpty()), action) => {
|
||||||
chapters,
|
switch(action.type) {
|
||||||
currentChapter,
|
case 'UPDATE_EDITOR_STATE':
|
||||||
highlightActive
|
console.log(action.payload.getSelection())
|
||||||
})
|
return action.payload
|
||||||
|
default:
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default reduceEditor
|
export {
|
||||||
|
chapters,
|
||||||
|
highlightActive,
|
||||||
|
currentChapter,
|
||||||
|
editorState
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import { combineReducers } from 'redux'
|
|
||||||
import objectAssign from 'object-assign' // Object.assign() polyfill for older browsers
|
import objectAssign from 'object-assign' // Object.assign() polyfill for older browsers
|
||||||
|
|
||||||
const chapters = (state=[], action) => {
|
const chapters = (state=[], action) => {
|
||||||
|
@ -28,10 +27,8 @@ const currentChapter = (state={}, action) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const reduceReader = combineReducers({
|
export {
|
||||||
chapters,
|
chapters,
|
||||||
currentChapter,
|
highlightActive,
|
||||||
highlightActive
|
currentChapter
|
||||||
})
|
}
|
||||||
|
|
||||||
export default reduceReader
|
|
|
@ -62,11 +62,25 @@ nav a:hover {
|
||||||
border-right: 1px solid $border_color;
|
border-right: 1px solid $border_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#joyce_editor {
|
||||||
|
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 {
|
#joyce_reader > div {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#joyce_editor > div {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
|
height: 100%;
|
||||||
background-color: rgba(250,250,250,.8);
|
background-color: rgba(250,250,250,.8);
|
||||||
margin: -2.5% 2% 1.5% 2%;
|
margin: -2.5% 2% 1.5% 2%;
|
||||||
padding: 1%;
|
padding: 1%;
|
||||||
|
@ -94,6 +108,15 @@ nav a:hover {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#text_editor {
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(256,256,256,.8);
|
||||||
|
box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.3);
|
||||||
|
padding: 3% 8%;
|
||||||
|
border: 1px solid $border_color;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#page {
|
#page {
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
|
Loading…
Reference in New Issue