Skip to content
This repository has been archived by the owner on Oct 1, 2019. It is now read-only.

Commit

Permalink
Implement 'Load more' button for list of users on /+talk
Browse files Browse the repository at this point in the history
  • Loading branch information
voidxnull committed Jun 9, 2017
1 parent 6d28a43 commit dfed40c
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/actions/user-messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,12 @@ export function updateUserMessagesStatus(status) {
};
}

export function loadMessageableUsers(users) {
export function loadMessageableUsers(users, meta = { offset: 0 }) {
return {
type: LOAD_MESSAGEABLE_USERS,
payload: {
users
}
},
meta
};
}
4 changes: 2 additions & 2 deletions src/api/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ export default class ApiClient {
return await response.json();
}

async mutualFollows(userId: UserId): Promise<Array<User>> {
const response = await this.get(`/api/v1/user/${userId}/mutual-follows`);
async mutualFollows(userId: UserId, query: Object = {}): Promise<Array<User>> {
const response = await this.get(`/api/v1/user/${userId}/mutual-follows`, query);
return await response.json();
}

Expand Down
2 changes: 2 additions & 0 deletions src/api/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1923,6 +1923,8 @@ export default class ApiController {
});

this.applySortQuery(qb, ctx.query, 'username');
this.applyLimitQuery(qb, ctx.query);
this.applyOffsetQuery(qb, ctx.query);
})
.fetch({
withRelated: USER_RELATIONS
Expand Down
8 changes: 6 additions & 2 deletions src/components/conversations/user-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
import React from 'react';
import { Link } from 'react-router';
import Avatar from '../user/avatar';
import { getName } from '../../utils/user';


export default function UserList({ onClick, selectedUserId, users, user_messages }) {
export default function UserList({ canLoadMore, selectedUserId, users, user_messages, onClick, onLoadMore }) {
const followedUsers = user_messages.get('messageableUserIds').map(id => users.get(id));

const userItems = followedUsers.map((user, index) => {
Expand All @@ -40,7 +41,7 @@ export default function UserList({ onClick, selectedUserId, users, user_messages
>
<Link className={className} href="javascript:;" onClick={handleClick}>
<Avatar className="aux-nav__icon--left" isRound={false} size={23} user={user} />
{user.get('username')}
{getName(user)}
{numUnread > 0 &&
<div className="aux-nav__count">{numUnread}</div>
}
Expand All @@ -52,6 +53,9 @@ export default function UserList({ onClick, selectedUserId, users, user_messages
return (
<div className="aux-nav">
{userItems}
{canLoadMore &&
<button className="aux-nav__button" onClick={onLoadMore}>Load more</button>
}
</div>
);
}
13 changes: 13 additions & 0 deletions src/less/blocks/aux-nav.less
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
@active-icon: #6AB7EA;
@active-text: #1078B4;

display: flex;
flex-direction: column;
margin-bottom: @doubleSpace;

&__item {
Expand Down Expand Up @@ -64,4 +66,15 @@
font-size: 12px;
margin-left: auto;
}

// TODO: I'm not sure if this should be here.
&__button {
margin: @space auto;
padding: 8px 50px;
border: none;
outline: none;
background-color: white;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1);
color: #1078B4;
}
}
11 changes: 10 additions & 1 deletion src/pages/conversations.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import RiverItemCreateForm from '../components/river/type/text/create-form';
import User from '../components/user';


const USER_LIMIT = 5;

class ConversationsPage extends React.Component {
static async fetchData(router, store, client) {
const state = store.getState();
Expand All @@ -55,7 +57,7 @@ class ConversationsPage extends React.Component {
}

const triggers = new ActionsTrigger(client, store.dispatch);
const users = await triggers.loadMessageableUsers(currentUserId);
const users = await triggers.loadMessageableUsers(currentUserId, { offset: 0, limit: USER_LIMIT });

if (users.length > 0) {
const firstUserId = users[0].id;
Expand Down Expand Up @@ -118,6 +120,11 @@ class ConversationsPage extends React.Component {
this.triggers.deleteUserMessage(message.get('receiver_id'), message.get('id'));
};

handleLoadMoreUsers = async () => {
const offset = this.props.user_messages.get('messageableUserIds').size;
await this.triggers.loadMessageableUsers(this.props.current_user.get('id'), { offset, limit: USER_LIMIT });
}

setMessagesInterval = (selectedUserId) => {
clearInterval(this.messageIntervalId);

Expand Down Expand Up @@ -185,10 +192,12 @@ class ConversationsPage extends React.Component {
</PageContent>
<SidebarAlt>
<UserList
canLoadMore={user_messages.get('canLoadMore')}
selectedUserId={this.state.selectedUserId}
user_messages={user_messages}
users={users}
onClick={this.handleSelectUser}
onLoadMore={this.handleLoadMoreUsers}
/>
</SidebarAlt>
</PageBody>
Expand Down
16 changes: 14 additions & 2 deletions src/store/user_messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { userMessages } from '../actions';
export const initialState = i.fromJS({
numUnread: 0,
byUser: {}, // userId => { numUnread: 0, messages: [] },
messageableUserIds: [] // for optimization
messageableUserIds: [], // for optimization
canLoadMore: true,
});

export function reducer(state = initialState, action) {
Expand Down Expand Up @@ -85,7 +86,18 @@ export function reducer(state = initialState, action) {

state = state.withMutations(state => {
state.update('byUser', byUser => byUser.mergeDeep(i.fromJS(usersById)));
state.set('messageableUserIds', i.List(userIds));

if (action.meta.offset > 0) {
state.update('messageableUserIds', ids => {
return ids.slice(0, action.meta.offset).push(...userIds);
});
} else {
state.set('messageableUserIds', i.List(userIds));
}

if (userIds.length < action.meta.limit) {
state.set('canLoadMore', false);
}
});

break;
Expand Down
7 changes: 3 additions & 4 deletions src/triggers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,13 +893,12 @@ export class ActionsTrigger {
}
}

// TODO: Load more
loadMessageableUsers = async (currentUserId) => {
loadMessageableUsers = async (currentUserId, params = {}) => {
let users;

try {
users = await this.client.mutualFollows(currentUserId);
this.dispatch(a.userMessages.loadMessageableUsers(users));
users = await this.client.mutualFollows(currentUserId, params);
this.dispatch(a.userMessages.loadMessageableUsers(users, params));
} catch (e) {
this.dispatch(a.messages.addError(e.message));
}
Expand Down

0 comments on commit dfed40c

Please sign in to comment.