Cleaning up action names and compose drawer
This commit is contained in:
		
							
								
								
									
										49
									
								
								app/assets/javascripts/components/actions/compose.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/assets/javascripts/components/actions/compose.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| import api from '../api' | ||||
|  | ||||
| export const COMPOSE_CHANGE         = 'COMPOSE_CHANGE'; | ||||
| export const COMPOSE_SUBMIT         = 'COMPOSE_SUBMIT'; | ||||
| export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST'; | ||||
| export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'; | ||||
| export const COMPOSE_SUBMIT_FAIL    = 'COMPOSE_SUBMIT_FAIL'; | ||||
|  | ||||
| export function changeCompose(text) { | ||||
|   return { | ||||
|     type: COMPOSE_CHANGE, | ||||
|     text: text | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function submitCompose() { | ||||
|   return function (dispatch, getState) { | ||||
|     dispatch(submitComposeRequest()); | ||||
|  | ||||
|     api(getState).post('/api/statuses', { | ||||
|       status: getState().getIn(['compose', 'text'], ''), | ||||
|       in_reply_to_id: getState().getIn(['compose', 'in_reply_to_id'], null) | ||||
|     }).then(function (response) { | ||||
|       dispatch(submitComposeSuccess(response.data)); | ||||
|     }).catch(function (error) { | ||||
|       dispatch(submitComposeFail(error)); | ||||
|     }); | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function submitComposeRequest() { | ||||
|   return { | ||||
|     type: COMPOSE_SUBMIT_REQUEST | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function submitComposeSuccess(response) { | ||||
|   return { | ||||
|     type: COMPOSE_SUBMIT_SUCCESS | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function submitComposeFail(error) { | ||||
|   return { | ||||
|     type: COMPOSE_SUBMIT_FAIL, | ||||
|     error: error | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @@ -1,8 +1,8 @@ | ||||
| export const SET_ACCESS_TOKEN = 'SET_ACCESS_TOKEN'; | ||||
| export const ACCESS_TOKEN_SET = 'ACCESS_TOKEN_SET'; | ||||
|  | ||||
| export function setAccessToken(token) { | ||||
|   return { | ||||
|     type: SET_ACCESS_TOKEN, | ||||
|     type: ACCESS_TOKEN_SET, | ||||
|     token: token | ||||
|   }; | ||||
| } | ||||
|   | ||||
| @@ -1,81 +0,0 @@ | ||||
| import fetch from 'isomorphic-fetch' | ||||
|  | ||||
| export const SET_TIMELINE = 'SET_TIMELINE'; | ||||
| export const ADD_STATUS   = 'ADD_STATUS'; | ||||
|  | ||||
| export const PUBLISH       = 'PUBLISH'; | ||||
| export const PUBLISH_START = 'PUBLISH_START'; | ||||
| export const PUBLISH_SUCC  = 'PUBLISH_SUCC'; | ||||
| export const PUBLISH_ERROR = 'PUBLISH_ERROR'; | ||||
|  | ||||
| export function setTimeline(timeline, statuses) { | ||||
|   return { | ||||
|     type: SET_TIMELINE, | ||||
|     timeline: timeline, | ||||
|     statuses: statuses | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function addStatus(timeline, status) { | ||||
|   return { | ||||
|     type: ADD_STATUS, | ||||
|     timeline: timeline, | ||||
|     status: status | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function publishStart() { | ||||
|   return { | ||||
|     type: PUBLISH_START | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function publishError(error) { | ||||
|   return { | ||||
|     type: PUBLISH_ERROR, | ||||
|     error: error | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function publishSucc(status) { | ||||
|   return { | ||||
|     type: PUBLISH_SUCC, | ||||
|     status: status | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function publish(text, in_reply_to_id) { | ||||
|   return function (dispatch, getState) { | ||||
|     const access_token = getState().getIn(['meta', 'access_token']); | ||||
|  | ||||
|     var data = new FormData(); | ||||
|  | ||||
|     data.append('status', text); | ||||
|  | ||||
|     if (in_reply_to_id !== null) { | ||||
|       data.append('in_reply_to_id', in_reply_to_id); | ||||
|     } | ||||
|  | ||||
|     dispatch(publishStart()); | ||||
|  | ||||
|     return fetch('/api/statuses', { | ||||
|       method: 'POST', | ||||
|  | ||||
|       headers: { | ||||
|         'Authorization': `Bearer ${access_token}` | ||||
|       }, | ||||
|  | ||||
|       body: data | ||||
|     }).then(function (response) { | ||||
|       return response.json(); | ||||
|     }).then(function (json) { | ||||
|       if (json.error) { | ||||
|         dispatch(publishError(json.error)); | ||||
|       } else { | ||||
|         dispatch(publishSucc(json)); | ||||
|       } | ||||
|     }).catch(function (error) { | ||||
|       dispatch(publishError(error)); | ||||
|     }); | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										19
									
								
								app/assets/javascripts/components/actions/timelines.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/assets/javascripts/components/actions/timelines.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| export const TIMELINE_SET    = 'TIMELINE_SET'; | ||||
| export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; | ||||
|  | ||||
|  | ||||
| export function setTimeline(timeline, statuses) { | ||||
|   return { | ||||
|     type: TIMELINE_SET, | ||||
|     timeline: timeline, | ||||
|     statuses: statuses | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export function updateTimeline(timeline, status) { | ||||
|   return { | ||||
|     type: TIMELINE_UPDATE, | ||||
|     timeline: timeline, | ||||
|     status: status | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										11
									
								
								app/assets/javascripts/components/api.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/assets/javascripts/components/api.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| import axios from 'axios'; | ||||
|  | ||||
| export default getState => axios.create({ | ||||
|   headers: { | ||||
|     'Authorization': `Bearer ${getState().getIn(['meta', 'access_token'], '')}` | ||||
|   }, | ||||
|  | ||||
|   transformResponse: [function (data) { | ||||
|     return JSON.parse(data); | ||||
|   }] | ||||
| }); | ||||
| @@ -1,9 +1,13 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const Avatar = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     src: React.PropTypes.string.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ width: '48px', height: '48px', flex: '0 0 auto' }}> | ||||
|   | ||||
| @@ -1,12 +1,21 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const Button = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     text: React.PropTypes.string.isRequired, | ||||
|     onClick: React.PropTypes.func | ||||
|     onClick: React.PropTypes.func, | ||||
|     disabled: React.PropTypes.boolean | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   handleClick (e) { | ||||
|     e.preventDefault(); | ||||
|     this.props.onClick(); | ||||
|  | ||||
|     if (!this.props.disabled) { | ||||
|       this.props.onClick(); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   render () { | ||||
|   | ||||
| @@ -1,8 +1,13 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const CharacterCounter = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     text: React.PropTypes.string.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <span style={{ fontSize: '16px', cursor: 'default' }}> | ||||
|   | ||||
| @@ -1,12 +1,16 @@ | ||||
| import StatusListContainer from '../containers/status_list_container'; | ||||
| import ColumnHeader        from './column_header'; | ||||
| import PureRenderMixin     from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const Column = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     type: React.PropTypes.string | ||||
|   }, | ||||
|  | ||||
|   render: function() { | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ width: '380px', flex: '0 0 auto', background: '#282c37', margin: '10px', marginRight: '0', display: 'flex', flexDirection: 'column' }}> | ||||
|         <ColumnHeader type={this.props.type} /> | ||||
| @@ -14,6 +18,7 @@ const Column = React.createClass({ | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default Column; | ||||
|   | ||||
| @@ -1,15 +1,21 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const ColumnHeader = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     type: React.PropTypes.string | ||||
|   }, | ||||
|  | ||||
|   render: function() { | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ padding: '15px', fontSize: '16px', background: '#2f3441', flex: '0 0 auto' }}> | ||||
|         {this.props.type} | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default ColumnHeader; | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| import Column from './column'; | ||||
| import Column          from './column'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const ColumnsArea = React.createClass({ | ||||
|  | ||||
|   render: function() { | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ display: 'flex', flexDirection: 'row', flex: '1' }}> | ||||
|         <Column type='home' /> | ||||
| @@ -10,6 +13,7 @@ const ColumnsArea = React.createClass({ | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default ColumnsArea; | ||||
|   | ||||
| @@ -1,42 +1,40 @@ | ||||
| import CharacterCounter from './character_counter'; | ||||
| import Button           from './button'; | ||||
| import { publish }      from '../actions/statuses'; | ||||
| import PureRenderMixin  from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const ComposerDrawer = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     text: React.PropTypes.string.isRequired, | ||||
|     isSubmitting: React.PropTypes.boolean, | ||||
|     onChange: React.PropTypes.func.isRequired, | ||||
|     onSubmit: React.PropTypes.func.isRequired | ||||
|   }, | ||||
|  | ||||
|   getInitialState() { | ||||
|     return { | ||||
|       text: '' | ||||
|     }; | ||||
|   }, | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   handleChange (e) { | ||||
|     this.setState({ text: e.target.value }); | ||||
|     this.props.onChange(e.target.value); | ||||
|   }, | ||||
|  | ||||
|   handleKeyUp (e) { | ||||
|     if (e.keyCode === 13 && e.ctrlKey) { | ||||
|       this.handleSubmit(); | ||||
|       this.props.onSubmit(); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   handleSubmit () { | ||||
|     this.props.onSubmit(this.state.text, null); | ||||
|     this.setState({ text: '' }); | ||||
|     this.props.onSubmit(); | ||||
|   }, | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ width: '230px', background: '#454b5e', margin: '10px 0', padding: '10px' }}> | ||||
|         <textarea placeholder='What is on your mind?' value={this.state.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', background: '#fff', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px' }} /> | ||||
|       <div style={{ width: '380px', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '10px' }}> | ||||
|         <textarea disabled={this.props.isSubmitting} placeholder='What is on your mind?' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', background: '#fff', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px' }} /> | ||||
|  | ||||
|         <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||
|           <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} /></div> | ||||
|           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter text={this.state.text} /></div> | ||||
|           <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.isSubmitting} /></div> | ||||
|           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter text={this.props.text} /></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   | ||||
| @@ -1,10 +1,14 @@ | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PureRenderMixin    from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const DisplayName = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     account: ImmutablePropTypes.map.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     var displayName = this.props.account.get('display_name', this.props.account.get('username')); | ||||
|     var acct        = this.props.account.get('acct'); | ||||
|   | ||||
| @@ -1,18 +1,20 @@ | ||||
| import NavBar                  from './nav_bar'; | ||||
| import ColumnsArea             from './columns_area'; | ||||
| import ComposerDrawerContainer from '../containers/composer_drawer_container'; | ||||
| import PureRenderMixin         from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const Frontend = React.createClass({ | ||||
|  | ||||
|   render: function() { | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ flex: '0 0 auto', display: 'flex', width: '100%', height: '100%', background: '#1a1c23' }}> | ||||
|         <NavBar /> | ||||
|         <ComposerDrawerContainer /> | ||||
|         <ColumnsArea /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default Frontend; | ||||
|   | ||||
| @@ -1,12 +0,0 @@ | ||||
| const NavBar = React.createClass({ | ||||
|  | ||||
|   render: function() { | ||||
|     return ( | ||||
|       <div style={{ background: '#2f3441', width: '60px', margin: '10px', marginRight: '0' }}> | ||||
|  | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| export default NavBar; | ||||
| @@ -1,4 +1,5 @@ | ||||
| import moment from 'moment'; | ||||
| import moment          from 'moment'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| moment.updateLocale('en', { | ||||
|   relativeTime : { | ||||
| @@ -19,6 +20,7 @@ moment.updateLocale('en', { | ||||
| }); | ||||
|  | ||||
| const RelativeTimestamp = React.createClass({ | ||||
|  | ||||
|   getInitialState () { | ||||
|     return { | ||||
|       text: '' | ||||
| @@ -29,6 +31,8 @@ const RelativeTimestamp = React.createClass({ | ||||
|     timestamp: React.PropTypes.string.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   componentWillMount () { | ||||
|     this._updateMomentText(); | ||||
|     this.interval = setInterval(this._updateMomentText, 6000); | ||||
|   | ||||
| @@ -2,12 +2,16 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import Avatar             from './avatar'; | ||||
| import DisplayName        from './display_name'; | ||||
| import RelativeTimestamp  from './relative_timestamp'; | ||||
| import PureRenderMixin    from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const Status = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     status: ImmutablePropTypes.map.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     var content = { __html: this.props.status.get('content') }; | ||||
|     var status  = this.props.status; | ||||
| @@ -30,6 +34,7 @@ const Status = React.createClass({ | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default Status; | ||||
|   | ||||
| @@ -1,12 +1,16 @@ | ||||
| import Status             from './status'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import PureRenderMixin    from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const StatusList = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     statuses: ImmutablePropTypes.list.isRequired | ||||
|   }, | ||||
|  | ||||
|   render: function() { | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ overflowY: 'scroll', flex: '1 1 auto' }}> | ||||
|         <div> | ||||
| @@ -17,6 +21,7 @@ const StatusList = React.createClass({ | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default StatusList; | ||||
|   | ||||
| @@ -1,15 +1,22 @@ | ||||
| import { connect }    from 'react-redux'; | ||||
| import ComposerDrawer from '../components/composer_drawer'; | ||||
| import { publish }    from '../actions/statuses'; | ||||
| import { connect }                      from 'react-redux'; | ||||
| import ComposerDrawer                   from '../components/composer_drawer'; | ||||
| import { changeCompose, submitCompose } from '../actions/compose'; | ||||
|  | ||||
| const mapStateToProps = function (state, props) { | ||||
|   return {}; | ||||
|   return { | ||||
|     text: state.getIn(['compose', 'text']), | ||||
|     isSubmitting: state.getIn(['compose', 'isSubmitting']) | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| const mapDispatchToProps = function (dispatch) { | ||||
|   return { | ||||
|     onSubmit: function (text, in_reply_to_id) { | ||||
|       dispatch(publish(text, in_reply_to_id)); | ||||
|     onChange: function (text) { | ||||
|       dispatch(changeCompose(text)); | ||||
|     }, | ||||
|  | ||||
|     onSubmit: function () { | ||||
|       dispatch(submitCompose()); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import { Provider }               from 'react-redux'; | ||||
| import configureStore             from '../store/configureStore'; | ||||
| import Frontend                   from '../components/frontend'; | ||||
| import { setTimeline, addStatus } from '../actions/statuses'; | ||||
| import { setAccessToken }         from '../actions/meta'; | ||||
| import PureRenderMixin            from 'react-addons-pure-render-mixin'; | ||||
| import { Provider }                    from 'react-redux'; | ||||
| import configureStore                  from '../store/configureStore'; | ||||
| import Frontend                        from '../components/frontend'; | ||||
| import { setTimeline, updateTimeline } from '../actions/timelines'; | ||||
| import { setAccessToken }              from '../actions/meta'; | ||||
| import PureRenderMixin                 from 'react-addons-pure-render-mixin'; | ||||
|  | ||||
| const store = configureStore(); | ||||
|  | ||||
| @@ -11,7 +11,7 @@ const Root = React.createClass({ | ||||
|  | ||||
|   propTypes: { | ||||
|     token: React.PropTypes.string.isRequired, | ||||
|     timelines: React.PropTypes.array | ||||
|     timelines: React.PropTypes.object | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
| @@ -32,13 +32,13 @@ const Root = React.createClass({ | ||||
|         disconnected: function() {}, | ||||
|  | ||||
|         received: function(data) { | ||||
|           return store.dispatch(addStatus(data.timeline, JSON.parse(data.message))); | ||||
|           return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message))); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   render() { | ||||
|   render () { | ||||
|     return ( | ||||
|       <Provider store={store}> | ||||
|         <Frontend /> | ||||
|   | ||||
| @@ -3,7 +3,7 @@ import StatusList  from '../components/status_list'; | ||||
|  | ||||
| const mapStateToProps = function (state, props) { | ||||
|   return { | ||||
|     statuses: state.getIn(['statuses', props.type]) | ||||
|     statuses: state.getIn(['timelines', props.type]) | ||||
|   }; | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										25
									
								
								app/assets/javascripts/components/reducers/compose.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/assets/javascripts/components/reducers/compose.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| import { COMPOSE_CHANGE, COMPOSE_SUBMIT_REQUEST, COMPOSE_SUBMIT_SUCCESS, COMPOSE_SUBMIT_FAIL } from '../actions/compose'; | ||||
| import Immutable                                                                               from 'immutable'; | ||||
|  | ||||
| const initialState = Immutable.Map({ | ||||
|   text: '', | ||||
|   in_reply_to_id: null, | ||||
|   isSubmitting: false | ||||
| }); | ||||
|  | ||||
| export default function compose(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case COMPOSE_CHANGE: | ||||
|       return state.set('text', action.text); | ||||
|     case COMPOSE_SUBMIT_REQUEST: | ||||
|       return state.set('isSubmitting', true); | ||||
|     case COMPOSE_SUBMIT_SUCCESS: | ||||
|       return state.withMutations(map => { | ||||
|         map.set('text', '').set('isSubmitting', false); | ||||
|       }); | ||||
|     case COMPOSE_SUBMIT_FAIL: | ||||
|       return state.set('isSubmitting', false); | ||||
|     default: | ||||
|       return state; | ||||
|   } | ||||
| } | ||||
| @@ -1,8 +1,10 @@ | ||||
| import { combineReducers } from 'redux-immutable'; | ||||
| import statuses            from './statuses'; | ||||
| import timelines           from './timelines'; | ||||
| import meta                from './meta'; | ||||
| import compose             from './compose'; | ||||
|  | ||||
| export default combineReducers({ | ||||
|   statuses, | ||||
|   meta | ||||
|   timelines, | ||||
|   meta, | ||||
|   compose | ||||
| }); | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| import { SET_ACCESS_TOKEN }         from '../actions/meta'; | ||||
| import { ACCESS_TOKEN_SET }         from '../actions/meta'; | ||||
| import Immutable                    from 'immutable'; | ||||
|  | ||||
| const initialState = Immutable.Map(); | ||||
|  | ||||
| export default function meta(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case SET_ACCESS_TOKEN: | ||||
|     case ACCESS_TOKEN_SET: | ||||
|       return state.set('access_token', action.token); | ||||
|     default: | ||||
|       return state; | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import { SET_TIMELINE, ADD_STATUS } from '../actions/statuses'; | ||||
| import Immutable                    from 'immutable'; | ||||
| import { TIMELINE_SET, TIMELINE_UPDATE } from '../actions/timelines'; | ||||
| import Immutable                         from 'immutable'; | ||||
| 
 | ||||
| const initialState = Immutable.Map(); | ||||
| 
 | ||||
| export default function statuses(state = initialState, action) { | ||||
| export default function timelines(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case SET_TIMELINE: | ||||
|     case TIMELINE_SET: | ||||
|       return state.set(action.timeline, Immutable.fromJS(action.statuses)); | ||||
|     case ADD_STATUS: | ||||
|     case TIMELINE_UPDATE: | ||||
|       return state.update(action.timeline, function (list) { | ||||
|         return list.unshift(Immutable.fromJS(action.status)); | ||||
|       }); | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { createStore, applyMiddleware } from 'redux'; | ||||
| import { createStore, applyMiddleware, compose } from 'redux'; | ||||
| import thunk from 'redux-thunk'; | ||||
| import appReducer from '../reducers'; | ||||
|  | ||||
| export default function configureStore() { | ||||
|   return createStore(appReducer, applyMiddleware(thunk)); | ||||
| export default function configureStore(initialState) { | ||||
|   return createStore(appReducer, initialState, compose(applyMiddleware(thunk), window.devToolsExtension ? window.devToolsExtension() : f => f)); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user