parent
1e9d2c4b1e
commit
312c51b5c8
16 changed files with 462 additions and 150 deletions
@ -0,0 +1,60 @@ |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import { Motion, spring } from 'react-motion'; |
||||
|
||||
const iconStyle = { |
||||
fontSize: '16px', |
||||
padding: '15px', |
||||
position: 'absolute', |
||||
right: '0', |
||||
top: '-48px', |
||||
cursor: 'pointer' |
||||
}; |
||||
|
||||
const ColumnCollapsable = React.createClass({ |
||||
|
||||
propTypes: { |
||||
icon: React.PropTypes.string.isRequired, |
||||
fullHeight: React.PropTypes.number.isRequired, |
||||
children: React.PropTypes.node, |
||||
onCollapse: React.PropTypes.func |
||||
}, |
||||
|
||||
getInitialState () { |
||||
return { |
||||
collapsed: true |
||||
}; |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
handleToggleCollapsed () { |
||||
const currentState = this.state.collapsed; |
||||
|
||||
this.setState({ collapsed: !currentState }); |
||||
|
||||
if (!currentState && this.props.onCollapse) { |
||||
this.props.onCollapse(); |
||||
} |
||||
}, |
||||
|
||||
render () { |
||||
const { icon, fullHeight, children } = this.props; |
||||
const { collapsed } = this.state; |
||||
|
||||
return ( |
||||
<div style={{ position: 'relative' }}> |
||||
<div style={{...iconStyle, color: collapsed ? '#9baec8' : '#fff', background: collapsed ? '#2f3441' : '#373b4a' }} onClick={this.handleToggleCollapsed}><i className={`fa fa-${icon}`} /></div> |
||||
|
||||
<Motion defaultStyle={{ opacity: 0, height: 0 }} style={{ opacity: spring(collapsed ? 0 : 100), height: spring(collapsed ? 0 : fullHeight) }}> |
||||
{({ opacity, height }) => |
||||
<div style={{ overflow: 'hidden', height: `${height}px`, opacity: opacity / 100 }}> |
||||
{children} |
||||
</div> |
||||
} |
||||
</Motion> |
||||
</div> |
||||
); |
||||
} |
||||
}); |
||||
|
||||
export default ColumnCollapsable; |
@ -0,0 +1,68 @@ |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; |
||||
import ColumnCollapsable from '../../../components/column_collapsable'; |
||||
import SettingToggle from '../../notifications/components/setting_toggle'; |
||||
import SettingText from './setting_text'; |
||||
|
||||
const messages = defineMessages({ |
||||
filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter by regular expressions' } |
||||
}); |
||||
|
||||
const outerStyle = { |
||||
background: '#373b4a', |
||||
padding: '15px' |
||||
}; |
||||
|
||||
const sectionStyle = { |
||||
cursor: 'default', |
||||
display: 'block', |
||||
fontWeight: '500', |
||||
color: '#9baec8', |
||||
marginBottom: '10px' |
||||
}; |
||||
|
||||
const rowStyle = { |
||||
|
||||
}; |
||||
|
||||
const ColumnSettings = React.createClass({ |
||||
|
||||
propTypes: { |
||||
settings: ImmutablePropTypes.map.isRequired, |
||||
onChange: React.PropTypes.func.isRequired, |
||||
onSave: React.PropTypes.func.isRequired, |
||||
intl: React.PropTypes.object.isRequired |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
render () { |
||||
const { settings, onChange, onSave, intl } = this.props; |
||||
|
||||
return ( |
||||
<ColumnCollapsable icon='sliders' fullHeight={209} onCollapse={onSave}> |
||||
<div style={outerStyle}> |
||||
<span style={sectionStyle}><FormattedMessage id='home.column_settings.basic' defaultMessage='Basic' /></span> |
||||
|
||||
<div style={rowStyle}> |
||||
<SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show reblogs' />} /> |
||||
</div> |
||||
|
||||
<div style={rowStyle}> |
||||
<SettingToggle settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} /> |
||||
</div> |
||||
|
||||
<span style={sectionStyle}><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span> |
||||
|
||||
<div style={rowStyle}> |
||||
<SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} /> |
||||
</div> |
||||
</div> |
||||
</ColumnCollapsable> |
||||
); |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default injectIntl(ColumnSettings); |
@ -0,0 +1,41 @@ |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
|
||||
const style = { |
||||
display: 'block', |
||||
fontFamily: 'inherit', |
||||
marginBottom: '10px', |
||||
padding: '7px 0', |
||||
boxSizing: 'border-box', |
||||
width: '100%' |
||||
}; |
||||
|
||||
const SettingText = React.createClass({ |
||||
|
||||
propTypes: { |
||||
settings: ImmutablePropTypes.map.isRequired, |
||||
settingKey: React.PropTypes.array.isRequired, |
||||
label: React.PropTypes.string.isRequired, |
||||
onChange: React.PropTypes.func.isRequired |
||||
}, |
||||
|
||||
handleChange (e) { |
||||
this.props.onChange(this.props.settingKey, e.target.value) |
||||
}, |
||||
|
||||
render () { |
||||
const { settings, settingKey, label } = this.props; |
||||
|
||||
return ( |
||||
<input |
||||
style={style} |
||||
className='setting-text' |
||||
value={settings.getIn(settingKey)} |
||||
onChange={this.handleChange} |
||||
placeholder={label} |
||||
/> |
||||
); |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default SettingText; |
@ -0,0 +1,21 @@ |
||||
import { connect } from 'react-redux'; |
||||
import ColumnSettings from '../components/column_settings'; |
||||
import { changeSetting, saveSettings } from '../../../actions/settings'; |
||||
|
||||
const mapStateToProps = state => ({ |
||||
settings: state.getIn(['settings', 'home']) |
||||
}); |
||||
|
||||
const mapDispatchToProps = dispatch => ({ |
||||
|
||||
onChange (key, checked) { |
||||
dispatch(changeSetting(['home', ...key], checked)); |
||||
}, |
||||
|
||||
onSave () { |
||||
dispatch(saveSettings()); |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); |
@ -0,0 +1,32 @@ |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
import Toggle from 'react-toggle'; |
||||
|
||||
const labelStyle = { |
||||
display: 'block', |
||||
lineHeight: '24px', |
||||
verticalAlign: 'middle' |
||||
}; |
||||
|
||||
const labelSpanStyle = { |
||||
display: 'inline-block', |
||||
verticalAlign: 'middle', |
||||
marginBottom: '14px', |
||||
marginLeft: '8px', |
||||
color: '#9baec8' |
||||
}; |
||||
|
||||
const SettingToggle = ({ settings, settingKey, label, onChange }) => ( |
||||
<label style={labelStyle}> |
||||
<Toggle checked={settings.getIn(settingKey)} onChange={(e) => onChange(settingKey, e.target.checked)} /> |
||||
<span style={labelSpanStyle}>{label}</span> |
||||
</label> |
||||
); |
||||
|
||||
SettingToggle.propTypes = { |
||||
settings: ImmutablePropTypes.map.isRequired, |
||||
settingKey: React.PropTypes.array.isRequired, |
||||
label: React.PropTypes.node.isRequired, |
||||
onChange: React.PropTypes.func.isRequired |
||||
}; |
||||
|
||||
export default SettingToggle; |
Loading…
Reference in new issue