fleshing out main functionality
This commit is contained in:
parent
afce2f47a4
commit
dc96ac104c
12
bower.json
Normal file
12
bower.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "dubdiff",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"dependencies": {
|
||||||
|
"jquery": "~1.11.0",
|
||||||
|
"bootstrap": "~3.1.1",
|
||||||
|
"bootstrap-sass-official": "~3.1.1",
|
||||||
|
"font-awesome": ">=4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
}
|
||||||
|
}
|
1154
dist/browser-bundle.js
vendored
1154
dist/browser-bundle.js
vendored
File diff suppressed because one or more lines are too long
18
dist/old-dubdiff.css
vendored
18
dist/old-dubdiff.css
vendored
@ -1,4 +1,22 @@
|
|||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/*
|
||||||
|
.hero-unit {
|
||||||
|
color: #fff2dc;
|
||||||
|
background: #fea539 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #688bb5 !important;
|
||||||
|
border-color: #08246b !important; }
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #587ba5 !important;
|
||||||
|
border-color: #08246b !important; }
|
||||||
|
*/
|
||||||
|
|
||||||
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
|
||||||
html {
|
html {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
12
package.json
12
package.json
@ -4,18 +4,24 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run webpack --colors",
|
"build": "ebpack --colors",
|
||||||
"start": "npm run webpack --progress --colors --watch",
|
"start": "webpack --progress --colors --watch",
|
||||||
"deploy": "git subtree push --prefix dist origin gh-pages",
|
"serve": "node src/server.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"babel-preset-es2015-mod": "^6.6.0",
|
||||||
|
"babel-preset-es3": "^1.0.1",
|
||||||
|
"diff": "^3.0.1",
|
||||||
|
"express": "^4.14.0",
|
||||||
"react": "^0.14.5",
|
"react": "^0.14.5",
|
||||||
"react-dom": "^0.14.5",
|
"react-dom": "^0.14.5",
|
||||||
"react-redux": "^4.4.6",
|
"react-redux": "^4.4.6",
|
||||||
|
"react-router": "^1.0.0",
|
||||||
"redux": "^3.5.1",
|
"redux": "^3.5.1",
|
||||||
|
"redux-router": "^1.0.0-beta5",
|
||||||
"reselect": "^2.5.1"
|
"reselect": "^2.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
|
||||||
export const updateOriginalInput = (data) => ({ type: 'UPDATE_ORIGINAL_INPUT', data})
|
export const resetInput = () => ({ type: 'RESET_INPUT' })
|
||||||
export const updateFinalInput = (data) => ({ type: 'UPDATE_FINAL_INPUT', data})
|
export const updateOriginalInput = (text) => ({ type: 'UPDATE_ORIGINAL_INPUT', data:text})
|
||||||
|
export const updateFinalInput = (text) => ({ type: 'UPDATE_FINAL_INPUT', data:text})
|
||||||
|
export const setPlaintextFormat = () => ({ type: 'SET_PLAINTEXT_FORMAT'})
|
||||||
|
export const setMarkdownFormat = () => ({ type: 'SET_MARKDOWN_FORMAT'})
|
||||||
|
export const showOriginal = () => ({ type: 'SHOW_ORIGINAL'})
|
||||||
|
export const showFinal = () => ({ type: 'SHOW_FINAL'})
|
||||||
|
export const showDifference = () => ({ type: 'SHOW_DIFFERENCE'})
|
||||||
|
|
@ -9,13 +9,18 @@ import * as localStore from './localStore'
|
|||||||
import * as reducers from './reducers'
|
import * as reducers from './reducers'
|
||||||
|
|
||||||
import Main from './components/Main'
|
import Main from './components/Main'
|
||||||
|
import Compare from './components/Compare'
|
||||||
|
|
||||||
|
import { Router } from 'react-router'
|
||||||
|
import createBrowserHistory from 'history/lib/createBrowserHistory'
|
||||||
|
import {Route, IndexRoute, Redirect } from 'react-router'
|
||||||
|
|
||||||
|
|
||||||
//create the redux store
|
//create the redux store
|
||||||
//initial state is retrieved from localStore
|
//initial state is retrieved from localStore
|
||||||
const store = Redux.createStore(
|
const store = Redux.createStore(
|
||||||
Redux.combineReducers(reducers),
|
Redux.combineReducers(reducers),
|
||||||
localStore.get(),
|
localStore.get("dubdiff"),
|
||||||
window.devToolsExtension ? window.devToolsExtension() : undefined
|
window.devToolsExtension ? window.devToolsExtension() : undefined
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,7 +28,7 @@ const store = Redux.createStore(
|
|||||||
function saveState() {
|
function saveState() {
|
||||||
let state = store.getState()
|
let state = store.getState()
|
||||||
//pass the elements of state that should be persisted to the local store as an array of element name strings
|
//pass the elements of state that should be persisted to the local store as an array of element name strings
|
||||||
localStore.set(state, [])
|
localStore.set(state, ["input"], "dubdiff")
|
||||||
}
|
}
|
||||||
store.subscribe(saveState)
|
store.subscribe(saveState)
|
||||||
|
|
||||||
@ -31,7 +36,10 @@ store.subscribe(saveState)
|
|||||||
function render() {
|
function render() {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Main/>
|
<Router history={createBrowserHistory()}>
|
||||||
|
<Route path="/" component={Main} />
|
||||||
|
<Route path="/**" component={Compare}/>
|
||||||
|
</Router>
|
||||||
</Provider>
|
</Provider>
|
||||||
, document.getElementById('root'))
|
, document.getElementById('root'))
|
||||||
}
|
}
|
||||||
|
85
src/components/Compare.js
Normal file
85
src/components/Compare.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {connect} from 'react-redux'
|
||||||
|
|
||||||
|
import * as Actions from '../actions'
|
||||||
|
import * as Selectors from '../selectors'
|
||||||
|
|
||||||
|
import Header from './Header'
|
||||||
|
import CompareControls from './CompareControls'
|
||||||
|
|
||||||
|
import Show from './Show'
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
isMarkdownFormat: Selectors.isMarkdownFormat(state),
|
||||||
|
isShowOriginal: Selectors.isShowOriginal(state),
|
||||||
|
isShowFinal: Selectors.isShowFinal(state),
|
||||||
|
isShowDifference: Selectors.isShowDifference(state),
|
||||||
|
safeInput: Selectors.safeInput(state),
|
||||||
|
diff: Selectors.diff(state)
|
||||||
|
})
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Compare extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
console.log(this.props.safeInput)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Header/>
|
||||||
|
<div className="container">
|
||||||
|
<form className="row">
|
||||||
|
<div className="col-md-2 col-sm-12">
|
||||||
|
<CompareControls/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-10 col-sm-12 content-well">
|
||||||
|
{ this.props.isShowDifference ?
|
||||||
|
|
||||||
|
<div>{this.props.diff}</div>:
|
||||||
|
|
||||||
|
<Show
|
||||||
|
text={this.props.isShowOriginal? this.props.safeInput.original: this.props.safeInput.final}
|
||||||
|
isMarkdownFormat={this.props.isMarkdownFormat}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Compare)
|
||||||
|
|
||||||
|
|
||||||
|
/* <div ng-if="isMarkdownFormat">
|
||||||
|
<div ng-show="isShowBefore" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div btf-markdown="before" class="before">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="isShowWdiff" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div btf-markdown="wdiff" class="wdiff">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="isShowAfter" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div btf-markdown="after" class="after">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="!isMarkdownFormat">
|
||||||
|
<div ng-show="isShowBefore" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div ng-bind-html="before" class="content-pre before"></div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="isShowWdiff" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div ng-bind-html="wdiff" class="content-pre wdiff"></div>
|
||||||
|
</div>
|
||||||
|
<div ng-show="isShowAfter" class="col-md-10 col-sm-12 content-well">
|
||||||
|
<div ng-bind-html="after" class="content-pre after"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
*/
|
59
src/components/CompareControls.js
Normal file
59
src/components/CompareControls.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {connect} from 'react-redux'
|
||||||
|
import {Link} from 'react-router'
|
||||||
|
|
||||||
|
import * as Actions from '../actions'
|
||||||
|
import * as Selectors from '../selectors'
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
isMarkdownFormat: Selectors.isMarkdownFormat(state),
|
||||||
|
isShowOriginal: Selectors.isShowOriginal(state),
|
||||||
|
isShowFinal: Selectors.isShowFinal(state),
|
||||||
|
isShowDifference: Selectors.isShowDifference(state),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
onSetPlaintextFormat: () => dispatch(Actions.setPlaintextFormat()),
|
||||||
|
onSetMarkdownFormat: () => dispatch(Actions.setMarkdownFormat()),
|
||||||
|
onShowOriginal: () => dispatch(Actions.showOriginal()),
|
||||||
|
onShowFinal: () => dispatch(Actions.showFinal()),
|
||||||
|
onShowDifference: () => dispatch(Actions.showDifference()),
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
class CompareControls extends React.Component {
|
||||||
|
|
||||||
|
onClickCompare() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickMarkdownFormat() {
|
||||||
|
if (this.props.isMarkdownFormat)
|
||||||
|
this.props.onSetPlaintextFormat()
|
||||||
|
else
|
||||||
|
this.props.onSetMarkdownFormat()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="controls well btn-group col-lg-12">
|
||||||
|
<a type="submit" onClick={this.props.onShowOriginal} className={(this.props.isShowOriginal?'active ':'')+'btn btn-block btn-primary'}>Original</a>
|
||||||
|
<a type="submit" onClick={this.props.onShowFinal} className={(this.props.isShowFinal?'active ':'')+'btn btn-block btn-primary'}>Final</a>
|
||||||
|
<a type="submit" onClick={this.props.onShowDifference} className={(this.props.isShowDifference?'active ':'')+'btn btn-block btn-primary'}>Difference</a>
|
||||||
|
</div>
|
||||||
|
<div className="controls well btn-group col-lg-12">
|
||||||
|
<a className={(this.props.isMarkdownFormat ? "active " : "")+"btn btn-block btn-primary"} type="submit" onClick={this.onClickMarkdownFormat.bind(this)}>
|
||||||
|
<span className={(this.props.isMarkdownFormat ? "glyphicon-ok " : "") + "glyphicon"}></span>
|
||||||
|
As Markdown
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(CompareControls)
|
||||||
|
|
16
src/components/Header.js
Normal file
16
src/components/Header.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import {Link} from 'react-router'
|
||||||
|
|
||||||
|
const Header = (props) => (
|
||||||
|
<nav>
|
||||||
|
<header id="banner" className="hero-unit">
|
||||||
|
<div className="container">
|
||||||
|
<h1><Link to="/">dubdiff</Link></h1>
|
||||||
|
<h3></h3>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default Header
|
@ -5,15 +5,18 @@ import {connect} from 'react-redux'
|
|||||||
import * as Actions from '../actions'
|
import * as Actions from '../actions'
|
||||||
import * as Selectors from '../selectors'
|
import * as Selectors from '../selectors'
|
||||||
|
|
||||||
|
import Header from './Header'
|
||||||
|
import MainControls from './MainControls'
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
input: state.input,
|
input: state.input,
|
||||||
safeInput: Selectors.safeInput(state),
|
safeInput: Selectors.safeInput(state),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
onChangeOriginal: (text) => dispatch(Actions.updateOriginalInput(text)),
|
onChangeOriginal: (text) => dispatch(Actions.updateOriginalInput(text)),
|
||||||
onChangeFinal: (text) => dispatch(Actions.updateFinalInput(text))
|
onChangeFinal: (text) => dispatch(Actions.updateFinalInput(text)),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -21,70 +24,31 @@ class Main extends React.Component {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div class="container">
|
<div>
|
||||||
<form class="row">
|
<Header/>
|
||||||
<div class="col-md-2 col-sm-12 form-group">
|
<div className="container">
|
||||||
<div class="controls well col-lg-12">
|
<form className="row">
|
||||||
<a type="button" ng-click="compare()" class="btn btn-block btn-primary">compare</a>
|
<div className="col-md-2 col-sm-12">
|
||||||
|
<MainControls/>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls well btn-group col-lg-12">
|
<div className="col-lg-5 col-sm-12 form-group">
|
||||||
<a ng-class="{"active": isMarkdownFormat}" type="submit" ng-click="toggleMarkdownFormat()" class="btn btn-block btn-primary active">
|
<label htmlFor="docA">Original</label>
|
||||||
<span ng-class="{"glyphicon-ok": isMarkdownFormat}" class="glyphicon glyphicon-ok"></span>
|
<textarea id="docA" value={this.props.input.original} onChange={event => this.props.onChangeOriginal(event.target.value)} className="form-control"></textarea>
|
||||||
As Markdown
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="col-lg-5 col-sm-12 form-group">
|
||||||
<div class="col-lg-5 col-sm-12 form-group">
|
<label htmlFor="docB">Final</label>
|
||||||
<label for="docA">Original</label>
|
<textarea id="docB" value={this.props.input.final} onChange={event => this.props.onChangeFinal(event.target.value)} className="form-control"></textarea>
|
||||||
<textarea id="docA" ng-model="docA" class="form-control"></textarea>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<div class="col-lg-5 col-sm-12 form-group">
|
</div>
|
||||||
<label for="docB">Final</label>
|
|
||||||
<textarea id="docB" ng-model="docB" class="form-control"></textarea>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function renderDate(props) {
|
|
||||||
return <div>
|
|
||||||
<DateInputForm/>
|
|
||||||
<div>
|
|
||||||
<p><strong>Data for {props.formattedDate}</strong></p>
|
|
||||||
<DateResultsSummary/>
|
|
||||||
<DateResultsChart/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderMonthly(props) {
|
|
||||||
return <div>
|
|
||||||
<p><strong>Yearly Data</strong></p>
|
|
||||||
<MonthlyResultsSummary/>
|
|
||||||
<MonthlyResultsChart/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Main)
|
export default connect(mapStateToProps, mapDispatchToProps)(Main)
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
{this.props.view == "RESULTS" ?
|
|
||||||
(this.props.inputIsValid.valid ?
|
|
||||||
<div>
|
|
||||||
<p><strong>{this.props.formattedDate}</strong></p>
|
|
||||||
<DateResultsSummary/>
|
|
||||||
<DateResultsTable/>
|
|
||||||
</div> :
|
|
||||||
<InvalidResults/>
|
|
||||||
):
|
|
||||||
*/
|
|
||||||
|
53
src/components/MainControls.js
Normal file
53
src/components/MainControls.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {connect} from 'react-redux'
|
||||||
|
import {Link} from 'react-router'
|
||||||
|
|
||||||
|
import * as Actions from '../actions'
|
||||||
|
import * as Selectors from '../selectors'
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
format: state.format,
|
||||||
|
isMarkdownFormat: Selectors.isMarkdownFormat(state)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
onSetPlaintextFormat: (format) => dispatch(Actions.setPlaintextFormat()),
|
||||||
|
onSetMarkdownFormat: (format) => dispatch(Actions.setMarkdownFormat())
|
||||||
|
})
|
||||||
|
|
||||||
|
class MainControls extends React.Component {
|
||||||
|
|
||||||
|
onClickCompare() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickMarkdownFormat() {
|
||||||
|
if (this.props.isMarkdownFormat)
|
||||||
|
this.props.onSetPlaintextFormat()
|
||||||
|
else
|
||||||
|
this.props.onSetMarkdownFormat()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="controls well col-lg-12">
|
||||||
|
<Link to="compare" className="btn btn-block btn-primary">Compare</Link>
|
||||||
|
</div>
|
||||||
|
<div className="controls well btn-group col-lg-12">
|
||||||
|
<a className={(this.props.isMarkdownFormat ? "active " : "")+"btn btn-block btn-primary"} type="submit" onClick={this.onClickMarkdownFormat.bind(this)}>
|
||||||
|
<span className={(this.props.isMarkdownFormat ? "glyphicon-ok " : "") + "glyphicon"}></span>
|
||||||
|
As Markdown
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(MainControls)
|
||||||
|
|
||||||
|
/*
|
||||||
|
<a type="button" onClick={this.onClickCompare.bind(this)} className="btn btn-block btn-primary">compare</a>*/
|
11
src/components/Show.js
Normal file
11
src/components/Show.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const Show = (props) => (
|
||||||
|
<div>
|
||||||
|
<pre>
|
||||||
|
{props.text}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default Show
|
@ -1,7 +1,10 @@
|
|||||||
export const get = () => JSON.parse(localStorage.getItem('state')) || undefined;
|
let stateName = (suffix) => 'state'+(suffix?suffix:"")
|
||||||
|
|
||||||
export function set (state, props) {
|
export const get = (suffix) => JSON.parse(localStorage.getItem(stateName(suffix))) || undefined;
|
||||||
|
|
||||||
|
export function set (state, props, suffix) {
|
||||||
let toSave = {}
|
let toSave = {}
|
||||||
props.forEach(p => toSave[p] = state[p])
|
props.forEach(p => toSave[p] = state[p])
|
||||||
localStorage.setItem('state', JSON.stringify(toSave))
|
localStorage.setItem(stateName(suffix), JSON.stringify(toSave))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,50 @@
|
|||||||
|
|
||||||
|
|
||||||
export function textInput (state, action ) {
|
export function input (state, action ) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'UPDATE_ORIGINAL_INPUT':
|
case 'UPDATE_ORIGINAL_INPUT':
|
||||||
return Object.assign({}, state, {original:action.data})
|
return Object.assign({}, state, {original:action.data})
|
||||||
|
case 'UPDATE_FINAL_INPUT':
|
||||||
|
return Object.assign({}, state, {final:action.data})
|
||||||
|
case 'RESET_INPUT':
|
||||||
|
return {original:'', final:''}
|
||||||
default:
|
default:
|
||||||
return state || {original:"", final:""}
|
return state || {original:'', final:''}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Format = {
|
||||||
export function locationInput (state, action) {
|
PLAINTEXT: 'PLAINTEXT',
|
||||||
switch (action.type) {
|
MARKDOWN: 'MARKDOWN'
|
||||||
case 'UPDATE_LOCATION_INPUT':
|
|
||||||
return Object.assign({}, state, action.data)
|
|
||||||
default:
|
|
||||||
return state || {latitude:"0", longitude:"0"}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dateInput (state, action) {
|
|
||||||
|
export function format (state, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'UPDATE_DATE_INPUT':
|
case 'SET_PLAINTEXT_FORMAT':
|
||||||
return action.data
|
return Format.PLAINTEXT
|
||||||
|
case 'SET_MARKDOWN_FORMAT':
|
||||||
|
return Format.MARKDOWN
|
||||||
default:
|
default:
|
||||||
return state || "Jun 21"
|
return state || Format.PLAINTEXT
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Show = {
|
||||||
|
ORIGINAL:'ORIGINAL',
|
||||||
|
FINAL:'FINAL',
|
||||||
|
DIFFERENCE:'DIFFERENCE'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function view (state, action) {
|
export function show (state, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'VIEW_DATE':
|
case 'SHOW_ORIGINAL':
|
||||||
return 'DATE'
|
return Show.ORIGINAL
|
||||||
case 'VIEW_MONTHLY':
|
case 'SHOW_FINAL':
|
||||||
return 'MONTHLY'
|
return Show.FINAL
|
||||||
|
case 'SHOW_DIFFERENCE':
|
||||||
|
return Show.DIFFERENCE
|
||||||
default:
|
default:
|
||||||
return state || 'MONTHLY'
|
return state || Show.DIFFERENCE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,16 @@
|
|||||||
|
|
||||||
import { createSelector } from 'reselect'
|
import { createSelector } from 'reselect'
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import * as JsDiff from 'diff'
|
||||||
|
|
||||||
|
import {Format, Show} from './reducers'
|
||||||
|
|
||||||
|
|
||||||
const input = (state) => state.input
|
const input = (state) => state.input
|
||||||
|
const format = (state) => state.format
|
||||||
|
const show = (state) => state.show
|
||||||
|
|
||||||
export const safeInput = createSelector(
|
export const safeInput = createSelector(
|
||||||
[input],
|
[input],
|
||||||
@ -10,4 +19,55 @@ export const safeInput = createSelector(
|
|||||||
//!!! sanitize the input here and return
|
//!!! sanitize the input here and return
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const isMarkdownFormat = createSelector(
|
||||||
|
[format],
|
||||||
|
(format) => {
|
||||||
|
console.log(format, Format.MARKDOWN)
|
||||||
|
return format == Format.MARKDOWN
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const isShow = (type) => createSelector(
|
||||||
|
[show],
|
||||||
|
(show) => {
|
||||||
|
return show == type
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const isShowOriginal = isShow(Show.ORIGINAL)
|
||||||
|
export const isShowFinal = isShow(Show.FINAL)
|
||||||
|
export const isShowDifference= isShow(Show.DIFFERENCE)
|
||||||
|
|
||||||
|
|
||||||
|
export const diff = createSelector(
|
||||||
|
[format, input],
|
||||||
|
(format, input) => {
|
||||||
|
|
||||||
|
let diff = JsDiff.diffLines(input.original.replace(/ /g, '###\n'), input.final.replace(/ /g, '###\n'))
|
||||||
|
console.log(diff, diff.map(({added, removed, value})=>({added, removed, value:value.replace(/###\n/g, ' ')})))
|
||||||
|
return diff.map(({added, removed, value})=>({added, removed, value:value.replace(/###\n/g, ' ')})).map(part => (
|
||||||
|
part.added ? <ins>{part.value}</ins> :
|
||||||
|
part.removed ? <del>{part.value}</del> :
|
||||||
|
<span>{part.value}</span>
|
||||||
|
))
|
||||||
|
/*
|
||||||
|
let diff = JsDiff.diffWords (input.original.replace(/ /g, ' '), input.final.replace(/ /g, ' '))
|
||||||
|
return diff.map(({added, removed, value})=>({added, removed, value:value.replace(/ /g, ' ')})).map(part => (
|
||||||
|
part.added ? <ins>{part.value}</ins> :
|
||||||
|
part.removed ? <del>{part.value}</del> :
|
||||||
|
<span>{part.value}</span>
|
||||||
|
))
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
html diff
|
||||||
|
---
|
||||||
|
|
||||||
|
diffHtml(parentOriginal, parentFinal) {
|
||||||
|
create stringOriginal, stringFinal consisting of
|
||||||
|
}
|
||||||
|
*/
|
16
src/server.js
Normal file
16
src/server.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var express = require('express')
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
var app = express()
|
||||||
|
|
||||||
|
|
||||||
|
app.use(express.static('dist'))
|
||||||
|
app.use('bower_components/*', express.static('bower_components'))
|
||||||
|
app.route('/*')
|
||||||
|
.get(function(req, res) {
|
||||||
|
res.sendFile(path.join(__dirname, '..', 'dist', 'index.html'));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(8080, function () {
|
||||||
|
console.log('Server listening on port 8080.')
|
||||||
|
})
|
@ -5,7 +5,7 @@ module.exports = {
|
|||||||
filename: './dist/browser-bundle.js'
|
filename: './dist/browser-bundle.js'
|
||||||
},
|
},
|
||||||
target: 'web',
|
target: 'web',
|
||||||
devtool: 'eval-cheap-module-source-map',
|
devtool: 'eval-module-source-map',
|
||||||
module: {
|
module: {
|
||||||
loaders: [
|
loaders: [
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user