diff --git a/app/gabsocial/components/more_follows.js b/app/gabsocial/components/more_follows.js
new file mode 100644
index 000000000..86bc4ee45
--- /dev/null
+++ b/app/gabsocial/components/more_follows.js
@@ -0,0 +1,93 @@
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
+import PropTypes from 'prop-types';
+
+export default class MoreFollows extends React.PureComponent {
+
+ static propTypes = {
+ visible: PropTypes.bool,
+ moreFollows: PropTypes.number,
+ isFollowing: PropTypes.bool,
+ }
+
+ static defaultProps = {
+ visible: true,
+ }
+
+ render() {
+ const { moreFollows, isFollowing, visible } = this.props;
+
+ if (isFollowing === true && moreFollows === 1) {
+ return (
+
+
+
+ {moreFollows},
+ }}
+ />
+
+
+
+ );
+ } else if (isFollowing && moreFollows > 1) {
+ return (
+
+
+
+ {moreFollows},
+ }}
+ />
+
+
+
+ );
+ } else if (!isFollowing && moreFollows === 1) {
+ return (
+
+
+
+ {moreFollows},
+ }}
+ />
+
+
+
+ );
+ } else if (!isFollowing && moreFollows > 1) {
+ return (
+
+
+
+ {moreFollows},
+ }}
+ />
+
+
+
+ );
+ } else {
+ return (null);
+ }
+ }
+
+}
diff --git a/app/gabsocial/components/scrollable_list.js b/app/gabsocial/components/scrollable_list.js
index d9445c44f..ae796f16e 100644
--- a/app/gabsocial/components/scrollable_list.js
+++ b/app/gabsocial/components/scrollable_list.js
@@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import IntersectionObserverArticleContainer from '../containers/intersection_observer_article_container';
import LoadMore from './load_more';
+import MoreFollows from './more_follows';
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper';
import { throttle } from 'lodash';
import { List as ImmutableList } from 'immutable';
@@ -21,16 +22,18 @@ export default class ScrollableList extends PureComponent {
isLoading: PropTypes.bool,
showLoading: PropTypes.bool,
hasMore: PropTypes.bool,
+ hasMoreFollows: PropTypes.number,
prepend: PropTypes.node,
alwaysPrepend: PropTypes.bool,
emptyMessage: PropTypes.node,
children: PropTypes.node,
onScrollToTop: PropTypes.func,
onScroll: PropTypes.func,
+ isFollowing: PropTypes.bool,
};
state = {
- cachedMediaWidth: 250, // Default media/card width using default Gab Social theme
+ cachedMediaWidth: 250, // Default media/card width using default theme
};
intersectionObserverWrapper = new IntersectionObserverWrapper();
@@ -205,12 +208,13 @@ export default class ScrollableList extends PureComponent {
}
render() {
- const { children, scrollKey, showLoading, isLoading, hasMore, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
+ const { children, scrollKey, showLoading, isLoading, hasMore, hasMoreFollows, isFollowing, prepend, alwaysPrepend, emptyMessage, onLoadMore } = this.props;
const childrenCount = React.Children.count(children);
const trackScroll = true; //placeholder
const loadMore = (hasMore && onLoadMore) ? : null;
+ const moreFollows = (hasMoreFollows !== undefined && isFollowing !== undefined) ? : null;
let scrollableArea = null;
if (showLoading) {
@@ -248,7 +252,7 @@ export default class ScrollableList extends PureComponent {
})}
))}
-
+ {moreFollows}
{loadMore}
diff --git a/app/gabsocial/features/followers/index.js b/app/gabsocial/features/followers/index.js
index 93a57cf4d..7fe3106c4 100644
--- a/app/gabsocial/features/followers/index.js
+++ b/app/gabsocial/features/followers/index.js
@@ -16,6 +16,7 @@ import AccountContainer from '../../containers/account_container';
import Column from '../ui/components/column';
import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'gabsocial/components/missing_indicator';
+import { getHasMoreFollowsCount } from 'gabsocial/utils/accounts';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
@@ -30,6 +31,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
accountId = account ? account.getIn(['id'], null) : -1;
}
+ const hasMoreFollows = getHasMoreFollowsCount(state, accountId, false);
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
@@ -41,6 +43,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
isAccount: !!state.getIn(['accounts', accountId]),
accountIds: state.getIn(['user_lists', 'followers', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'followers', accountId, 'next']),
+ hasMoreFollows,
};
};
@@ -52,6 +55,7 @@ class Followers extends ImmutablePureComponent {
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
+ hasMoreFollows: PropTypes.number,
isAccount: PropTypes.bool,
unavailable: PropTypes.bool,
};
@@ -81,7 +85,8 @@ class Followers extends ImmutablePureComponent {
}, 300, { leading: true });
render() {
- const { accountIds, hasMore, isAccount, accountId, unavailable } = this.props;
+ const { accountIds, hasMore, hasMoreFollows, isAccount, accountId, unavailable } = this.props;
+ const isFollowing = false;
if (!isAccount && accountId !== -1) {
return (
@@ -114,6 +119,8 @@ class Followers extends ImmutablePureComponent {
}
>
diff --git a/app/gabsocial/features/following/index.js b/app/gabsocial/features/following/index.js
index 40befdd91..2952d7995 100644
--- a/app/gabsocial/features/following/index.js
+++ b/app/gabsocial/features/following/index.js
@@ -16,6 +16,7 @@ import AccountContainer from '../../containers/account_container';
import Column from '../ui/components/column';
import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'gabsocial/components/missing_indicator';
+import { getHasMoreFollowsCount } from 'gabsocial/utils/accounts';
const mapStateToProps = (state, { params: { username }, withReplies = false }) => {
const me = state.get('me');
@@ -30,6 +31,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
accountId = account ? account.getIn(['id'], null) : -1;
}
+ const hasMoreFollows = getHasMoreFollowsCount(state, accountId, true);
const isBlocked = state.getIn(['relationships', accountId, 'blocked_by'], false);
const isLocked = state.getIn(['accounts', accountId, 'locked'], false);
const isFollowing = state.getIn(['relationships', accountId, 'following'], false);
@@ -41,6 +43,7 @@ const mapStateToProps = (state, { params: { username }, withReplies = false }) =
isAccount: !!state.getIn(['accounts', accountId]),
accountIds: state.getIn(['user_lists', 'following', accountId, 'items']),
hasMore: !!state.getIn(['user_lists', 'following', accountId, 'next']),
+ hasMoreFollows,
};
};
@@ -54,6 +57,7 @@ class Following extends ImmutablePureComponent {
hasMore: PropTypes.bool,
isAccount: PropTypes.bool,
unavailable: PropTypes.bool,
+ hasMoreFollows: PropTypes.number,
};
componentWillMount() {
@@ -81,7 +85,8 @@ class Following extends ImmutablePureComponent {
}, 300, { leading: true });
render() {
- const { accountIds, hasMore, isAccount, accountId, unavailable } = this.props;
+ const { accountIds, hasMore, isAccount, hasMoreFollows, accountId, unavailable } = this.props;
+ const isFollowing = true;
if (!isAccount && accountId !== -1) {
return (
@@ -114,6 +119,8 @@ class Following extends ImmutablePureComponent {
}
>
diff --git a/app/gabsocial/utils/accounts.js b/app/gabsocial/utils/accounts.js
index adc029981..2558d4357 100644
--- a/app/gabsocial/utils/accounts.js
+++ b/app/gabsocial/utils/accounts.js
@@ -1,4 +1,5 @@
import { Map as ImmutableMap } from 'immutable';
+import { List as ImmutableList } from 'immutable';
export const getDomain = account => {
let re = /https?:\/\/(.*?)\//i;
@@ -28,3 +29,18 @@ export const isAdmin = account => (
export const isModerator = account => (
account.getIn(['pleroma', 'is_moderator']) === true
);
+
+export const getHasMoreFollowsCount = (state, accountId, isFollowing) => {
+ let moreFollowsCount = undefined; //variable text in defaultMessage with null value preventing rendering
+ let emptyList = ImmutableList();
+ if (isFollowing) {
+ let followingList = ImmutableList();
+ followingList = state.getIn(['user_lists', 'following', accountId, 'items'], emptyList);
+ moreFollowsCount = parseInt(state.getIn(['accounts_counters', accountId, 'following_count']), 0) - followingList.size;
+ } else {
+ let followersList = ImmutableList();
+ followersList = state.getIn(['user_lists', 'followers', accountId, 'items'], emptyList);
+ moreFollowsCount = parseInt(state.getIn(['accounts_counters', accountId, 'followers_count']), 0) - followersList.size;
+ }
+ return moreFollowsCount;
+};
diff --git a/app/styles/gabsocial/components.scss b/app/styles/gabsocial/components.scss
index 0d67b566f..28f9fb638 100644
--- a/app/styles/gabsocial/components.scss
+++ b/app/styles/gabsocial/components.scss
@@ -2339,6 +2339,34 @@ a.status-card.compact:hover {
}
}
+.morefollows-indicator {
+ text-align: center;
+ font-size: 16px;
+ font-weight: 500;
+ color: $dark-text-color;
+ background: $ui-base-color;
+ cursor: default;
+ display: flex;
+ flex: 1 1 auto;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+
+ & > div {
+ width: 100%;
+ background: transparent;
+ padding-top: 0;
+ }
+
+ &__label {
+ strong {
+ display: block;
+ margin-bottom: 10px;
+ color: $dark-text-color;
+ }
+ }
+}
+
.columns-area--mobile .column {@include gab-container-standards();}
.column-header__wrapper {
position: relative;