@ -1,13 +1,18 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
import PropTypes from 'prop-types'; | |||
import emojify from '../../../emoji'; | |||
import escapeTextContentForBrowser from 'escape-html'; | |||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | |||
import IconButton from '../../../components/icon_button'; | |||
import Avatar from '../../../components/avatar'; | |||
import ImmutablePureComponent from 'react-immutable-pure-component'; | |||
import { processBio } from '../util/bio_metadata'; | |||
// Mastodon imports // | |||
import emojify from '../../../mastodon/emoji'; | |||
import IconButton from '../../../mastodon/components/icon_button'; | |||
import Avatar from '../../../mastodon/components/avatar'; | |||
// Our imports // | |||
import { processBio } from '../../util/bio_metadata'; | |||
const messages = defineMessages({ | |||
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, |
@ -1,13 +1,18 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
import StatusContainer from '../../../containers/status_container'; | |||
import AccountContainer from '../../../containers/account_container'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import Permalink from '../../../components/permalink'; | |||
import emojify from '../../../emoji'; | |||
import escapeTextContentForBrowser from 'escape-html'; | |||
import ImmutablePureComponent from 'react-immutable-pure-component'; | |||
// Mastodon imports // | |||
import AccountContainer from '../../../mastodon/containers/account_container'; | |||
import Permalink from '../../../mastodon/components/permalink'; | |||
import emojify from '../../../mastodon/emoji'; | |||
// Our imports // | |||
import StatusContainer from '../../containers/status'; | |||
export default class Notification extends ImmutablePureComponent { | |||
static propTypes = { |
@ -0,0 +1,79 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
export default class SettingsItem extends React.PureComponent { | |||
static propTypes = { | |||
settings: ImmutablePropTypes.map.isRequired, | |||
item: PropTypes.array.isRequired, | |||
id: PropTypes.string.isRequired, | |||
options: PropTypes.arrayOf(PropTypes.shape({ | |||
value: PropTypes.string.isRequired, | |||
message: PropTypes.object.isRequired, | |||
})), | |||
dependsOn: PropTypes.array, | |||
dependsOnNot: PropTypes.array, | |||
children: PropTypes.element.isRequired, | |||
onChange: PropTypes.func.isRequired, | |||
}; | |||
handleChange = (e) => { | |||
const { item, onChange } = this.props; | |||
onChange(item, e); | |||
} | |||
render () { | |||
const { settings, item, id, options, children, dependsOn, dependsOnNot } = this.props; | |||
let enabled = true; | |||
if (dependsOn) { | |||
for (let i = 0; i < dependsOn.length; i++) { | |||
enabled = enabled && settings.getIn(dependsOn[i]); | |||
} | |||
} | |||
if (dependsOnNot) { | |||
for (let i = 0; i < dependsOnNot.length; i++) { | |||
enabled = enabled && !settings.getIn(dependsOnNot[i]); | |||
} | |||
} | |||
if (options && options.length > 0) { | |||
const currentValue = settings.getIn(item); | |||
const optionElems = options && options.length > 0 && options.map((opt) => ( | |||
<option key={opt.value} selected={currentValue === opt.value} value={opt.value} > | |||
{opt.message} | |||
</option> | |||
)); | |||
return ( | |||
<label htmlFor={id}> | |||
<p>{children}</p> | |||
<p> | |||
<select | |||
id={id} | |||
disabled={!enabled} | |||
onBlur={this.handleChange} | |||
> | |||
{optionElems} | |||
</select> | |||
</p> | |||
</label> | |||
); | |||
} else { | |||
return ( | |||
<label htmlFor={id}> | |||
<input | |||
id={id} | |||
type='checkbox' | |||
checked={settings.getIn(item)} | |||
onChange={this.handleChange} | |||
disabled={!enabled} | |||
/> | |||
{children} | |||
</label> | |||
); | |||
} | |||
} | |||
} |
@ -1,11 +1,14 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
import PropTypes from 'prop-types'; | |||
import IconButton from './icon_button'; | |||
import DropdownMenu from './dropdown_menu'; | |||
import { defineMessages, injectIntl } from 'react-intl'; | |||
import ImmutablePureComponent from 'react-immutable-pure-component'; | |||
import RelativeTimestamp from './relative_timestamp'; | |||
// Mastodon imports // | |||
import RelativeTimestamp from '../../../mastodon/components/relative_timestamp'; | |||
import IconButton from '../../../mastodon/components/icon_button'; | |||
import DropdownMenu from '../../../mastodon/components/dropdown_menu'; | |||
const messages = defineMessages({ | |||
delete: { id: 'status.delete', defaultMessage: 'Delete' }, |
@ -1,11 +1,14 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
import escapeTextContentForBrowser from 'escape-html'; | |||
import PropTypes from 'prop-types'; | |||
import emojify from '../emoji'; | |||
import { isRtl } from '../rtl'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import Permalink from './permalink'; | |||
// Mastodon imports // | |||
import emojify from '../../../mastodon/emoji'; | |||
import { isRtl } from '../../../mastodon/rtl'; | |||
import Permalink from '../../../mastodon/components/permalink'; | |||
export default class StatusContent extends React.PureComponent { | |||
@ -0,0 +1,79 @@ | |||
// Package imports // | |||
import React from 'react'; | |||
import ImmutablePropTypes from 'react-immutable-proptypes'; | |||
import PropTypes from 'prop-types'; | |||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | |||
// Mastodon imports // | |||
import IconButton from '../../../../mastodon/components/icon_button'; | |||
// Our imports // | |||
import StatusGalleryItem from './item'; | |||
const messages = defineMessages({ | |||
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }, | |||
}); | |||
@injectIntl | |||
export default class StatusGallery extends React.PureComponent { | |||
static propTypes = { | |||
sensitive: PropTypes.bool, | |||
media: ImmutablePropTypes.list.isRequired, | |||
letterbox: PropTypes.bool, | |||
fullwidth: PropTypes.bool, | |||
height: PropTypes.number.isRequired, | |||
onOpenMedia: PropTypes.func.isRequired, | |||
intl: PropTypes.object.isRequired, | |||
autoPlayGif: PropTypes.bool.isRequired, | |||
}; | |||
state = { | |||
visible: !this.props.sensitive, | |||
}; | |||
handleOpen = () => { | |||
this.setState({ visible: !this.state.visible }); | |||
} | |||
handleClick = (index) => { | |||
this.props.onOpenMedia(this.props.media, index); | |||
} | |||
render () { | |||
const { media, intl, sensitive, letterbox, fullwidth } = this.props; | |||
let children; | |||
if (!this.state.visible) { | |||
let warning; | |||
if (sensitive) { | |||
warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />; | |||
} else { | |||
warning = <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />; | |||
} | |||
children = ( | |||
<div role='button' tabIndex='0' className='media-spoiler' onClick={this.handleOpen}> | |||
<span className='media-spoiler__warning'>{warning}</span> | |||
<span className='media-spoiler__trigger'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span> | |||
</div> | |||
); | |||
} else { | |||
const size = media.take(4).size; | |||
children = media.take(4).map((attachment, i) => <StatusGalleryItem key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} autoPlayGif={this.props.autoPlayGif} index={i} size={size} letterbox={letterbox} />); | |||
} | |||
return ( | |||
<div className={`media-gallery ${fullwidth ? 'full-width' : ''}`} style={{ height: `${this.props.height}px` }}> | |||
<div className={`spoiler-button ${this.state.visible ? 'spoiler-button--visible' : ''}`}> | |||
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} overlay onClick={this.handleOpen} /> | |||
</div> | |||
{children} | |||
</div> | |||
); | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
// Package imports // | |||
import { connect } from 'react-redux'; | |||
// Mastodon imports // | |||
import { changeComposeAdvancedOption } from '../../../mastodon/actions/compose'; | |||
// Our imports // | |||
import ComposeAdvancedOptions from '../../components/compose/advanced_options'; | |||
const mapStateToProps = state => ({ | |||
values: state.getIn(['compose', 'advanced_options']), | |||
}); | |||
const mapDispatchToProps = dispatch => ({ | |||
onChange (option) { | |||
dispatch(changeComposeAdvancedOption(option)); | |||
}, | |||
}); | |||
export default connect(mapStateToProps, mapDispatchToProps)(ComposeAdvancedOptions); |
@ -1,6 +1,11 @@ | |||
// Package imports // | |||
import { connect } from 'react-redux'; | |||
import { makeGetNotification } from '../../../selectors'; | |||
import Notification from '../components/notification'; | |||
// Mastodon imports // | |||
import { makeGetNotification } from '../../../mastodon/selectors'; | |||
// Our imports // | |||
import Notification from '../../components/notification'; | |||
const makeMapStateToProps = () => { | |||
const getNotification = makeGetNotification(); |
@ -1,7 +1,12 @@ | |||
import { LOCAL_SETTING_CHANGE } from '../actions/local_settings'; | |||
import { STORE_HYDRATE } from '../actions/store'; | |||
// Package imports // | |||
import Immutable from 'immutable'; | |||
// Mastodon imports // | |||
import { STORE_HYDRATE } from '../../mastodon/actions/store'; | |||
// Our imports // | |||
import { LOCAL_SETTING_CHANGE } from '../actions/local_settings'; | |||
const initialState = Immutable.fromJS({ | |||
layout : 'auto', | |||
stretch : true, |
@ -1,17 +0,0 @@ | |||
import { connect } from 'react-redux'; | |||
import AdvancedOptionsDropdown from '../components/advanced_options_dropdown'; | |||
import { changeComposeAdvancedOption } from '../../../actions/compose'; | |||
const mapStateToProps = state => ({ | |||
values: state.getIn(['compose', 'advanced_options']), | |||
}); | |||
const mapDispatchToProps = dispatch => ({ | |||
onChange (option) { | |||
dispatch(changeComposeAdvancedOption(option)); | |||
}, | |||
}); | |||
export default connect(mapStateToProps, mapDispatchToProps)(AdvancedOptionsDropdown); |