import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from 'flavours/glitch/components/column';
import ColumnHeader from 'flavours/glitch/components/column_header';
import {
enterNotificationClearingMode,
expandNotifications,
scrollTopNotifications,
} from 'flavours/glitch/actions/notifications';
import { addColumn, removeColumn, moveColumn } from 'flavours/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 'flavours/glitch/components/scrollable_list';
import LoadMore from 'flavours/glitch/components/load_more';
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 => item !== null && excludedTypes.includes(item.get('type'))));
class LoadGap extends React.PureComponent {
static propTypes = {
disabled: PropTypes.bool,
maxId: PropTypes.string,
onClick: PropTypes.func.isRequired,
};
handleClick = () => {
this.props.onClick(this.props.maxId);
}
render () {
return ;
}
}
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', 'hasMore']),
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,
};
handleLoadGap = (maxId) => {
this.props.dispatch(expandNotifications({ maxId }));
};
handleLoadOlder = debounce(() => {
const last = this.props.notifications.last();
this.props.dispatch(expandNotifications({ maxId: last && last.get('id') }));
}, 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 !== null && item.get('id') === id) - 1;
this._selectChild(elementIndex);
}
handleMoveDown = id => {
const elementIndex = this.props.notifications.findIndex(item => item !== null && 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 = ;
let scrollableContent = null;
if (isLoading && this.scrollableContent) {
scrollableContent = this.scrollableContent;
} else if (notifications.size > 0 || hasMore) {
scrollableContent = notifications.map((item, index) => item === null ? (
0 ? notifications.getIn([index - 1, 'id']) : null}
onClick={this.handleLoadGap}
/>
) : (
));
} else {
scrollableContent = null;
}
this.scrollableContent = scrollableContent;
const scrollContainer = (
{scrollableContent}
);
return (
{scrollContainer}
);
}
}