diff options
author | Thibaut Girka <thib@sitedethib.com> | 2018-05-27 19:30:52 +0200 |
---|---|---|
committer | ThibG <thib@sitedethib.com> | 2018-05-29 21:25:28 +0200 |
commit | 4eba8c50c31d70f466a68d48445f86d644e4a889 (patch) | |
tree | e9f7f44ef62c4f0c1f8d4de38ca43f4337e8f6ca /app/javascript/flavours/glitch/features/notifications | |
parent | 0ad3eedd4cf6d1d7f7ceacc2c4412dbd8ee79cef (diff) |
[Glitch] Allow clients to fetch notifications made while they were offline
Port cbf97c03bba35a642e6f1d1a698aad7a69ad13a3 to glitch-soc
Diffstat (limited to 'app/javascript/flavours/glitch/features/notifications')
-rw-r--r-- | app/javascript/flavours/glitch/features/notifications/index.js | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index c27d3ffc9..f1319af45 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -17,6 +17,7 @@ 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' }, @@ -25,14 +26,32 @@ const messages = defineMessages({ 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')))); +], (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 <LoadMore onClick={this.handleClick} disabled={this.props.disabled} />; + } + +} 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']), + hasMore: state.getIn(['notifications', 'hasMore']), notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), }); @@ -67,9 +86,13 @@ export default class Notifications extends React.PureComponent { trackScroll: true, }; - handleLoadMore = debounce(() => { - this.props.dispatch(scrollTopNotifications(false)); - this.props.dispatch(expandNotifications()); + 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(() => { @@ -104,12 +127,12 @@ export default class Notifications extends React.PureComponent { } handleMoveUp = id => { - const elementIndex = this.props.notifications.findIndex(item => item.get('id') === id) - 1; + 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.get('id') === id) + 1; + const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1; this._selectChild(elementIndex); } @@ -131,7 +154,14 @@ export default class Notifications extends React.PureComponent { if (isLoading && this.scrollableContent) { scrollableContent = this.scrollableContent; } else if (notifications.size > 0 || hasMore) { - scrollableContent = notifications.map((item) => ( + scrollableContent = notifications.map((item, index) => item === null ? ( + <LoadGap + key={'gap:' + notifications.getIn([index + 1, 'id'])} + disabled={isLoading} + maxId={index > 0 ? notifications.getIn([index - 1, 'id']) : null} + onClick={this.handleLoadGap} + /> + ) : ( <NotificationContainer key={item.get('id')} notification={item} @@ -153,7 +183,7 @@ export default class Notifications extends React.PureComponent { isLoading={isLoading} hasMore={hasMore} emptyMessage={emptyMessage} - onLoadMore={this.handleLoadMore} + onLoadMore={this.handleLoadOlder} onScrollToTop={this.handleScrollToTop} onScroll={this.handleScroll} shouldUpdateScroll={shouldUpdateScroll} |