Improve status reselect, do not display "load more" when no next link available
This commit is contained in:
parent
c77a54fe0a
commit
c96fd24f48
|
@ -15,6 +15,7 @@ const StatusList = React.createClass({
|
||||||
trackScroll: React.PropTypes.bool,
|
trackScroll: React.PropTypes.bool,
|
||||||
isLoading: React.PropTypes.bool,
|
isLoading: React.PropTypes.bool,
|
||||||
isUnread: React.PropTypes.bool,
|
isUnread: React.PropTypes.bool,
|
||||||
|
hasMore: React.PropTypes.bool,
|
||||||
prepend: React.PropTypes.node,
|
prepend: React.PropTypes.node,
|
||||||
emptyMessage: React.PropTypes.node
|
emptyMessage: React.PropTypes.node
|
||||||
},
|
},
|
||||||
|
@ -73,13 +74,13 @@ const StatusList = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, onScrollToBottom, trackScroll, isLoading, isUnread, prepend, emptyMessage } = this.props;
|
const { statusIds, onScrollToBottom, trackScroll, isLoading, isUnread, hasMore, prepend, emptyMessage } = this.props;
|
||||||
|
|
||||||
let loadMore = '';
|
let loadMore = '';
|
||||||
let scrollableArea = '';
|
let scrollableArea = '';
|
||||||
let unread = '';
|
let unread = '';
|
||||||
|
|
||||||
if (!isLoading && statusIds.size > 0) {
|
if (!isLoading && statusIds.size > 0 && hasMore) {
|
||||||
loadMore = <LoadMore onClick={this.handleLoadMore} />;
|
loadMore = <LoadMore onClick={this.handleLoadMore} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,47 +18,14 @@ import { openMedia } from '../actions/modal';
|
||||||
import { createSelector } from 'reselect'
|
import { createSelector } from 'reselect'
|
||||||
import { isMobile } from '../is_mobile'
|
import { isMobile } from '../is_mobile'
|
||||||
|
|
||||||
|
const makeMapStateToProps = () => {
|
||||||
|
const getStatus = makeGetStatus();
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
statusBase: state.getIn(['statuses', props.id]),
|
status: getStatus(state, props.id),
|
||||||
me: state.getIn(['meta', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeMapStateToPropsInner = () => {
|
|
||||||
const getStatus = (() => {
|
|
||||||
return createSelector(
|
|
||||||
[
|
|
||||||
(_, base) => base,
|
|
||||||
(state, base) => (base ? state.getIn(['accounts', base.get('account')]) : null),
|
|
||||||
(state, base) => (base ? state.getIn(['statuses', base.get('reblog')], null) : null)
|
|
||||||
],
|
|
||||||
|
|
||||||
(base, account, reblog) => (base ? base.set('account', account).set('reblog', reblog) : null)
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
|
|
||||||
const mapStateToProps = (state, { statusBase }) => ({
|
|
||||||
status: getStatus(state, statusBase)
|
|
||||||
});
|
|
||||||
|
|
||||||
return mapStateToProps;
|
|
||||||
};
|
|
||||||
|
|
||||||
const makeMapStateToPropsLast = () => {
|
|
||||||
const getStatus = (() => {
|
|
||||||
return createSelector(
|
|
||||||
[
|
|
||||||
(_, status) => status,
|
|
||||||
(state, status) => (status ? state.getIn(['accounts', status.getIn(['reblog', 'account'])], null) : null)
|
|
||||||
],
|
|
||||||
|
|
||||||
(status, reblogAccount) => (status && status.get('reblog') ? status.setIn(['reblog', 'account'], reblogAccount) : status)
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
|
|
||||||
const mapStateToProps = (state, { status }) => ({
|
|
||||||
status: getStatus(state, status)
|
|
||||||
});
|
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,8 +73,4 @@ const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(
|
export default connect(makeMapStateToProps, mapDispatchToProps)(Status);
|
||||||
connect(makeMapStateToPropsInner)(
|
|
||||||
connect(makeMapStateToPropsLast)(Status)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import Immutable from 'immutable';
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'items'], Immutable.List()),
|
statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'items'], Immutable.List()),
|
||||||
isLoading: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'isLoading']),
|
isLoading: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'isLoading']),
|
||||||
|
hasMore: !!state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'next']),
|
||||||
me: state.getIn(['meta', 'me'])
|
me: state.getIn(['meta', 'me'])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ const AccountTimeline = React.createClass({
|
||||||
dispatch: React.PropTypes.func.isRequired,
|
dispatch: React.PropTypes.func.isRequired,
|
||||||
statusIds: ImmutablePropTypes.list,
|
statusIds: ImmutablePropTypes.list,
|
||||||
isLoading: React.PropTypes.bool,
|
isLoading: React.PropTypes.bool,
|
||||||
|
hasMore: React.PropTypes.bool,
|
||||||
me: React.PropTypes.number.isRequired
|
me: React.PropTypes.number.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ const AccountTimeline = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, isLoading, me } = this.props;
|
const { statusIds, isLoading, hasMore, me } = this.props;
|
||||||
|
|
||||||
if (!statusIds && isLoading) {
|
if (!statusIds && isLoading) {
|
||||||
return (
|
return (
|
||||||
|
@ -66,6 +68,7 @@ const AccountTimeline = React.createClass({
|
||||||
prepend={<HeaderContainer accountId={this.props.params.accountId} />}
|
prepend={<HeaderContainer accountId={this.props.params.accountId} />}
|
||||||
statusIds={statusIds}
|
statusIds={statusIds}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
hasMore={hasMore}
|
||||||
me={me}
|
me={me}
|
||||||
onScrollToBottom={this.handleScrollToBottom}
|
onScrollToBottom={this.handleScrollToBottom}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -40,7 +40,8 @@ const makeMapStateToProps = () => {
|
||||||
const mapStateToProps = (state, props) => ({
|
const mapStateToProps = (state, props) => ({
|
||||||
statusIds: getStatusIds(state, props),
|
statusIds: getStatusIds(state, props),
|
||||||
isLoading: state.getIn(['timelines', props.type, 'isLoading'], true),
|
isLoading: state.getIn(['timelines', props.type, 'isLoading'], true),
|
||||||
isUnread: state.getIn(['timelines', props.type, 'unread']) > 0
|
isUnread: state.getIn(['timelines', props.type, 'unread']) > 0,
|
||||||
|
hasMore: !!state.getIn(['timelines', props.type, 'next'])
|
||||||
});
|
});
|
||||||
|
|
||||||
return mapStateToProps;
|
return mapStateToProps;
|
||||||
|
|
|
@ -17,37 +17,32 @@ export const makeGetAccount = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStatusBase = (state, id) => state.getIn(['statuses', id], null);
|
|
||||||
|
|
||||||
export const makeGetStatus = () => {
|
export const makeGetStatus = () => {
|
||||||
return createSelector([getStatusBase, getStatuses, getAccounts], (base, statuses, accounts) => {
|
return createSelector(
|
||||||
if (base === null) {
|
[
|
||||||
|
(state, id) => state.getIn(['statuses', id]),
|
||||||
|
(state, id) => state.getIn(['statuses', state.getIn(['statuses', id, 'reblog'])]),
|
||||||
|
(state, id) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]),
|
||||||
|
(state, id) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]),
|
||||||
|
],
|
||||||
|
|
||||||
|
(statusBase, statusReblog, accountBase, accountReblog) => {
|
||||||
|
if (!statusBase) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return assembleStatus(base.get('id'), statuses, accounts);
|
if (statusReblog) {
|
||||||
});
|
statusReblog = statusReblog.set('account', accountReblog);
|
||||||
};
|
|
||||||
|
|
||||||
const assembleStatus = (id, statuses, accounts) => {
|
|
||||||
let status = statuses.get(id, null);
|
|
||||||
let reblog = null;
|
|
||||||
|
|
||||||
if (status === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.get('reblog', null) !== null) {
|
|
||||||
reblog = statuses.get(status.get('reblog'), null);
|
|
||||||
|
|
||||||
if (reblog !== null) {
|
|
||||||
reblog = reblog.set('account', accounts.get(reblog.get('account')));
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
statusReblog = null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status.set('reblog', reblog).set('account', accounts.get(status.get('account')));
|
return statusBase.withMutations(map => {
|
||||||
|
map.set('reblog', statusReblog);
|
||||||
|
map.set('account', accountBase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAlertsBase = state => state.get('alerts');
|
const getAlertsBase = state => state.get('alerts');
|
||||||
|
|
Loading…
Reference in New Issue