diff options
Diffstat (limited to 'app/assets/javascripts/components')
26 files changed, 70 insertions, 44 deletions
diff --git a/app/assets/javascripts/components/components/autosuggest_textarea.jsx b/app/assets/javascripts/components/components/autosuggest_textarea.jsx index 744424661..04328aae8 100644 --- a/app/assets/javascripts/components/components/autosuggest_textarea.jsx +++ b/app/assets/javascripts/components/components/autosuggest_textarea.jsx @@ -178,7 +178,12 @@ const AutosuggestTextarea = React.createClass({ <div style={{ display: (suggestions.size > 0 && !suggestionsHidden) ? 'block' : 'none' }} className='autosuggest-textarea__suggestions'> {suggestions.map((suggestion, i) => ( - <div key={suggestion} className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} onClick={this.onSuggestionClick.bind(this, suggestion)}> + <div + role='button' + tabIndex='0' + key={suggestion} + className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} + onClick={this.onSuggestionClick.bind(this, suggestion)}> <AutosuggestAccountContainer id={suggestion} /> </div> ))} diff --git a/app/assets/javascripts/components/components/button.jsx b/app/assets/javascripts/components/components/button.jsx index babc6b259..c3e184024 100644 --- a/app/assets/javascripts/components/components/button.jsx +++ b/app/assets/javascripts/components/components/button.jsx @@ -9,6 +9,7 @@ const Button = React.createClass({ block: React.PropTypes.bool, secondary: React.PropTypes.bool, size: React.PropTypes.number, + style: React.PropTypes.object, children: React.PropTypes.node }, diff --git a/app/assets/javascripts/components/components/column_back_button.jsx b/app/assets/javascripts/components/components/column_back_button.jsx index 6b5ffee53..91c3b92be 100644 --- a/app/assets/javascripts/components/components/column_back_button.jsx +++ b/app/assets/javascripts/components/components/column_back_button.jsx @@ -15,13 +15,13 @@ const ColumnBackButton = React.createClass({ mixins: [PureRenderMixin], handleClick () { - if (window.history && window.history.length == 1) this.context.router.push("/"); + if (window.history && window.history.length === 1) this.context.router.push("/"); else this.context.router.goBack(); }, render () { return ( - <div onClick={this.handleClick} className='column-back-button'> + <div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'> <i className='fa fa-fw fa-chevron-left' style={iconStyle} /> <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> </div> diff --git a/app/assets/javascripts/components/components/column_back_button_slim.jsx b/app/assets/javascripts/components/components/column_back_button_slim.jsx index 780e3b182..536964b01 100644 --- a/app/assets/javascripts/components/components/column_back_button_slim.jsx +++ b/app/assets/javascripts/components/components/column_back_button_slim.jsx @@ -31,7 +31,7 @@ const ColumnBackButtonSlim = React.createClass({ render () { return ( <div style={{ position: 'relative' }}> - <div style={outerStyle} onClick={this.handleClick} className='column-back-button'> + <div role='button' tabIndex='0' style={outerStyle} onClick={this.handleClick} className='column-back-button'> <i className='fa fa-fw fa-chevron-left' style={iconStyle} /> <FormattedMessage id='column_back_button.label' defaultMessage='Back' /> </div> diff --git a/app/assets/javascripts/components/components/column_collapsable.jsx b/app/assets/javascripts/components/components/column_collapsable.jsx index 85ce63835..75dfc8a4e 100644 --- a/app/assets/javascripts/components/components/column_collapsable.jsx +++ b/app/assets/javascripts/components/components/column_collapsable.jsx @@ -46,7 +46,9 @@ const ColumnCollapsable = React.createClass({ return ( <div style={{ position: 'relative' }}> - <div title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} onClick={this.handleToggleCollapsed}><i className={`fa fa-${icon}`} /></div> + <div role='button' tabIndex='0' title={`${title}`} style={{...iconStyle }} className={`column-icon ${collapsedClassName}`} 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, collapsed ? undefined : { stiffness: 150, damping: 9 }) }}> {({ opacity, height }) => diff --git a/app/assets/javascripts/components/components/load_more.jsx b/app/assets/javascripts/components/components/load_more.jsx index 2cb9b09a8..b4bc8b711 100644 --- a/app/assets/javascripts/components/components/load_more.jsx +++ b/app/assets/javascripts/components/components/load_more.jsx @@ -1,7 +1,7 @@ import { FormattedMessage } from 'react-intl'; const LoadMore = ({ onClick }) => ( - <a href='#' className='load-more' onClick={onClick}> + <a href="#" className='load-more' role='button' onClick={onClick}> <FormattedMessage id='status.load_more' defaultMessage='Load more' /> </a> ); diff --git a/app/assets/javascripts/components/components/media_gallery.jsx b/app/assets/javascripts/components/components/media_gallery.jsx index 10b7d525b..325fd8157 100644 --- a/app/assets/javascripts/components/components/media_gallery.jsx +++ b/app/assets/javascripts/components/components/media_gallery.jsx @@ -220,7 +220,7 @@ const MediaGallery = React.createClass({ } children = ( - <div style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}> + <div role='button' tabIndex='0' style={spoilerStyle} className='media-spoiler' onClick={this.handleOpen}> <span style={spoilerSpanStyle}>{warning}</span> <span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span> </div> diff --git a/app/assets/javascripts/components/components/permalink.jsx b/app/assets/javascripts/components/components/permalink.jsx index ae2fb0d29..ebfa63cbc 100644 --- a/app/assets/javascripts/components/components/permalink.jsx +++ b/app/assets/javascripts/components/components/permalink.jsx @@ -6,7 +6,8 @@ const Permalink = React.createClass({ propTypes: { href: React.PropTypes.string.isRequired, - to: React.PropTypes.string.isRequired + to: React.PropTypes.string.isRequired, + children: React.PropTypes.node.isRequired }, handleClick (e) { diff --git a/app/assets/javascripts/components/components/status_content.jsx b/app/assets/javascripts/components/components/status_content.jsx index 33e407e43..ce8ead41e 100644 --- a/app/assets/javascripts/components/components/status_content.jsx +++ b/app/assets/javascripts/components/components/status_content.jsx @@ -119,7 +119,7 @@ const StatusContent = React.createClass({ return ( <div className='status__content' style={{ cursor: 'pointer' }} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}> <p style={{ marginBottom: hidden && status.get('mentions').size === 0 ? '0px' : '' }} > - <span dangerouslySetInnerHTML={spoilerContent} /> <a className='status__content__spoiler-link' onClick={this.handleSpoilerClick}>{toggleText}</a> + <span dangerouslySetInnerHTML={spoilerContent} /> <a tabIndex='0' className='status__content__spoiler-link' role='button' onClick={this.handleSpoilerClick}>{toggleText}</a> </p> {mentionsPlaceholder} diff --git a/app/assets/javascripts/components/components/video_player.jsx b/app/assets/javascripts/components/components/video_player.jsx index dce276c75..e9e860e39 100644 --- a/app/assets/javascripts/components/components/video_player.jsx +++ b/app/assets/javascripts/components/components/video_player.jsx @@ -194,7 +194,7 @@ const VideoPlayer = React.createClass({ if (!this.state.visible) { if (sensitive) { return ( - <div style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}> + <div role='button' tabIndex='0' style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}> {spoilerButton} <span style={spoilerSpanStyle}><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span> <span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span> @@ -202,7 +202,7 @@ const VideoPlayer = React.createClass({ ); } else { return ( - <div style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}> + <div role='button' tabIndex='0' style={{...spoilerStyle, width: `${width}px`, height: `${height}px` }} className='media-spoiler' onClick={this.handleVisibility}> {spoilerButton} <span style={spoilerSpanStyle}><FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' /></span> <span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span> @@ -213,7 +213,7 @@ const VideoPlayer = React.createClass({ if (this.state.preview && !autoplay) { return ( - <div style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}> + <div role='button' tabIndex='0' style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}> {spoilerButton} <div style={{ position: 'absolute', top: '50%', left: '50%', fontSize: '36px', transform: 'translate(-50%, -50%)', padding: '5px', borderRadius: '100px', color: 'rgba(255, 255, 255, 0.8)' }}><i className='fa fa-play' /></div> </div> @@ -225,7 +225,7 @@ const VideoPlayer = React.createClass({ {spoilerButton} {muteButton} {expandButton} - <video ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} /> + <video role='button' tabIndex='0' ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} /> </div> ); } diff --git a/app/assets/javascripts/components/features/account/components/header.jsx b/app/assets/javascripts/components/features/account/components/header.jsx index a359963c4..c4619a3c7 100644 --- a/app/assets/javascripts/components/features/account/components/header.jsx +++ b/app/assets/javascripts/components/features/account/components/header.jsx @@ -43,7 +43,16 @@ const Avatar = React.createClass({ return ( <Motion defaultStyle={{ radius: 90 }} style={{ radius: spring(isHovered ? 30 : 90, { stiffness: 180, damping: 12 }) }}> {({ radius }) => - <a href={account.get('url')} className='account__header__avatar' target='_blank' rel='noopener' style={{ display: 'block', width: '90px', height: '90px', margin: '0 auto', marginBottom: '10px', borderRadius: `${radius}px`, overflow: 'hidden' }} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}> + <a + href={account.get('url')} + className='account__header__avatar' + target='_blank' + rel='noopener' + style={{ display: 'block', width: '90px', height: '90px', margin: '0 auto', marginBottom: '10px', borderRadius: `${radius}px`, overflow: 'hidden' }} + onMouseOver={this.handleMouseOver} + onMouseOut={this.handleMouseOut} + onFocus={this.handleMouseOver} + onBlur={this.handleMouseOut}> <img src={account.get('avatar')} alt={account.get('acct')} style={{ display: 'block', width: '90px', height: '90px' }} /> </a> } diff --git a/app/assets/javascripts/components/features/compose/components/privacy_dropdown.jsx b/app/assets/javascripts/components/features/compose/components/privacy_dropdown.jsx index e54fa4d28..de8942d4d 100644 --- a/app/assets/javascripts/components/features/compose/components/privacy_dropdown.jsx +++ b/app/assets/javascripts/components/features/compose/components/privacy_dropdown.jsx @@ -83,7 +83,7 @@ const PrivacyDropdown = React.createClass({ <div className='privacy-dropdown__value'><IconButton icon={valueOption.icon} title={intl.formatMessage(messages.change_privacy)} size={18} active={open} inverted onClick={this.handleToggle} style={iconStyle} /></div> <div className='privacy-dropdown__dropdown'> {options.map(item => - <div key={item.value} onClick={this.handleClick.bind(this, item.value)} className={`privacy-dropdown__option ${item.value === value ? 'active' : ''}`}> + <div role='button' tabIndex='0' key={item.value} onClick={this.handleClick.bind(this, item.value)} className={`privacy-dropdown__option ${item.value === value ? 'active' : ''}`}> <div className='privacy-dropdown__option__icon'><i className={`fa fa-fw fa-${item.icon}`} /></div> <div className='privacy-dropdown__option__content'> <strong>{item.shortText}</strong> diff --git a/app/assets/javascripts/components/features/compose/components/search.jsx b/app/assets/javascripts/components/features/compose/components/search.jsx index 936e003f2..9ca1f5dc5 100644 --- a/app/assets/javascripts/components/features/compose/components/search.jsx +++ b/app/assets/javascripts/components/features/compose/components/search.jsx @@ -36,6 +36,10 @@ const Search = React.createClass({ } }, + noop () { + + }, + handleFocus () { this.props.onShow(); }, @@ -56,9 +60,9 @@ const Search = React.createClass({ onFocus={this.handleFocus} /> - <div className='search__icon'> + <div role='button' tabIndex='0' className='search__icon' onClick={hasValue ? this.handleClear : this.noop}> <i className={`fa fa-search ${hasValue ? '' : 'active'}`} /> - <i className={`fa fa-times-circle ${hasValue ? 'active' : ''}`} onClick={this.handleClear} /> + <i aria-label="Clear search" className={`fa fa-times-circle ${hasValue ? 'active' : ''}`} /> </div> </div> ); diff --git a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx index debbfd01f..63fe86af6 100644 --- a/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx +++ b/app/assets/javascripts/components/features/notifications/components/clear_column_button.jsx @@ -15,7 +15,7 @@ const ClearColumnButton = React.createClass({ const { intl } = this.props; return ( - <div title={intl.formatMessage(messages.clear)} className='column-icon column-icon-clear' tabIndex='0' onClick={this.props.onClick}> + <div role='button' title={intl.formatMessage(messages.clear)} className='column-icon column-icon-clear' tabIndex='0' onClick={this.props.onClick}> <i className='fa fa-eraser' /> </div> ); diff --git a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx b/app/assets/javascripts/components/features/notifications/components/column_settings.jsx index 2edf98292..03bfaa653 100644 --- a/app/assets/javascripts/components/features/notifications/components/column_settings.jsx +++ b/app/assets/javascripts/components/features/notifications/components/column_settings.jsx @@ -27,9 +27,11 @@ const ColumnSettings = React.createClass({ propTypes: { settings: ImmutablePropTypes.map.isRequired, - intl: React.PropTypes.object.isRequired, onChange: React.PropTypes.func.isRequired, onSave: React.PropTypes.func.isRequired, + intl: React.PropTypes.shape({ + formatMessage: React.PropTypes.func.isRequired + }).isRequired }, mixins: [PureRenderMixin], diff --git a/app/assets/javascripts/components/features/notifications/components/notification.jsx b/app/assets/javascripts/components/features/notifications/components/notification.jsx index fdebe4bb5..2a9f2d076 100644 --- a/app/assets/javascripts/components/features/notifications/components/notification.jsx +++ b/app/assets/javascripts/components/features/notifications/components/notification.jsx @@ -71,7 +71,7 @@ const Notification = React.createClass({ ); }, - render () { + render () { // eslint-disable-line consistent-return const { notification } = this.props; const account = notification.get('account'); const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username'); diff --git a/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx b/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx index eae3c2be2..c4bfad5cd 100644 --- a/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx +++ b/app/assets/javascripts/components/features/notifications/components/setting_toggle.jsx @@ -14,8 +14,8 @@ const labelSpanStyle = { marginLeft: '8px' }; -const SettingToggle = ({ settings, settingKey, label, onChange }) => ( - <label style={labelStyle}> +const SettingToggle = ({ settings, settingKey, label, onChange, htmlFor = '' }) => ( + <label htmlFor={htmlFor} style={labelStyle}> <Toggle checked={settings.getIn(settingKey)} onChange={(e) => onChange(settingKey, e.target.checked)} /> <span className='setting-toggle' style={labelSpanStyle}>{label}</span> </label> @@ -25,7 +25,8 @@ SettingToggle.propTypes = { settings: ImmutablePropTypes.map.isRequired, settingKey: React.PropTypes.array.isRequired, label: React.PropTypes.node.isRequired, - onChange: React.PropTypes.func.isRequired + onChange: React.PropTypes.func.isRequired, + htmlFor: React.PropTypes.string }; export default SettingToggle; diff --git a/app/assets/javascripts/components/features/ui/components/column_header.jsx b/app/assets/javascripts/components/features/ui/components/column_header.jsx index b7052ffaf..1df0b3da9 100644 --- a/app/assets/javascripts/components/features/ui/components/column_header.jsx +++ b/app/assets/javascripts/components/features/ui/components/column_header.jsx @@ -25,7 +25,7 @@ const ColumnHeader = React.createClass({ } return ( - <div aria-label={type} className={`column-header ${active ? 'active' : ''}`} onClick={this.handleClick}> + <div role='button' tabIndex='0' aria-label={type} className={`column-header ${active ? 'active' : ''}`} onClick={this.handleClick}> {icon} {type} </div> diff --git a/app/assets/javascripts/components/features/ui/components/column_link.jsx b/app/assets/javascripts/components/features/ui/components/column_link.jsx index 2bd1e1017..fb253bbbd 100644 --- a/app/assets/javascripts/components/features/ui/components/column_link.jsx +++ b/app/assets/javascripts/components/features/ui/components/column_link.jsx @@ -34,7 +34,8 @@ ColumnLink.propTypes = { icon: React.PropTypes.string.isRequired, text: React.PropTypes.string.isRequired, to: React.PropTypes.string, - href: React.PropTypes.string + href: React.PropTypes.string, + method: React.PropTypes.string }; export default ColumnLink; diff --git a/app/assets/javascripts/components/features/ui/components/media_modal.jsx b/app/assets/javascripts/components/features/ui/components/media_modal.jsx index 130f48b46..786b08152 100644 --- a/app/assets/javascripts/components/features/ui/components/media_modal.jsx +++ b/app/assets/javascripts/components/features/ui/components/media_modal.jsx @@ -104,8 +104,8 @@ const MediaModal = React.createClass({ leftNav = rightNav = content = ''; if (media.size > 1) { - leftNav = <div style={leftNavStyle} className='modal-container__nav' onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>; - rightNav = <div style={rightNavStyle} className='modal-container__nav' onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>; + leftNav = <div role='button' tabIndex='0' style={leftNavStyle} className='modal-container__nav' onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>; + rightNav = <div role='button' tabIndex='0' style={rightNavStyle} className='modal-container__nav' onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>; } if (attachment.get('type') === 'image') { diff --git a/app/assets/javascripts/components/features/ui/components/modal_root.jsx b/app/assets/javascripts/components/features/ui/components/modal_root.jsx index 74eb50039..a1ed8fd88 100644 --- a/app/assets/javascripts/components/features/ui/components/modal_root.jsx +++ b/app/assets/javascripts/components/features/ui/components/modal_root.jsx @@ -66,7 +66,7 @@ const ModalRoot = React.createClass({ return ( <div key={key}> - <div className='modal-root__overlay' style={{ opacity: style.opacity, transform: `translateZ(0px)` }} onClick={onClose} /> + <div role='presentation' className='modal-root__overlay' style={{ opacity: style.opacity, transform: `translateZ(0px)` }} onClick={onClose} /> <div className='modal-root__container' style={{ opacity: style.opacity, transform: `translateZ(0px) scale(${style.scale})` }}> <SpecificComponent {...props} onClose={onClose} /> </div> diff --git a/app/assets/javascripts/components/link_header.jsx b/app/assets/javascripts/components/link_header.jsx index 9a9ff7e7a..b872dc24a 100644 --- a/app/assets/javascripts/components/link_header.jsx +++ b/app/assets/javascripts/components/link_header.jsx @@ -14,7 +14,7 @@ Link.parseAttrs = (link, parts) => { link = Link.parseParams(link, uriAttrs[1]) } - while(match = Link.attrPattern.exec(attrs)) { + while(match = Link.attrPattern.exec(attrs)) { // eslint-disable-line no-cond-assign attr = match[1].toLowerCase() value = match[4] || match[3] || match[2] diff --git a/app/assets/javascripts/components/locales/es.jsx b/app/assets/javascripts/components/locales/es.jsx index 7e9c0dc2c..b118def8b 100644 --- a/app/assets/javascripts/components/locales/es.jsx +++ b/app/assets/javascripts/components/locales/es.jsx @@ -73,7 +73,7 @@ const es = { "notifications.column_settings.mention": "Menciones:", "notifications.column_settings.reblog": "Retoots:", "emoji_button.label": "Insertar emoji", - "privacy.public.short": "Público", + "privacy.public.short": "Público", "privacy.public.long": "Mostrar en la historia federada", "privacy.unlisted.short": "Sin federar", "privacy.unlisted.long": "No mostrar en la historia federada", diff --git a/app/assets/javascripts/components/locales/ru.jsx b/app/assets/javascripts/components/locales/ru.jsx index 95ed52656..5d84527b6 100644 --- a/app/assets/javascripts/components/locales/ru.jsx +++ b/app/assets/javascripts/components/locales/ru.jsx @@ -16,7 +16,7 @@ const ru = { "status.show_less": "Свернуть", "status.open": "Развернуть статус", "status.report": "Пожаловаться", - "status.load_more": "Показать еще", + "status.load_more": "Показать еще", "video_player.toggle_sound": "Вкл./выкл. звук", "video_player.toggle_visible": "Показать/скрыть", "account.disclaimer": "Это пользователь с другого узла. Число может быть больше.", diff --git a/app/assets/javascripts/components/middleware/errors.jsx b/app/assets/javascripts/components/middleware/errors.jsx index 4aca75f1e..9a51257cb 100644 --- a/app/assets/javascripts/components/middleware/errors.jsx +++ b/app/assets/javascripts/components/middleware/errors.jsx @@ -22,7 +22,7 @@ export default function errorsMiddleware() { dispatch(showAlert(title, message)); } else { - console.error(action.error); + console.error(action.error); // eslint-disable-line no-console dispatch(showAlert('Oops!', 'An unexpected error occurred.')); } } diff --git a/app/assets/javascripts/components/reducers/alerts.jsx b/app/assets/javascripts/components/reducers/alerts.jsx index 42987f649..dc0145824 100644 --- a/app/assets/javascripts/components/reducers/alerts.jsx +++ b/app/assets/javascripts/components/reducers/alerts.jsx @@ -9,17 +9,17 @@ const initialState = Immutable.List([]); export default function alerts(state = initialState, action) { switch(action.type) { - case ALERT_SHOW: - return state.push(Immutable.Map({ - key: state.size > 0 ? state.last().get('key') + 1 : 0, - title: action.title, - message: action.message - })); - case ALERT_DISMISS: - return state.filterNot(item => item.get('key') === action.alert.key); - case ALERT_CLEAR: - return state.clear(); - default: - return state; + case ALERT_SHOW: + return state.push(Immutable.Map({ + key: state.size > 0 ? state.last().get('key') + 1 : 0, + title: action.title, + message: action.message + })); + case ALERT_DISMISS: + return state.filterNot(item => item.get('key') === action.alert.key); + case ALERT_CLEAR: + return state.clear(); + default: + return state; } }; |