diff options
Diffstat (limited to 'app/javascript/themes/glitch/features/notifications')
10 files changed, 0 insertions, 661 deletions
diff --git a/app/javascript/themes/glitch/features/notifications/components/clear_column_button.js b/app/javascript/themes/glitch/features/notifications/components/clear_column_button.js deleted file mode 100644 index 22a10753f..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/clear_column_button.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; - -export default class ClearColumnButton extends React.Component { - - static propTypes = { - onClick: PropTypes.func.isRequired, - }; - - render () { - return ( - <button className='text-btn column-header__setting-btn' tabIndex='0' onClick={this.props.onClick}><i className='fa fa-eraser' /> <FormattedMessage id='notifications.clear' defaultMessage='Clear notifications' /></button> - ); - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/components/column_settings.js b/app/javascript/themes/glitch/features/notifications/components/column_settings.js deleted file mode 100644 index 88a29d4d3..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/column_settings.js +++ /dev/null @@ -1,86 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { FormattedMessage } from 'react-intl'; -import ClearColumnButton from './clear_column_button'; -import SettingToggle from './setting_toggle'; - -export default class ColumnSettings extends React.PureComponent { - - static propTypes = { - settings: ImmutablePropTypes.map.isRequired, - pushSettings: ImmutablePropTypes.map.isRequired, - onChange: PropTypes.func.isRequired, - onSave: PropTypes.func.isRequired, - onClear: PropTypes.func.isRequired, - }; - - onPushChange = (key, checked) => { - this.props.onChange(['push', ...key], checked); - } - - render () { - const { settings, pushSettings, onChange, onClear } = this.props; - - const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />; - const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />; - const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />; - - const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed'); - const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />; - const pushMeta = showPushSettings && <FormattedMessage id='notifications.column_settings.push_meta' defaultMessage='This device' />; - - return ( - <div> - <div className='column-settings__row'> - <ClearColumnButton onClick={onClear} /> - </div> - - <div role='group' aria-labelledby='notifications-follow'> - <span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span> - - <div className='column-settings__row'> - <SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} /> - {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'follow']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />} - <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} /> - <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} /> - </div> - </div> - - <div role='group' aria-labelledby='notifications-favourite'> - <span id='notifications-favourite' className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span> - - <div className='column-settings__row'> - <SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} /> - {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'favourite']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />} - <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} /> - <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} /> - </div> - </div> - - <div role='group' aria-labelledby='notifications-mention'> - <span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span> - - <div className='column-settings__row'> - <SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} /> - {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'mention']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />} - <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} /> - <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} /> - </div> - </div> - - <div role='group' aria-labelledby='notifications-reblog'> - <span id='notifications-reblog' className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span> - - <div className='column-settings__row'> - <SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} /> - {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'reblog']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />} - <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} /> - <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} /> - </div> - </div> - </div> - ); - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/components/follow.js b/app/javascript/themes/glitch/features/notifications/components/follow.js deleted file mode 100644 index 8a0f01736..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/follow.js +++ /dev/null @@ -1,97 +0,0 @@ -// Package imports. -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { HotKeys } from 'react-hotkeys'; - -// Our imports. -import Permalink from 'themes/glitch/components/permalink'; -import AccountContainer from 'themes/glitch/containers/account_container'; -import NotificationOverlayContainer from '../containers/overlay_container'; - -export default class NotificationFollow extends ImmutablePureComponent { - - static propTypes = { - id: PropTypes.string.isRequired, - account: ImmutablePropTypes.map.isRequired, - notification: ImmutablePropTypes.map.isRequired, - }; - - handleMoveUp = () => { - const { notification, onMoveUp } = this.props; - onMoveUp(notification.get('id')); - } - - handleMoveDown = () => { - const { notification, onMoveDown } = this.props; - onMoveDown(notification.get('id')); - } - - handleOpen = () => { - this.handleOpenProfile(); - } - - handleOpenProfile = () => { - const { notification } = this.props; - this.context.router.history.push(`/accounts/${notification.getIn(['account', 'id'])}`); - } - - handleMention = e => { - e.preventDefault(); - - const { notification, onMention } = this.props; - onMention(notification.get('account'), this.context.router.history); - } - - getHandlers () { - return { - moveUp: this.handleMoveUp, - moveDown: this.handleMoveDown, - open: this.handleOpen, - openProfile: this.handleOpenProfile, - mention: this.handleMention, - reply: this.handleMention, - }; - } - - render () { - const { account, notification } = this.props; - - // Links to the display name. - const displayName = account.get('display_name_html') || account.get('username'); - const link = ( - <Permalink - className='notification__display-name' - href={account.get('url')} - title={account.get('acct')} - to={`/accounts/${account.get('id')}`} - dangerouslySetInnerHTML={{ __html: displayName }} - /> - ); - - // Renders. - return ( - <HotKeys handlers={this.getHandlers()}> - <div className='notification notification-follow focusable' tabIndex='0'> - <div className='notification__message'> - <div className='notification__favourite-icon-wrapper'> - <i className='fa fa-fw fa-user-plus' /> - </div> - - <FormattedMessage - id='notification.follow' - defaultMessage='{name} followed you' - values={{ name: link }} - /> - </div> - - <AccountContainer id={account.get('id')} withNote={false} /> - <NotificationOverlayContainer notification={notification} /> - </div> - </HotKeys> - ); - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/components/notification.js b/app/javascript/themes/glitch/features/notifications/components/notification.js deleted file mode 100644 index a309d3a42..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/notification.js +++ /dev/null @@ -1,88 +0,0 @@ -// Package imports. -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -// Our imports, -import StatusContainer from 'themes/glitch/containers/status_container'; -import NotificationFollow from './follow'; - -export default class Notification extends ImmutablePureComponent { - - static propTypes = { - notification: ImmutablePropTypes.map.isRequired, - hidden: PropTypes.bool, - onMoveUp: PropTypes.func.isRequired, - onMoveDown: PropTypes.func.isRequired, - onMention: PropTypes.func.isRequired, - settings: ImmutablePropTypes.map.isRequired, - }; - - renderFollow () { - const { notification } = this.props; - return ( - <NotificationFollow - id={notification.get('id')} - account={notification.get('account')} - notification={notification} - /> - ); - } - - renderMention () { - const { notification } = this.props; - return ( - <StatusContainer - id={notification.get('status')} - notification={notification} - withDismiss - /> - ); - } - - renderFavourite () { - const { notification } = this.props; - return ( - <StatusContainer - id={notification.get('status')} - account={notification.get('account')} - prepend='favourite' - muted - notification={notification} - withDismiss - /> - ); - } - - renderReblog () { - const { notification } = this.props; - return ( - <StatusContainer - id={notification.get('status')} - account={notification.get('account')} - prepend='reblog' - muted - notification={notification} - withDismiss - /> - ); - } - - render () { - const { notification } = this.props; - switch(notification.get('type')) { - case 'follow': - return this.renderFollow(); - case 'mention': - return this.renderMention(); - case 'favourite': - return this.renderFavourite(); - case 'reblog': - return this.renderReblog(); - default: - return null; - } - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/components/overlay.js b/app/javascript/themes/glitch/features/notifications/components/overlay.js deleted file mode 100644 index e56f9c628..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/overlay.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Notification overlay - */ - - -// Package imports. -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl } from 'react-intl'; - -const messages = defineMessages({ - markForDeletion: { id: 'notification.markForDeletion', defaultMessage: 'Mark for deletion' }, -}); - -@injectIntl -export default class NotificationOverlay extends ImmutablePureComponent { - - static propTypes = { - notification : ImmutablePropTypes.map.isRequired, - onMarkForDelete : PropTypes.func.isRequired, - show : PropTypes.bool.isRequired, - intl : PropTypes.object.isRequired, - }; - - onToggleMark = () => { - const mark = !this.props.notification.get('markedForDelete'); - const id = this.props.notification.get('id'); - this.props.onMarkForDelete(id, mark); - } - - render () { - const { notification, show, intl } = this.props; - - const active = notification.get('markedForDelete'); - const label = intl.formatMessage(messages.markForDeletion); - - return show ? ( - <div - aria-label={label} - role='checkbox' - aria-checked={active} - tabIndex={0} - className={`notification__dismiss-overlay ${active ? 'active' : ''}`} - onClick={this.onToggleMark} - > - <div className='wrappy'> - <div className='ckbox' aria-hidden='true' title={label}> - {active ? (<i className='fa fa-check' />) : ''} - </div> - </div> - </div> - ) : null; - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/components/setting_toggle.js b/app/javascript/themes/glitch/features/notifications/components/setting_toggle.js deleted file mode 100644 index 281359d2a..000000000 --- a/app/javascript/themes/glitch/features/notifications/components/setting_toggle.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import Toggle from 'react-toggle'; - -export default class SettingToggle extends React.PureComponent { - - static propTypes = { - prefix: PropTypes.string, - settings: ImmutablePropTypes.map.isRequired, - settingKey: PropTypes.array.isRequired, - label: PropTypes.node.isRequired, - meta: PropTypes.node, - onChange: PropTypes.func.isRequired, - } - - onChange = ({ target }) => { - this.props.onChange(this.props.settingKey, target.checked); - } - - render () { - const { prefix, settings, settingKey, label, meta } = this.props; - const id = ['setting-toggle', prefix, ...settingKey].filter(Boolean).join('-'); - - return ( - <div className='setting-toggle'> - <Toggle id={id} checked={settings.getIn(settingKey)} onChange={this.onChange} onKeyDown={this.onKeyDown} /> - <label htmlFor={id} className='setting-toggle__label'>{label}</label> - {meta && <span className='setting-meta__label'>{meta}</span>} - </div> - ); - } - -} diff --git a/app/javascript/themes/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/themes/glitch/features/notifications/containers/column_settings_container.js deleted file mode 100644 index ddc8495f4..000000000 --- a/app/javascript/themes/glitch/features/notifications/containers/column_settings_container.js +++ /dev/null @@ -1,44 +0,0 @@ -import { connect } from 'react-redux'; -import { defineMessages, injectIntl } from 'react-intl'; -import ColumnSettings from '../components/column_settings'; -import { changeSetting, saveSettings } from 'themes/glitch/actions/settings'; -import { clearNotifications } from 'themes/glitch/actions/notifications'; -import { changeAlerts as changePushNotifications, saveSettings as savePushNotificationSettings } from 'themes/glitch/actions/push_notifications'; -import { openModal } from 'themes/glitch/actions/modal'; - -const messages = defineMessages({ - clearMessage: { id: 'notifications.clear_confirmation', defaultMessage: 'Are you sure you want to permanently clear all your notifications?' }, - clearConfirm: { id: 'notifications.clear', defaultMessage: 'Clear notifications' }, -}); - -const mapStateToProps = state => ({ - settings: state.getIn(['settings', 'notifications']), - pushSettings: state.get('push_notifications'), -}); - -const mapDispatchToProps = (dispatch, { intl }) => ({ - - onChange (key, checked) { - if (key[0] === 'push') { - dispatch(changePushNotifications(key.slice(1), checked)); - } else { - dispatch(changeSetting(['notifications', ...key], checked)); - } - }, - - onSave () { - dispatch(saveSettings()); - dispatch(savePushNotificationSettings()); - }, - - onClear () { - dispatch(openModal('CONFIRM', { - message: intl.formatMessage(messages.clearMessage), - confirm: intl.formatMessage(messages.clearConfirm), - onConfirm: () => dispatch(clearNotifications()), - })); - }, - -}); - -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ColumnSettings)); diff --git a/app/javascript/themes/glitch/features/notifications/containers/notification_container.js b/app/javascript/themes/glitch/features/notifications/containers/notification_container.js deleted file mode 100644 index b61aaa21c..000000000 --- a/app/javascript/themes/glitch/features/notifications/containers/notification_container.js +++ /dev/null @@ -1,27 +0,0 @@ -// Package imports. -import { connect } from 'react-redux'; - -// Our imports. -import { makeGetNotification } from 'themes/glitch/selectors'; -import Notification from '../components/notification'; -import { mentionCompose } from 'themes/glitch/actions/compose'; - -const makeMapStateToProps = () => { - const getNotification = makeGetNotification(); - - const mapStateToProps = (state, props) => ({ - notification: getNotification(state, props.notification, props.accountId), - settings: state.get('local_settings'), - notifCleaning: state.getIn(['notifications', 'cleaningMode']), - }); - - return mapStateToProps; -}; - -const mapDispatchToProps = dispatch => ({ - onMention: (account, router) => { - dispatch(mentionCompose(account, router)); - }, -}); - -export default connect(makeMapStateToProps, mapDispatchToProps)(Notification); diff --git a/app/javascript/themes/glitch/features/notifications/containers/overlay_container.js b/app/javascript/themes/glitch/features/notifications/containers/overlay_container.js deleted file mode 100644 index 52649cdd7..000000000 --- a/app/javascript/themes/glitch/features/notifications/containers/overlay_container.js +++ /dev/null @@ -1,18 +0,0 @@ -// Package imports. -import { connect } from 'react-redux'; - -// Our imports. -import NotificationOverlay from '../components/overlay'; -import { markNotificationForDelete } from 'themes/glitch/actions/notifications'; - -const mapDispatchToProps = dispatch => ({ - onMarkForDelete(id, yes) { - dispatch(markNotificationForDelete(id, yes)); - }, -}); - -const mapStateToProps = state => ({ - show: state.getIn(['notifications', 'cleaningMode']), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(NotificationOverlay); diff --git a/app/javascript/themes/glitch/features/notifications/index.js b/app/javascript/themes/glitch/features/notifications/index.js deleted file mode 100644 index 1ecde660a..000000000 --- a/app/javascript/themes/glitch/features/notifications/index.js +++ /dev/null @@ -1,193 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import Column from 'themes/glitch/components/column'; -import ColumnHeader from 'themes/glitch/components/column_header'; -import { - enterNotificationClearingMode, - expandNotifications, - scrollTopNotifications, -} from 'themes/glitch/actions/notifications'; -import { addColumn, removeColumn, moveColumn } from 'themes/glitch/actions/columns'; -import NotificationContainer from './containers/notification_container'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import ColumnSettingsContainer from './containers/column_settings_container'; -import { createSelector } from 'reselect'; -import { List as ImmutableList } from 'immutable'; -import { debounce } from 'lodash'; -import ScrollableList from 'themes/glitch/components/scrollable_list'; - -const messages = defineMessages({ - title: { id: 'column.notifications', defaultMessage: 'Notifications' }, -}); - -const getNotifications = createSelector([ - state => ImmutableList(state.getIn(['settings', 'notifications', 'shows']).filter(item => !item).keys()), - state => state.getIn(['notifications', 'items']), -], (excludedTypes, notifications) => notifications.filterNot(item => excludedTypes.includes(item.get('type')))); - -const mapStateToProps = state => ({ - notifications: getNotifications(state), - localSettings: state.get('local_settings'), - isLoading: state.getIn(['notifications', 'isLoading'], true), - isUnread: state.getIn(['notifications', 'unread']) > 0, - hasMore: !!state.getIn(['notifications', 'next']), - notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), -}); - -/* glitch */ -const mapDispatchToProps = dispatch => ({ - onEnterCleaningMode(yes) { - dispatch(enterNotificationClearingMode(yes)); - }, - dispatch, -}); - -@connect(mapStateToProps, mapDispatchToProps) -@injectIntl -export default class Notifications extends React.PureComponent { - - static propTypes = { - columnId: PropTypes.string, - notifications: ImmutablePropTypes.list.isRequired, - dispatch: PropTypes.func.isRequired, - shouldUpdateScroll: PropTypes.func, - intl: PropTypes.object.isRequired, - isLoading: PropTypes.bool, - isUnread: PropTypes.bool, - multiColumn: PropTypes.bool, - hasMore: PropTypes.bool, - localSettings: ImmutablePropTypes.map, - notifCleaningActive: PropTypes.bool, - onEnterCleaningMode: PropTypes.func, - }; - - static defaultProps = { - trackScroll: true, - }; - - handleScrollToBottom = debounce(() => { - this.props.dispatch(scrollTopNotifications(false)); - this.props.dispatch(expandNotifications()); - }, 300, { leading: true }); - - handleScrollToTop = debounce(() => { - this.props.dispatch(scrollTopNotifications(true)); - }, 100); - - handleScroll = debounce(() => { - this.props.dispatch(scrollTopNotifications(false)); - }, 100); - - handlePin = () => { - const { columnId, dispatch } = this.props; - - if (columnId) { - dispatch(removeColumn(columnId)); - } else { - dispatch(addColumn('NOTIFICATIONS', {})); - } - } - - handleMove = (dir) => { - const { columnId, dispatch } = this.props; - dispatch(moveColumn(columnId, dir)); - } - - handleHeaderClick = () => { - this.column.scrollTop(); - } - - setColumnRef = c => { - this.column = c; - } - - handleMoveUp = id => { - const elementIndex = this.props.notifications.findIndex(item => item.get('id') === id) - 1; - this._selectChild(elementIndex); - } - - handleMoveDown = id => { - const elementIndex = this.props.notifications.findIndex(item => item.get('id') === id) + 1; - this._selectChild(elementIndex); - } - - _selectChild (index) { - const element = this.column.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`); - - if (element) { - element.focus(); - } - } - - render () { - const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore } = this.props; - const pinned = !!columnId; - const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />; - - let scrollableContent = null; - - if (isLoading && this.scrollableContent) { - scrollableContent = this.scrollableContent; - } else if (notifications.size > 0 || hasMore) { - scrollableContent = notifications.map((item) => ( - <NotificationContainer - key={item.get('id')} - notification={item} - accountId={item.get('account')} - onMoveUp={this.handleMoveUp} - onMoveDown={this.handleMoveDown} - /> - )); - } else { - scrollableContent = null; - } - - this.scrollableContent = scrollableContent; - - const scrollContainer = ( - <ScrollableList - scrollKey={`notifications-${columnId}`} - trackScroll={!pinned} - isLoading={isLoading} - hasMore={hasMore} - emptyMessage={emptyMessage} - onScrollToBottom={this.handleScrollToBottom} - onScrollToTop={this.handleScrollToTop} - onScroll={this.handleScroll} - shouldUpdateScroll={shouldUpdateScroll} - > - {scrollableContent} - </ScrollableList> - ); - - return ( - <Column - ref={this.setColumnRef} - name='notifications' - extraClasses={this.props.notifCleaningActive ? 'notif-cleaning' : null} - > - <ColumnHeader - icon='bell' - active={isUnread} - title={intl.formatMessage(messages.title)} - onPin={this.handlePin} - onMove={this.handleMove} - onClick={this.handleHeaderClick} - pinned={pinned} - multiColumn={multiColumn} - localSettings={this.props.localSettings} - notifCleaning - notifCleaningActive={this.props.notifCleaningActive} // this is used to toggle the header text - onEnterCleaningMode={this.props.onEnterCleaningMode} - > - <ColumnSettingsContainer /> - </ColumnHeader> - - {scrollContainer} - </Column> - ); - } - -} |