about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-02-22 16:30:09 +0100
committerEugen Rochko <eugen@zeonfederated.com>2017-02-22 16:30:09 +0100
commitc96fd24f48c388116b6a1b42cc0be693aa428d0f (patch)
treeb5764c8b79f159d301b00851168183458af70729 /app
parentc77a54fe0aadceb9b1e74097dbdb272a4eb62fd5 (diff)
Improve status reselect, do not display "load more" when no next link available
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/components/components/status_list.jsx5
-rw-r--r--app/assets/javascripts/components/containers/status_container.jsx49
-rw-r--r--app/assets/javascripts/components/features/account_timeline/index.jsx5
-rw-r--r--app/assets/javascripts/components/features/ui/containers/status_list_container.jsx3
-rw-r--r--app/assets/javascripts/components/selectors/index.jsx53
5 files changed, 39 insertions, 76 deletions
diff --git a/app/assets/javascripts/components/components/status_list.jsx b/app/assets/javascripts/components/components/status_list.jsx
index 6c71a31e8..345944e4d 100644
--- a/app/assets/javascripts/components/components/status_list.jsx
+++ b/app/assets/javascripts/components/components/status_list.jsx
@@ -15,6 +15,7 @@ const StatusList = React.createClass({
     trackScroll: React.PropTypes.bool,
     isLoading: React.PropTypes.bool,
     isUnread: React.PropTypes.bool,
+    hasMore: React.PropTypes.bool,
     prepend: React.PropTypes.node,
     emptyMessage: React.PropTypes.node
   },
@@ -73,13 +74,13 @@ const StatusList = React.createClass({
   },
 
   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 scrollableArea = '';
     let unread         = '';
 
-    if (!isLoading && statusIds.size > 0) {
+    if (!isLoading && statusIds.size > 0 && hasMore) {
       loadMore = <LoadMore onClick={this.handleLoadMore} />;
     }
 
diff --git a/app/assets/javascripts/components/containers/status_container.jsx b/app/assets/javascripts/components/containers/status_container.jsx
index fc096a375..81265bc50 100644
--- a/app/assets/javascripts/components/containers/status_container.jsx
+++ b/app/assets/javascripts/components/containers/status_container.jsx
@@ -18,45 +18,12 @@ import { openMedia } from '../actions/modal';
 import { createSelector } from 'reselect'
 import { isMobile } from '../is_mobile'
 
-const mapStateToProps = (state, props) => ({
-  statusBase: state.getIn(['statuses', props.id]),
-  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 makeMapStateToProps = () => {
+  const getStatus = makeGetStatus();
 
-  const mapStateToProps = (state, { status }) => ({
-    status: getStatus(state, status)
+  const mapStateToProps = (state, props) => ({
+    status: getStatus(state, props.id),
+    me: state.getIn(['meta', 'me'])
   });
 
   return mapStateToProps;
@@ -106,8 +73,4 @@ const mapDispatchToProps = (dispatch) => ({
 
 });
 
-export default connect(mapStateToProps, mapDispatchToProps)(
-  connect(makeMapStateToPropsInner)(
-    connect(makeMapStateToPropsLast)(Status)
-  )
-);
+export default connect(makeMapStateToProps, mapDispatchToProps)(Status);
diff --git a/app/assets/javascripts/components/features/account_timeline/index.jsx b/app/assets/javascripts/components/features/account_timeline/index.jsx
index 349510295..f92e1b49c 100644
--- a/app/assets/javascripts/components/features/account_timeline/index.jsx
+++ b/app/assets/javascripts/components/features/account_timeline/index.jsx
@@ -16,6 +16,7 @@ import Immutable from 'immutable';
 const mapStateToProps = (state, props) => ({
   statusIds: state.getIn(['timelines', 'accounts_timelines', Number(props.params.accountId), 'items'], Immutable.List()),
   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'])
 });
 
@@ -26,6 +27,7 @@ const AccountTimeline = React.createClass({
     dispatch: React.PropTypes.func.isRequired,
     statusIds: ImmutablePropTypes.list,
     isLoading: React.PropTypes.bool,
+    hasMore: React.PropTypes.bool,
     me: React.PropTypes.number.isRequired
   },
 
@@ -48,7 +50,7 @@ const AccountTimeline = React.createClass({
   },
 
   render () {
-    const { statusIds, isLoading, me } = this.props;
+    const { statusIds, isLoading, hasMore, me } = this.props;
 
     if (!statusIds && isLoading) {
       return (
@@ -66,6 +68,7 @@ const AccountTimeline = React.createClass({
           prepend={<HeaderContainer accountId={this.props.params.accountId} />}
           statusIds={statusIds}
           isLoading={isLoading}
+          hasMore={hasMore}
           me={me}
           onScrollToBottom={this.handleScrollToBottom}
         />
diff --git a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
index bb6df1133..f249240d8 100644
--- a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
+++ b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
@@ -40,7 +40,8 @@ const makeMapStateToProps = () => {
   const mapStateToProps = (state, props) => ({
     statusIds: getStatusIds(state, props),
     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;
diff --git a/app/assets/javascripts/components/selectors/index.jsx b/app/assets/javascripts/components/selectors/index.jsx
index 20debe604..faa7f92d0 100644
--- a/app/assets/javascripts/components/selectors/index.jsx
+++ b/app/assets/javascripts/components/selectors/index.jsx
@@ -17,37 +17,32 @@ export const makeGetAccount = () => {
   });
 };
 
-const getStatusBase = (state, id) => state.getIn(['statuses', id], null);
-
 export const makeGetStatus = () => {
-  return createSelector([getStatusBase, getStatuses, getAccounts], (base, statuses, accounts) => {
-    if (base === null) {
-      return null;
+  return createSelector(
+    [
+      (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;
+      }
+
+      if (statusReblog) {
+        statusReblog = statusReblog.set('account', accountReblog);
+      } else {
+        statusReblog = null;
+      }
+
+      return statusBase.withMutations(map => {
+        map.set('reblog', statusReblog);
+        map.set('account', accountBase);
+      });
     }
-
-    return assembleStatus(base.get('id'), statuses, accounts);
-  });
-};
-
-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 {
-      return null;
-    }
-  }
-
-  return status.set('reblog', reblog).set('account', accounts.get(status.get('account')));
+  );
 };
 
 const getAlertsBase = state => state.get('alerts');