refactor load/save state, add favicon
This commit is contained in:
parent
720f123977
commit
d66292047f
74
dist/browser-bundle.js
vendored
74
dist/browser-bundle.js
vendored
@ -1516,12 +1516,25 @@ throw new Error(message);}catch(x){}}};}module.exports=warning;
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.save=exports.showDifference=exports.showFinal=exports.showOriginal=exports.setMarkdownFormat=exports.setPlaintextFormat=exports.clearInput=exports.updateFinalInput=exports.updateOriginalInput=undefined;var _isomorphicFetch=__webpack_require__(1214);var _isomorphicFetch2=_interopRequireDefault(_isomorphicFetch);var _v=__webpack_require__(566);var _v2=_interopRequireDefault(_v);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var updateOriginalInput=exports.updateOriginalInput=function updateOriginalInput(text){return function(dispatch,getState){dispatch({type:'UPDATE_ORIGINAL_INPUT',data:text});if(getState().input.original.length>0)dispatch({type:'SAVE_STATUS_DIRTY'});else dispatch({type:'SAVE_STATUS_EMPTY'});};};var updateFinalInput=exports.updateFinalInput=function updateFinalInput(text){return function(dispatch,getState){dispatch({type:'UPDATE_FINAL_INPUT',data:text});if(getState().input.final.length>0)dispatch({type:'SAVE_STATUS_DIRTY'});else dispatch({type:'SAVE_STATUS_EMPTY'});};};var clearInput=exports.clearInput=function clearInput(){return function(dispatch){dispatch({type:'CLEAR_INPUT'});dispatch({type:'SAVE_STATUS_EMPTY'});};};var setPlaintextFormat=exports.setPlaintextFormat=function setPlaintextFormat(){return{type:'SET_PLAINTEXT_FORMAT'};};var setMarkdownFormat=exports.setMarkdownFormat=function setMarkdownFormat(){return{type:'SET_MARKDOWN_FORMAT'};};var showOriginal=exports.showOriginal=function showOriginal(){return{type:'SHOW_ORIGINAL'};};var showFinal=exports.showFinal=function showFinal(){return{type:'SHOW_FINAL'};};var showDifference=exports.showDifference=function showDifference(){return{type:'SHOW_DIFFERENCE'};};//saves the current input fields to the server
|
||||
//creates and returns a new id for the
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.save=exports.edit=exports.reset=exports.compare=exports.showDifference=exports.showFinal=exports.showOriginal=exports.setMarkdownFormat=exports.setPlaintextFormat=exports.clearInput=exports.updateFinalInput=exports.updateOriginalInput=undefined;var _isomorphicFetch=__webpack_require__(1214);var _isomorphicFetch2=_interopRequireDefault(_isomorphicFetch);var _v=__webpack_require__(566);var _v2=_interopRequireDefault(_v);var _reactRouter=__webpack_require__(84);var _constants=__webpack_require__(570);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}//All state transitions in the app happen in these methods
|
||||
//this includes redux state changes, asyncronous data requests, and browser location changes
|
||||
var updateOriginalInput=exports.updateOriginalInput=function updateOriginalInput(text){return function(dispatch,getState){dispatch({type:'UPDATE_ORIGINAL_INPUT',data:text});if(getState().input.original.length>0)dispatch({type:'STATUS_SET',data:_constants.Status.DIRTY});else dispatch({type:'STATUS_SET',data:_constants.Status.EMPTY});};};var updateFinalInput=exports.updateFinalInput=function updateFinalInput(text){return function(dispatch,getState){dispatch({type:'UPDATE_FINAL_INPUT',data:text});if(getState().input.final.length>0)dispatch({type:'STATUS_SET',data:_constants.Status.DIRTY});else dispatch({type:'STATUS_SET',data:_constants.Status.EMPTY});};};var clearInput=exports.clearInput=function clearInput(){return function(dispatch){dispatch({type:'CLEAR_INPUT'});dispatch({type:'STATUS_SET',data:_constants.Status.EMPTY});};};var setPlaintextFormat=exports.setPlaintextFormat=function setPlaintextFormat(){return{type:'SET_PLAINTEXT_FORMAT'};};var setMarkdownFormat=exports.setMarkdownFormat=function setMarkdownFormat(){return{type:'SET_MARKDOWN_FORMAT'};};var showOriginal=exports.showOriginal=function showOriginal(){return{type:'SHOW_ORIGINAL'};};var showFinal=exports.showFinal=function showFinal(){return{type:'SHOW_FINAL'};};var showDifference=exports.showDifference=function showDifference(){return{type:'SHOW_DIFFERENCE'};};//if the input is dirty, saves it to the server
|
||||
//creates a new uuid for the same,
|
||||
//then changes the browser location to a comparison view with that id
|
||||
var compare=exports.compare=function compare(){return function(dispatch,getState){//!!! could test that the input is dirty before triggering a save
|
||||
//if the input is empty, the compare should do nothing
|
||||
//if the input is clean, the compare should not save and keep using the same id
|
||||
//start saving the input to the server
|
||||
var id=dispatch(save());//we can use the id created by the save method to build a path
|
||||
var comparePath='/'+id;_reactRouter.browserHistory.replace(comparePath);};};//clear the input and return to the edit page
|
||||
var reset=exports.reset=function reset(){return function(dispatch,getState){dispatch(clearInput());_reactRouter.browserHistory.push('/');};};//switch to the edit view
|
||||
var edit=exports.edit=function edit(){return function(dispatch,getState){_reactRouter.browserHistory.push('/');};};//saves the current input fields to the server
|
||||
//creates and returns a new id for the comparison
|
||||
//should this method ensure that the initial state is valid? ('DIRTY')
|
||||
var save=exports.save=function save(){return function(dispatch,getState){//generate an id
|
||||
var id=(0,_v2.default)();//set waiting state
|
||||
dispatch({type:'SAVE_STATUS_WAITING'});var endpointUri='/api/compare/'+id;var fetchOptions={method:'POST',body:JSON.stringify({a:getState().input.original,b:getState().input.final}),headers:{"Content-Type":"application/json"}};//dispatch post request
|
||||
(0,_isomorphicFetch2.default)(endpointUri,fetchOptions).then(function(response){dispatch({type:'SAVE_STATUS_SAVED'});}).catch(function(error){dispatch({type:'SAVE_STATUS_FAILED',error:error});});//return the id after the request has been sent
|
||||
dispatch({type:'STATUS_SET',data:_constants.Status.SAVING});var endpointUri='/api/compare/'+id;var fetchOptions={method:'POST',body:JSON.stringify({a:getState().input.original,b:getState().input.final}),headers:{"Content-Type":"application/json"}};//dispatch post request
|
||||
(0,_isomorphicFetch2.default)(endpointUri,fetchOptions).then(function(response){dispatch({type:'STATUS_SET',data:_constants.Status.CLEAN});}).catch(function(error){dispatch({type:'STATUS_SET',data:_constants.Status.DIRTY});dispatch({type:'STATUS_SET_ERROR',data:_constants.StatusError.SAVE_ERROR,error:error});});//return the id after the request has been sent
|
||||
return id;};};/*
|
||||
const load = (id) =>
|
||||
(dispatch, getState) => {
|
||||
@ -9782,14 +9795,14 @@ if(buf){for(var ii=0;ii<16;++ii){buf[i+ii]=rnds[ii];}}return buf||bytesToUuid(rn
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _semanticUiReact=__webpack_require__(80);var _reactRouter=__webpack_require__(84);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _SaveStatus=__webpack_require__(1180);var _SaveStatus2=_interopRequireDefault(_SaveStatus);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var mapStateToProps=function mapStateToProps(state){return{};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onClear:function onClear(){dispatch(Actions.clearInput());dispatch(Actions.clearCompare());}};};var SiteHeader=function SiteHeader(props){return _react2.default.createElement(_semanticUiReact.Segment,{basic:true},_react2.default.createElement(_semanticUiReact.Segment,{basic:true,padded:true,textAlign:'center',as:'header',id:'masthead'},_react2.default.createElement(_semanticUiReact.Header,null,_react2.default.createElement(_reactRouter.Link,{onClick:props.onClear,to:'/'},'dubdiff'))),_react2.default.createElement(_semanticUiReact.Rail,{internal:true,position:'right'},_react2.default.createElement(_semanticUiReact.Segment,{basic:true,padded:true},_react2.default.createElement(_SaveStatus2.default,null))));};exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(SiteHeader);
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _semanticUiReact=__webpack_require__(80);var _reactRouter=__webpack_require__(84);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _SaveStatus=__webpack_require__(1180);var _SaveStatus2=_interopRequireDefault(_SaveStatus);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var mapStateToProps=function mapStateToProps(state){return{};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onReset:function onReset(){console.log(Actions.reset());dispatch(Actions.reset());}};};var SiteHeader=function SiteHeader(props){return _react2.default.createElement(_semanticUiReact.Segment,{basic:true},_react2.default.createElement(_semanticUiReact.Segment,{basic:true,padded:true,textAlign:'center',as:'header',id:'masthead'},_react2.default.createElement(_semanticUiReact.Header,null,_react2.default.createElement(_reactRouter.Link,{onClick:props.onReset},'dubdiff'))),_react2.default.createElement(_semanticUiReact.Rail,{internal:true,position:'right'},_react2.default.createElement(_semanticUiReact.Segment,{basic:true,padded:true},_react2.default.createElement(_SaveStatus2.default,null))));};exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(SiteHeader);
|
||||
|
||||
/***/ },
|
||||
/* 570 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var Format=exports.Format={PLAINTEXT:'PLAINTEXT',MARKDOWN:'MARKDOWN'};var Show=exports.Show={ORIGINAL:'ORIGINAL',FINAL:'FINAL',DIFFERENCE:'DIFFERENCE'};
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var Format=exports.Format={PLAINTEXT:'PLAINTEXT',MARKDOWN:'MARKDOWN'};var Show=exports.Show={ORIGINAL:'ORIGINAL',FINAL:'FINAL',DIFFERENCE:'DIFFERENCE'};var Status=exports.Status={INIT:'INIT',LOADING:'LOADING',EMPTY:'EMPTY',CLEAN:'CLEAN',DIRTY:'DIRTY',SAVING:'SAVING'};var StatusError=exports.StatusError={LOADING_ERROR:'LOAD_ERROR',SAVING_ERROR:'SAVE_ERROR'};
|
||||
|
||||
/***/ },
|
||||
/* 571 */
|
||||
@ -9878,20 +9891,28 @@ function(acc,x,i){return test(x)?acc.concat([i]):acc;},//start with the empty ar
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.input=input;exports.format=format;exports.show=show;exports.saveStatus=saveStatus;var _constants=__webpack_require__(570);function input(state,action){switch(action.type){case'UPDATE_ORIGINAL_INPUT':return Object.assign({},state,{original:action.data});case'UPDATE_FINAL_INPUT':return Object.assign({},state,{final:action.data});case'CLEAR_INPUT':return{original:'',final:''};default:return state||{original:'',final:''};}}function format(state,action){switch(action.type){case'SET_PLAINTEXT_FORMAT':return _constants.Format.PLAINTEXT;case'SET_MARKDOWN_FORMAT':return _constants.Format.MARKDOWN;default:return state||_constants.Format.PLAINTEXT;}}function show(state,action){switch(action.type){case'SHOW_ORIGINAL':return _constants.Show.ORIGINAL;case'SHOW_FINAL':return _constants.Show.FINAL;case'SHOW_DIFFERENCE':return _constants.Show.DIFFERENCE;default:return state||_constants.Show.DIFFERENCE;}}function saveStatus(state,action){switch(action.type){case'SAVE_STATUS_DIRTY':return{dirty:true};case'SAVE_STATUS_EMPTY':return{dirty:false,empty:true};case'SAVE_STATUS_SAVED':return{dirty:false,saved:true};case'SAVE_STATUS_FAILED':return Object.assign({},state,{waiting:false,failed:true,error:action.error});case'SAVE_STATUS_WAITING':return Object.assign({},state,{waiting:true,failed:false,error:null});default:return state||{empty:true,dirty:false};}}/*
|
||||
export function loadStatus (state, action) {
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.input=input;exports.format=format;exports.show=show;exports.status=status;var _constants=__webpack_require__(570);function input(state,action){switch(action.type){case'UPDATE_ORIGINAL_INPUT':return Object.assign({},state,{original:action.data});case'UPDATE_FINAL_INPUT':return Object.assign({},state,{final:action.data});case'CLEAR_INPUT':return{original:'',final:''};default:return state||{original:'',final:''};}}function format(state,action){switch(action.type){case'SET_PLAINTEXT_FORMAT':return _constants.Format.PLAINTEXT;case'SET_MARKDOWN_FORMAT':return _constants.Format.MARKDOWN;default:return state||_constants.Format.PLAINTEXT;}}function show(state,action){switch(action.type){case'SHOW_ORIGINAL':return _constants.Show.ORIGINAL;case'SHOW_FINAL':return _constants.Show.FINAL;case'SHOW_DIFFERENCE':return _constants.Show.DIFFERENCE;default:return state||_constants.Show.DIFFERENCE;}}/*
|
||||
export function saveStatus (state, action) {
|
||||
switch (action.type) {
|
||||
case 'LOAD_STATUS_WAITING':
|
||||
return {waiting: true}
|
||||
case 'LOAD_STATUS_FAILED':
|
||||
return {failed: true, error: action.error }
|
||||
case 'LOAD_STATUS_LOADED':
|
||||
return {loaded: true}
|
||||
case 'SAVE_STATUS_DIRTY':
|
||||
return {dirty: true}
|
||||
case 'SAVE_STATUS_EMPTY':
|
||||
return {dirty: false, empty: true}
|
||||
case 'SAVE_STATUS_SAVED':
|
||||
return {dirty: false, saved: true}
|
||||
case 'SAVE_STATUS_FAILED' :
|
||||
return Object.assign({}, state, {waiting: false, failed: true, error: action.error})
|
||||
case 'SAVE_STATUS_WAITING' :
|
||||
return Object.assign({}, state, {waiting: true, failed: false, error: null})
|
||||
default:
|
||||
return state || {waiting: false}
|
||||
return state || {empty: true, dirty:false}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*///tracks status of the app, especially with respect to loaded and saved user data
|
||||
function status(state,action){//the status or error type is valid if it is in the list of Status or StatusError types
|
||||
var isValidStatus=function isValidStatus(type){return _constants.Status[type]==type;};var isValidError=function isValidError(type){return _constants.StatusError[type]==type;};//the error is cleared when status changes
|
||||
if(action.type=='STATUS_SET'&&isValidStatus(action.data))return{type:action.data,error:null,hasError:false,errorType:null};//the error is set in addition to the status
|
||||
else if(action.type=='STATUS_SET_ERROR'&&isValidError(action.data))return Object.assign({},state,{error:action.error,hasError:true,errorType:action.data});else return{type:_constants.Status.EMPTY,hasError:false,error:null};}
|
||||
|
||||
/***/ },
|
||||
/* 575 */
|
||||
@ -20807,7 +20828,7 @@ module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};}();var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _reactRouter=__webpack_require__(84);var _semanticUiReact=__webpack_require__(80);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _selectors=__webpack_require__(196);var Selectors=_interopRequireWildcard(_selectors);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self,call){if(!self){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call&&(typeof call==="object"||typeof call==="function")?call:self;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass;}var mapStateToProps=function mapStateToProps(state){return{isMarkdownFormat:Selectors.isMarkdownFormat(state),isShowOriginal:Selectors.isShowOriginal(state),isShowFinal:Selectors.isShowFinal(state),isShowDifference:Selectors.isShowDifference(state)};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onSetPlaintextFormat:function onSetPlaintextFormat(){return dispatch(Actions.setPlaintextFormat());},onSetMarkdownFormat:function onSetMarkdownFormat(){return dispatch(Actions.setMarkdownFormat());},onShowOriginal:function onShowOriginal(){return dispatch(Actions.showOriginal());},onShowFinal:function onShowFinal(){return dispatch(Actions.showFinal());},onShowDifference:function onShowDifference(){return dispatch(Actions.showDifference());},onEdit:function onEdit(){}};};var CompareControls=function(_React$Component){_inherits(CompareControls,_React$Component);function CompareControls(){_classCallCheck(this,CompareControls);return _possibleConstructorReturn(this,(CompareControls.__proto__||Object.getPrototypeOf(CompareControls)).apply(this,arguments));}_createClass(CompareControls,[{key:'onClickEdit',value:function onClickEdit(){this.props.onEdit();}},{key:'onClickMarkdownFormat',value:function onClickMarkdownFormat(){if(this.props.isMarkdownFormat)this.props.onSetPlaintextFormat();else this.props.onSetMarkdownFormat();}},{key:'render',value:function render(){return _react2.default.createElement(_semanticUiReact.Segment.Group,null,_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_reactRouter.Link,{to:'/'},_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.onClickEdit.bind(this)},'Edit'))),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowOriginal,active:this.props.isShowOriginal},'Original'),_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowFinal,active:this.props.isShowFinal},'Final'),_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowDifference,active:this.props.isShowDifference},'Difference')),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,active:this.props.isMarkdownFormat,type:'submit',onClick:this.onClickMarkdownFormat.bind(this)},this.props.isMarkdownFormat?_react2.default.createElement(_semanticUiReact.Icon,{name:'checkmark'}):_react2.default.createElement('span',null),'\xA0As Markdown')));}}]);return CompareControls;}(_react2.default.Component);exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(CompareControls);
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};}();var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _reactRouter=__webpack_require__(84);var _semanticUiReact=__webpack_require__(80);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _selectors=__webpack_require__(196);var Selectors=_interopRequireWildcard(_selectors);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self,call){if(!self){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call&&(typeof call==="object"||typeof call==="function")?call:self;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass;}var mapStateToProps=function mapStateToProps(state){return{isMarkdownFormat:Selectors.isMarkdownFormat(state),isShowOriginal:Selectors.isShowOriginal(state),isShowFinal:Selectors.isShowFinal(state),isShowDifference:Selectors.isShowDifference(state)};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onSetPlaintextFormat:function onSetPlaintextFormat(){return dispatch(Actions.setPlaintextFormat());},onSetMarkdownFormat:function onSetMarkdownFormat(){return dispatch(Actions.setMarkdownFormat());},onShowOriginal:function onShowOriginal(){return dispatch(Actions.showOriginal());},onShowFinal:function onShowFinal(){return dispatch(Actions.showFinal());},onShowDifference:function onShowDifference(){return dispatch(Actions.showDifference());},onEdit:function onEdit(){return dispatch(Actions.edit());}};};var CompareControls=function(_React$Component){_inherits(CompareControls,_React$Component);function CompareControls(){_classCallCheck(this,CompareControls);return _possibleConstructorReturn(this,(CompareControls.__proto__||Object.getPrototypeOf(CompareControls)).apply(this,arguments));}_createClass(CompareControls,[{key:'onClickMarkdownFormat',value:function onClickMarkdownFormat(){if(this.props.isMarkdownFormat)this.props.onSetPlaintextFormat();else this.props.onSetMarkdownFormat();}},{key:'render',value:function render(){return _react2.default.createElement(_semanticUiReact.Segment.Group,null,_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onEdit},'Edit')),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowOriginal,active:this.props.isShowOriginal},'Original'),_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowFinal,active:this.props.isShowFinal},'Final'),_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onShowDifference,active:this.props.isShowDifference},'Difference')),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,active:this.props.isMarkdownFormat,type:'submit',onClick:this.onClickMarkdownFormat.bind(this)},this.props.isMarkdownFormat?_react2.default.createElement(_semanticUiReact.Icon,{name:'checkmark'}):_react2.default.createElement('span',null),'\xA0As Markdown')));}}]);return CompareControls;}(_react2.default.Component);exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(CompareControls);
|
||||
|
||||
/***/ },
|
||||
/* 1178 */
|
||||
@ -20821,10 +20842,8 @@ module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};}();var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _reactRouter=__webpack_require__(84);var _semanticUiReact=__webpack_require__(80);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _selectors=__webpack_require__(196);var Selectors=_interopRequireWildcard(_selectors);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self,call){if(!self){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call&&(typeof call==="object"||typeof call==="function")?call:self;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass;}var mapStateToProps=function mapStateToProps(state){return{format:state.format,isMarkdownFormat:Selectors.isMarkdownFormat(state),saveStatus:state.saveStatus};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onSetPlaintextFormat:function onSetPlaintextFormat(format){return dispatch(Actions.setPlaintextFormat());},onSetMarkdownFormat:function onSetMarkdownFormat(format){return dispatch(Actions.setMarkdownFormat());},//returns an id for the record to be saved
|
||||
startSaveAsync:function startSaveAsync(){return dispatch(Actions.save());}};};var MainControls=function(_React$Component){_inherits(MainControls,_React$Component);function MainControls(){_classCallCheck(this,MainControls);return _possibleConstructorReturn(this,(MainControls.__proto__||Object.getPrototypeOf(MainControls)).apply(this,arguments));}_createClass(MainControls,[{key:'onClickCompare',value:function onClickCompare(){//start saving the input to the server
|
||||
var id=this.props.startSaveAsync();//we can use the id created by the save method to build a path
|
||||
var comparePath='/'+id;_reactRouter.browserHistory.replace(comparePath);return false;}},{key:'onClickMarkdownFormat',value:function onClickMarkdownFormat(){if(this.props.isMarkdownFormat)this.props.onSetPlaintextFormat();else this.props.onSetMarkdownFormat();}},{key:'render',value:function render(){return _react2.default.createElement(_semanticUiReact.Segment.Group,null,_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.onClickCompare.bind(this)},'Compare')),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,active:this.props.isMarkdownFormat,type:'submit',onClick:this.onClickMarkdownFormat.bind(this)},this.props.isMarkdownFormat?_react2.default.createElement(_semanticUiReact.Icon,{name:'checkmark'}):_react2.default.createElement('span',null),'\xA0As Markdown')));}}]);return MainControls;}(_react2.default.Component);exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(MainControls);/*
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};}();var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _semanticUiReact=__webpack_require__(80);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _selectors=__webpack_require__(196);var Selectors=_interopRequireWildcard(_selectors);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self,call){if(!self){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call&&(typeof call==="object"||typeof call==="function")?call:self;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function, not "+typeof superClass);}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass;}var mapStateToProps=function mapStateToProps(state){return{format:state.format,isMarkdownFormat:Selectors.isMarkdownFormat(state),saveStatus:state.saveStatus};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onSetPlaintextFormat:function onSetPlaintextFormat(format){return dispatch(Actions.setPlaintextFormat());},onSetMarkdownFormat:function onSetMarkdownFormat(format){return dispatch(Actions.setMarkdownFormat());},//returns an id for the record to be saved
|
||||
onCompare:function onCompare(){return dispatch(Actions.compare());}};};var MainControls=function(_React$Component){_inherits(MainControls,_React$Component);function MainControls(){_classCallCheck(this,MainControls);return _possibleConstructorReturn(this,(MainControls.__proto__||Object.getPrototypeOf(MainControls)).apply(this,arguments));}_createClass(MainControls,[{key:'onClickMarkdownFormat',value:function onClickMarkdownFormat(){if(this.props.isMarkdownFormat)this.props.onSetPlaintextFormat();else this.props.onSetMarkdownFormat();}},{key:'render',value:function render(){return _react2.default.createElement(_semanticUiReact.Segment.Group,null,_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,onClick:this.props.onCompare},'Compare')),_react2.default.createElement(_semanticUiReact.Segment,null,_react2.default.createElement(_semanticUiReact.Button,{fluid:true,active:this.props.isMarkdownFormat,type:'submit',onClick:this.onClickMarkdownFormat.bind(this)},this.props.isMarkdownFormat?_react2.default.createElement(_semanticUiReact.Icon,{name:'checkmark'}):_react2.default.createElement('span',null),'\xA0As Markdown')));}}]);return MainControls;}(_react2.default.Component);exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(MainControls);/*
|
||||
<a type="button" onClick={this.onClickCompare.bind(this)} className="btn btn-block btn-primary">compare</a>*/
|
||||
|
||||
/***/ },
|
||||
@ -20832,8 +20851,7 @@ var comparePath='/'+id;_reactRouter.browserHistory.replace(comparePath);return f
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _semanticUiReact=__webpack_require__(80);var _reactRouter=__webpack_require__(84);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var mapStateToProps=function mapStateToProps(state){return{saveStatus:state.saveStatus};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{retrySave:function retrySave(){return dispatch(Actions.save());}};};var onRetrySaveClick=function onRetrySaveClick(props){//we can use the id created by the save method to build a path
|
||||
var id=props.retrySave();var comparePath='/'+id;_reactRouter.browserHistory.replace(comparePath);return false;};var SaveStatus=function SaveStatus(props){if(props.saveStatus.waiting)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'circle notched',loading:true}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Saving diff')));else if(props.saveStatus.failed)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'exclamation'}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Error saving diff'),'The server returned ',props.saveStatus.error.message,'.',_react2.default.createElement(_semanticUiReact.Button,{onClick:function onClick(){return onRetrySaveClick(props);}},'Retry')));else return _react2.default.createElement('div',null);};exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(SaveStatus);
|
||||
'use strict';Object.defineProperty(exports,"__esModule",{value:true});var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactRedux=__webpack_require__(69);var _semanticUiReact=__webpack_require__(80);var _reactRouter=__webpack_require__(84);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _constants=__webpack_require__(570);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var mapStateToProps=function mapStateToProps(state){return{status:state.status};};var mapDispatchToProps=function mapDispatchToProps(dispatch){return{onSave:function onSave(){return dispatch(Actions.save());}};};var SaveStatus=function SaveStatus(props){console.log(props.status);if(props.status.type==_constants.Status.SAVING)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'circle notched',loading:true}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Saving diff')));if(props.status.type==_constants.Status.LOADING)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'circle notched',loading:true}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Loading diff')));else if(props.status.hasError&&props.status.errorType==_constants.StatusError.SAVE_ERROR)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'exclamation'}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Error saving diff'),props.status.error.message,_react2.default.createElement(_semanticUiReact.Button,{onClick:props.onSave},'Retry')));else if(props.status.hasError&&props.status.errorType==_constants.StatusError.LOAD_ERROR)return _react2.default.createElement(_semanticUiReact.Message,{size:'tiny',floating:true,compact:true,icon:true},_react2.default.createElement(_semanticUiReact.Icon,{name:'exclamation'}),_react2.default.createElement(_semanticUiReact.Message.Content,null,_react2.default.createElement(_semanticUiReact.Message.Header,null,'Error loading diff'),'Server returned ',props.status.error));else return _react2.default.createElement('div',null);};exports.default=(0,_reactRedux.connect)(mapStateToProps,mapDispatchToProps)(SaveStatus);
|
||||
|
||||
/***/ },
|
||||
/* 1181 */
|
||||
@ -23326,15 +23344,11 @@ module.exports = [
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
'use strict';var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactDom=__webpack_require__(303);var _reactDom2=_interopRequireDefault(_reactDom);var _redux=__webpack_require__(304);var Redux=_interopRequireWildcard(_redux);var _reactRedux=__webpack_require__(69);var _reactRouter=__webpack_require__(84);var _reduxThunk=__webpack_require__(572);var _reduxThunk2=_interopRequireDefault(_reduxThunk);var _reducers=__webpack_require__(574);var reducers=_interopRequireWildcard(_reducers);var _routes=__webpack_require__(575);var _routes2=_interopRequireDefault(_routes);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _LocalStorage=__webpack_require__(1216);var _LocalStorage2=_interopRequireDefault(_LocalStorage);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}//the localStore implementation is naive
|
||||
//initial state should be rehydrated from the server
|
||||
//then additional state transformations should be applied based on localStore contents
|
||||
// (or not? maybe localStore is not needed)
|
||||
'use strict';var _react=__webpack_require__(0);var _react2=_interopRequireDefault(_react);var _reactDom=__webpack_require__(303);var _reactDom2=_interopRequireDefault(_reactDom);var _redux=__webpack_require__(304);var Redux=_interopRequireWildcard(_redux);var _reactRedux=__webpack_require__(69);var _reactRouter=__webpack_require__(84);var _reduxThunk=__webpack_require__(572);var _reduxThunk2=_interopRequireDefault(_reduxThunk);var _reducers=__webpack_require__(574);var reducers=_interopRequireWildcard(_reducers);var _routes=__webpack_require__(575);var _routes2=_interopRequireDefault(_routes);var _actions=__webpack_require__(70);var Actions=_interopRequireWildcard(_actions);var _LocalStorage=__webpack_require__(1216);var _LocalStorage2=_interopRequireDefault(_LocalStorage);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key];}}newObj.default=obj;return newObj;}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}//initial state is rehydrated from the server
|
||||
//import createBrowserHistory from 'history/lib/createBrowserHistory'
|
||||
var initialState=window.__INITIAL_STATE__;//create the list of middlewares
|
||||
var middlewares=[_reduxThunk2.default];//create the redux store
|
||||
var initialState=window.__INITIAL_STATE__;//create the redux store
|
||||
//initial state is retrieved from localStore
|
||||
var store=Redux.createStore(Redux.combineReducers(reducers),initialState,window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(Redux.applyMiddleware.apply(Redux,middlewares)):Redux.applyMiddleware.apply(Redux,middlewares));function render(){_reactDom2.default.render(_react2.default.createElement(_reactRedux.Provider,{store:store},_react2.default.createElement(_LocalStorage2.default,null,_react2.default.createElement(_reactRouter.Router,{history:_reactRouter.browserHistory},_routes2.default))),document.getElementById('root'));}render();
|
||||
var store=Redux.createStore(Redux.combineReducers(reducers),initialState,Redux.compose(Redux.applyMiddleware(_reduxThunk2.default),window.devToolsExtension?window.devToolsExtension():function(f){return f;}));function render(){_reactDom2.default.render(_react2.default.createElement(_reactRedux.Provider,{store:store},_react2.default.createElement(_LocalStorage2.default,null,_react2.default.createElement(_reactRouter.Router,{history:_reactRouter.browserHistory},_routes2.default))),document.getElementById('root'));}render();
|
||||
|
||||
/***/ },
|
||||
/* 1214 */
|
||||
|
BIN
dist/favicon-16x16.png
vendored
Normal file
BIN
dist/favicon-16x16.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
dist/favicon-32x32.png
vendored
Normal file
BIN
dist/favicon-32x32.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
dist/favicon-96x96.png
vendored
Normal file
BIN
dist/favicon-96x96.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
dist/favicon.ico
vendored
Normal file
BIN
dist/favicon.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
10
dist/index.html
vendored
10
dist/index.html
vendored
@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Dubdiff 2</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">If you see this then something is wrong.</div>
|
||||
<script src="dist/browser-bundle.js"></script>
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.2/semantic.min.css"></link>
|
||||
<link href="dist/main.css" rel="stylesheet"> </body>
|
||||
</html>
|
7020
dist/old-dubdiff.css
vendored
7020
dist/old-dubdiff.css
vendored
File diff suppressed because it is too large
Load Diff
@ -18,32 +18,22 @@ import LocalStorage from './LocalStorage'
|
||||
|
||||
|
||||
|
||||
//the localStore implementation is naive
|
||||
//initial state should be rehydrated from the server
|
||||
//then additional state transformations should be applied based on localStore contents
|
||||
// (or not? maybe localStore is not needed)
|
||||
|
||||
//initial state is rehydrated from the server
|
||||
const initialState = window.__INITIAL_STATE__
|
||||
|
||||
|
||||
//create the list of middlewares
|
||||
let middlewares = [thunk]
|
||||
|
||||
//create the redux store
|
||||
//initial state is retrieved from localStore
|
||||
const store = Redux.createStore(
|
||||
Redux.combineReducers(reducers),
|
||||
initialState,
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(Redux.applyMiddleware(...middlewares)):
|
||||
Redux.applyMiddleware(...middlewares)
|
||||
Redux.compose(
|
||||
Redux.applyMiddleware(thunk),
|
||||
window.devToolsExtension ? window.devToolsExtension() : f => f
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function render() {
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
|
@ -1,27 +1,33 @@
|
||||
import fetch from 'isomorphic-fetch'
|
||||
import uuid from 'uuid/v4'
|
||||
import {browserHistory} from 'react-router'
|
||||
import {Status, StatusError} from './constants'
|
||||
|
||||
//All state transitions in the app happen in these methods
|
||||
//this includes redux state changes, asyncronous data requests, and browser location changes
|
||||
|
||||
export const updateOriginalInput = (text) =>
|
||||
(dispatch, getState) => {
|
||||
dispatch({ type: 'UPDATE_ORIGINAL_INPUT', data:text})
|
||||
dispatch({type: 'UPDATE_ORIGINAL_INPUT', data:text})
|
||||
if (getState().input.original.length>0)
|
||||
dispatch({type: 'SAVE_STATUS_DIRTY'})
|
||||
dispatch({type: 'STATUS_SET', data:Status.DIRTY})
|
||||
else
|
||||
dispatch({type: 'SAVE_STATUS_EMPTY'})
|
||||
dispatch({type: 'STATUS_SET', data:Status.EMPTY})
|
||||
}
|
||||
|
||||
export const updateFinalInput = (text) =>
|
||||
(dispatch, getState) => {
|
||||
dispatch({ type: 'UPDATE_FINAL_INPUT', data:text})
|
||||
if (getState().input.final.length>0)
|
||||
dispatch({type: 'SAVE_STATUS_DIRTY'})
|
||||
dispatch({type: 'STATUS_SET', data:Status.DIRTY})
|
||||
else
|
||||
dispatch({type: 'SAVE_STATUS_EMPTY'})
|
||||
dispatch({type: 'STATUS_SET', data:Status.EMPTY})
|
||||
}
|
||||
|
||||
export const clearInput = () =>
|
||||
(dispatch) => {
|
||||
dispatch({ type: 'CLEAR_INPUT'})
|
||||
dispatch({ type: 'SAVE_STATUS_EMPTY'})
|
||||
dispatch({type: 'CLEAR_INPUT'})
|
||||
dispatch({type: 'STATUS_SET', data:Status.EMPTY})
|
||||
}
|
||||
|
||||
export const setPlaintextFormat = () => ({ type: 'SET_PLAINTEXT_FORMAT'})
|
||||
@ -31,8 +37,42 @@ export const showFinal = () => ({ type: 'SHOW_FINAL'})
|
||||
export const showDifference = () => ({ type: 'SHOW_DIFFERENCE'})
|
||||
|
||||
|
||||
//if the input is dirty, saves it to the server
|
||||
//creates a new uuid for the same,
|
||||
//then changes the browser location to a comparison view with that id
|
||||
export const compare = () =>
|
||||
(dispatch, getState) => {
|
||||
//!!! could test that the input is dirty before triggering a save
|
||||
//if the input is empty, the compare should do nothing
|
||||
//if the input is clean, the compare should not save and keep using the same id
|
||||
|
||||
//start saving the input to the server
|
||||
const id = dispatch(save())
|
||||
|
||||
//we can use the id created by the save method to build a path
|
||||
const comparePath = `/${id}`
|
||||
browserHistory.replace(comparePath)
|
||||
}
|
||||
|
||||
|
||||
//clear the input and return to the edit page
|
||||
export const reset = () =>
|
||||
(dispatch, getState) => {
|
||||
dispatch(clearInput())
|
||||
browserHistory.push('/')
|
||||
}
|
||||
|
||||
|
||||
//switch to the edit view
|
||||
export const edit = () =>
|
||||
(dispatch, getState) => {
|
||||
browserHistory.push('/')
|
||||
}
|
||||
|
||||
|
||||
//saves the current input fields to the server
|
||||
//creates and returns a new id for the
|
||||
//creates and returns a new id for the comparison
|
||||
//should this method ensure that the initial state is valid? ('DIRTY')
|
||||
export const save = () =>
|
||||
(dispatch, getState) => {
|
||||
|
||||
@ -40,7 +80,7 @@ export const save = () =>
|
||||
const id = uuid()
|
||||
|
||||
//set waiting state
|
||||
dispatch( {type: 'SAVE_STATUS_WAITING'})
|
||||
dispatch( {type: 'STATUS_SET', data:Status.SAVING})
|
||||
|
||||
const endpointUri = `/api/compare/${id}`
|
||||
const fetchOptions = {
|
||||
@ -58,10 +98,11 @@ export const save = () =>
|
||||
//dispatch post request
|
||||
fetch(endpointUri, fetchOptions)
|
||||
.then(response => {
|
||||
dispatch( {type: 'SAVE_STATUS_SAVED'})
|
||||
dispatch({type: 'STATUS_SET', data: Status.CLEAN})
|
||||
})
|
||||
.catch(error => {
|
||||
dispatch( {type: 'SAVE_STATUS_FAILED', error})
|
||||
dispatch({type: 'STATUS_SET', data: Status.DIRTY})
|
||||
dispatch({type: 'STATUS_SET_ERROR', data: StatusError.SAVE_ERROR, error})
|
||||
})
|
||||
|
||||
//return the id after the request has been sent
|
||||
|
@ -21,16 +21,11 @@ const mapDispatchToProps = dispatch => ({
|
||||
onShowOriginal: () => dispatch(Actions.showOriginal()),
|
||||
onShowFinal: () => dispatch(Actions.showFinal()),
|
||||
onShowDifference: () => dispatch(Actions.showDifference()),
|
||||
onEdit: () => {
|
||||
}
|
||||
onEdit: () => dispatch(Actions.edit())
|
||||
})
|
||||
|
||||
class CompareControls extends React.Component {
|
||||
|
||||
onClickEdit() {
|
||||
this.props.onEdit()
|
||||
}
|
||||
|
||||
onClickMarkdownFormat() {
|
||||
if (this.props.isMarkdownFormat)
|
||||
this.props.onSetPlaintextFormat()
|
||||
@ -43,7 +38,7 @@ class CompareControls extends React.Component {
|
||||
return (
|
||||
<Segment.Group>
|
||||
<Segment>
|
||||
<Link to="/"><Button fluid onClick={this.onClickEdit.bind(this)}>Edit</Button></Link>
|
||||
<Button fluid onClick={this.props.onEdit}>Edit</Button>
|
||||
</Segment>
|
||||
|
||||
<Segment >
|
||||
|
@ -12,10 +12,7 @@ const mapStateToProps = (state) => ({
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onClear: () => {
|
||||
dispatch(Actions.clearInput())
|
||||
dispatch(Actions.clearCompare())
|
||||
},
|
||||
onReset: () => { console.log(Actions.reset()); dispatch(Actions.reset())},
|
||||
})
|
||||
|
||||
const SiteHeader = (props) => (
|
||||
@ -24,7 +21,7 @@ const SiteHeader = (props) => (
|
||||
<Segment basic >
|
||||
|
||||
<Segment basic padded textAlign="center" as="header" id='masthead'>
|
||||
<Header><Link onClick={props.onClear} to="/">dubdiff</Link></Header>
|
||||
<Header><Link onClick={props.onReset}>dubdiff</Link></Header>
|
||||
</Segment>
|
||||
|
||||
<Rail internal position="right">
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {browserHistory} from 'react-router'
|
||||
|
||||
import {Button, Icon, Segment} from 'semantic-ui-react'
|
||||
|
||||
@ -19,24 +18,11 @@ const mapDispatchToProps = dispatch => ({
|
||||
onSetMarkdownFormat: (format) => dispatch(Actions.setMarkdownFormat()),
|
||||
|
||||
//returns an id for the record to be saved
|
||||
startSaveAsync: () => {
|
||||
return dispatch(Actions.save())
|
||||
}
|
||||
onCompare: () => dispatch(Actions.compare())
|
||||
})
|
||||
|
||||
class MainControls extends React.Component {
|
||||
|
||||
onClickCompare() {
|
||||
//start saving the input to the server
|
||||
const id = this.props.startSaveAsync()
|
||||
|
||||
//we can use the id created by the save method to build a path
|
||||
const comparePath = `/${id}`
|
||||
browserHistory.replace(comparePath)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
onClickMarkdownFormat() {
|
||||
if (this.props.isMarkdownFormat)
|
||||
this.props.onSetPlaintextFormat()
|
||||
@ -49,7 +35,7 @@ class MainControls extends React.Component {
|
||||
return (
|
||||
<Segment.Group>
|
||||
<Segment >
|
||||
<Button fluid onClick={this.onClickCompare.bind(this)}>Compare</Button>
|
||||
<Button fluid onClick={this.props.onCompare}>Compare</Button>
|
||||
</Segment>
|
||||
|
||||
<Segment >
|
||||
|
@ -5,27 +5,20 @@ import { Message, Icon, Button} from 'semantic-ui-react'
|
||||
import { browserHistory} from 'react-router'
|
||||
|
||||
import * as Actions from '../actions'
|
||||
import {Status, StatusError} from '../constants'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
saveStatus: state.saveStatus
|
||||
status: state.status
|
||||
})
|
||||
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
retrySave: () => dispatch(Actions.save())
|
||||
onSave: () => dispatch(Actions.save())
|
||||
})
|
||||
|
||||
const onRetrySaveClick = (props) => {
|
||||
//we can use the id created by the save method to build a path
|
||||
const id = props.retrySave()
|
||||
const comparePath = `/${id}`
|
||||
browserHistory.replace(comparePath)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
const SaveStatus = (props) => {
|
||||
if (props.saveStatus.waiting) return (
|
||||
console.log(props.status)
|
||||
if (props.status.type == Status.SAVING) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='circle notched' loading />
|
||||
<Message.Content>
|
||||
@ -33,16 +26,32 @@ const SaveStatus = (props) => {
|
||||
</Message.Content>
|
||||
</Message>
|
||||
)
|
||||
else if (props.saveStatus.failed) return (
|
||||
if (props.status.type == Status.LOADING) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='circle notched' loading />
|
||||
<Message.Content>
|
||||
<Message.Header>Loading diff</Message.Header>
|
||||
</Message.Content>
|
||||
</Message>
|
||||
)
|
||||
else if (props.status.hasError && props.status.errorType == StatusError.SAVE_ERROR) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='exclamation' />
|
||||
<Message.Content>
|
||||
<Message.Header>Error saving diff</Message.Header>
|
||||
The server returned {props.saveStatus.error.message}.
|
||||
<Button onClick={()=>onRetrySaveClick(props)}>Retry</Button>
|
||||
{props.status.error.message}
|
||||
<Button onClick={props.onSave}>Retry</Button>
|
||||
</Message.Content>
|
||||
</Message>
|
||||
|
||||
</Message>
|
||||
)
|
||||
else if (props.status.hasError && props.status.errorType == StatusError.LOAD_ERROR) return (
|
||||
<Message size='tiny' floating compact icon>
|
||||
<Icon name='exclamation' />
|
||||
<Message.Content>
|
||||
<Message.Header>Error loading diff</Message.Header>
|
||||
Server returned {props.status.error}
|
||||
</Message.Content>
|
||||
</Message>
|
||||
)
|
||||
|
||||
else return ( <div></div> )
|
||||
|
@ -8,3 +8,17 @@ export const Show = {
|
||||
FINAL:'FINAL',
|
||||
DIFFERENCE:'DIFFERENCE'
|
||||
}
|
||||
|
||||
export const Status = {
|
||||
INIT: 'INIT',
|
||||
LOADING: 'LOADING',
|
||||
EMPTY: 'EMPTY',
|
||||
CLEAN: 'CLEAN',
|
||||
DIRTY: 'DIRTY',
|
||||
SAVING: 'SAVING'
|
||||
}
|
||||
|
||||
export const StatusError = {
|
||||
LOADING_ERROR: 'LOAD_ERROR',
|
||||
SAVING_ERROR: 'SAVE_ERROR'
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import {Format, Show} from './constants'
|
||||
import {Format, Show, Status, StatusError} from './constants'
|
||||
|
||||
|
||||
export function input (state, action ) {
|
||||
@ -39,7 +39,7 @@ export function show (state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
export function saveStatus (state, action) {
|
||||
switch (action.type) {
|
||||
case 'SAVE_STATUS_DIRTY':
|
||||
@ -56,17 +56,20 @@ export function saveStatus (state, action) {
|
||||
return state || {empty: true, dirty:false}
|
||||
}
|
||||
}
|
||||
/*
|
||||
export function loadStatus (state, action) {
|
||||
switch (action.type) {
|
||||
case 'LOAD_STATUS_WAITING':
|
||||
return {waiting: true}
|
||||
case 'LOAD_STATUS_FAILED':
|
||||
return {failed: true, error: action.error }
|
||||
case 'LOAD_STATUS_LOADED':
|
||||
return {loaded: true}
|
||||
default:
|
||||
return state || {waiting: false}
|
||||
}
|
||||
*/
|
||||
|
||||
//tracks status of the app, especially with respect to loaded and saved user data
|
||||
export function status (state, action) {
|
||||
//the status or error type is valid if it is in the list of Status or StatusError types
|
||||
const isValidStatus = (type) => Status[type] == type
|
||||
const isValidError = (type) => StatusError[type] == type
|
||||
|
||||
//the error is cleared when status changes
|
||||
if (action.type == 'STATUS_SET' && isValidStatus(action.data))
|
||||
return {type:action.data, error: null, hasError: false, errorType: null}
|
||||
//the error is set in addition to the status
|
||||
else if (action.type == 'STATUS_SET_ERROR' && isValidError(action.data))
|
||||
return Object.assign({}, state, {error: action.error, hasError: true, errorType:action.data})
|
||||
else
|
||||
return {type:Status.EMPTY, hasError: false, error:null}
|
||||
}
|
||||
*/
|
@ -51,7 +51,10 @@ const pageTemplate = (body) => {
|
||||
<link rel="stylesheet" href="dist/main.css"/>
|
||||
|
||||
<!-- Favicon -->
|
||||
<!--<link rel="shortcut icon" href="/assets/favicon.ico">-->
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="dist/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
Loading…
Reference in New Issue
Block a user