mattermost-mobile/service/actions/channels.js
enahum 81526fbb09 Channel drawer (#154)
* Channel list drawer
* Get channels by category
* Fix and connect websocket
* Fix Select first team using the team members

* create loadMe and fix login actions to loads the teams

* Add android back button handler for the channel drawer

* Channel drawer styling and functionality

* Mark channel as viewed and fixed reset unread counts

* Unread above/below indicators

* Improve performance replacing ScrollView with ListView

* Fix unread indicators

* Addressing review feedback
2017-01-03 19:49:28 -03:00

557 lines
16 KiB
JavaScript

// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {
Constants,
ChannelTypes,
Preferences,
PreferencesTypes,
UsersTypes
} from 'service/constants';
import {forceLogoutIfNecessary} from './helpers';
import {batchActions} from 'redux-batched-actions';
import Client from 'service/client';
export function selectChannel(channelId) {
return async (dispatch, getState) => {
dispatch({
type: ChannelTypes.SELECT_CHANNEL,
data: channelId
}, getState);
};
}
export function createChannel(channel, userId) {
return async (dispatch, getState) => {
dispatch(batchActions([
{
type: ChannelTypes.CREATE_CHANNEL_REQUEST
},
{
type: ChannelTypes.CHANNEL_MEMBERS_REQUEST
}
]), getState);
let created;
try {
created = await Client.createChannel(channel);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch(batchActions([
{
type: ChannelTypes.CREATE_CHANNEL_FAILURE,
error
},
{
type: ChannelTypes.CHANNEL_MEMBERS_FAILURE,
error
}
]), getState);
return;
}
const member = {
channel_id: created.id,
user_id: userId,
roles: `${Constants.CHANNEL_USER_ROLE} ${Constants.CHANNEL_ADMIN_ROLE}`,
last_viewed_at: 0,
msg_count: 0,
mention_count: 0,
notify_props: {desktop: 'default', mark_unread: 'all'},
last_update_at: created.create_at
};
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL,
data: created
},
{
type: ChannelTypes.CREATE_CHANNEL_SUCCESS
},
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBER,
data: member
},
{
type: ChannelTypes.CHANNEL_MEMBERS_SUCCESS
}
]), getState);
};
}
export function createDirectChannel(teamId, userId, otherUserId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.CREATE_CHANNEL_REQUEST}, getState);
let created;
try {
created = await Client.createDirectChannel(teamId, otherUserId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch(batchActions([
{
type: ChannelTypes.CREATE_CHANNEL_FAILURE,
error
},
{
type: ChannelTypes.CHANNEL_MEMBERS_FAILURE,
error
}
]), getState);
return;
}
const member = {
channel_id: created.id,
user_id: userId,
roles: `${Constants.CHANNEL_USER_ROLE} ${Constants.CHANNEL_ADMIN_ROLE}`,
last_viewed_at: 0,
msg_count: 0,
mention_count: 0,
notify_props: {desktop: 'default', mark_unread: 'all'},
last_update_at: created.create_at
};
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL,
data: created
},
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBER,
data: member
},
{
type: PreferencesTypes.RECEIVED_PREFERENCES,
data: [{category: Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, name: otherUserId, value: 'true'}]
},
{
type: ChannelTypes.CREATE_CHANNEL_SUCCESS
}
]), getState);
};
}
export function updateChannel(channel) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.UPDATE_CHANNEL_REQUEST}, getState);
let updated;
try {
updated = await Client.updateChannel(channel);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.UPDATE_CHANNEL_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL,
data: updated
},
{
type: ChannelTypes.UPDATE_CHANNEL_SUCCESS
}
]), getState);
};
}
export function updateChannelNotifyProps(userId, teamId, channelId, props) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.NOTIFY_PROPS_REQUEST}, getState);
const data = {
user_id: userId,
channel_id: channelId,
...props
};
let notifyProps;
try {
notifyProps = await Client.updateChannelNotifyProps(teamId, data);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.NOTIFY_PROPS_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL_PROPS,
data: {
channel_id: channelId,
notifyProps
}
},
{
type: ChannelTypes.NOTIFY_PROPS_SUCCESS
}
]), getState);
};
}
export function getChannel(teamId, channelId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.CHANNEL_REQUEST}, getState);
let data;
try {
data = await Client.getChannel(teamId, channelId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.CHANNELS_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL,
data: data.channel
},
{
type: ChannelTypes.CHANNEL_SUCCESS
},
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBER,
data: data.member
}
]), getState);
};
}
export function fetchMyChannelsAndMembers(teamId) {
return async (dispatch, getState) => {
dispatch(batchActions([
{
type: ChannelTypes.CHANNELS_REQUEST
},
{
type: ChannelTypes.CHANNEL_MEMBERS_REQUEST
}
]), getState);
let channels;
let channelMembers;
try {
const channelsRequest = Client.getChannels(teamId);
const channelMembersRequest = Client.getMyChannelMembers(teamId);
channels = await channelsRequest;
channelMembers = await channelMembersRequest;
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch(batchActions([
{
type: ChannelTypes.CHANNELS_FAILURE,
error
},
{
type: ChannelTypes.CHANNEL_MEMBERS_FAILURE,
error
}
]), getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNELS,
data: channels
},
{
type: ChannelTypes.CHANNELS_SUCCESS
},
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
data: channelMembers
},
{
type: ChannelTypes.CHANNEL_MEMBERS_SUCCESS
}
]), getState);
};
}
export function getMyChannelMembers(teamId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.CHANNEL_MEMBERS_REQUEST}, getState);
let channelMembers;
try {
const channelMembersRequest = Client.getMyChannelMembers(teamId);
channelMembers = await channelMembersRequest;
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.CHANNEL_MEMBERS_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
data: channelMembers
},
{
type: ChannelTypes.CHANNEL_MEMBERS_SUCCESS
}
]), getState);
};
}
export function leaveChannel(teamId, channelId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.LEAVE_CHANNEL_REQUEST}, getState);
try {
await Client.leaveChannel(teamId, channelId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.LEAVE_CHANNEL_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.LEAVE_CHANNEL,
data: channelId
},
{
type: ChannelTypes.LEAVE_CHANNEL_SUCCESS
}
]), getState);
};
}
export function joinChannel(userId, teamId, channelId, channelName) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.JOIN_CHANNEL_REQUEST}, getState);
let channel;
try {
if (channelId) {
channel = await Client.joinChannel(teamId, channelId);
} else if (channelName) {
channel = await Client.joinChannelByName(teamId, channelName);
}
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.JOIN_CHANNEL_FAILURE, error}, getState);
return;
}
const channelMember = {
channel_id: channel.id,
user_id: userId,
roles: `${Constants.CHANNEL_USER_ROLE}`,
last_viewed_at: 0,
msg_count: 0,
mention_count: 0,
notify_props: {desktop: 'default', mark_unread: 'all'},
last_update_at: new Date().getTime()
};
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL,
data: channel
},
{
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBER,
data: channelMember
},
{
type: ChannelTypes.JOIN_CHANNEL_SUCCESS
}
]), getState);
};
}
export function deleteChannel(teamId, channelId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.DELETE_CHANNEL_REQUEST}, getState);
try {
await Client.deleteChannel(teamId, channelId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.DELETE_CHANNEL_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL_DELETED,
data: channelId
},
{
type: ChannelTypes.DELETE_CHANNEL_SUCCESS
}
]), getState);
};
}
export function viewChannel(teamId, channelId, prevChannelId = '') {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.UPDATE_LAST_VIEWED_REQUEST}, getState);
try {
// this API should return the timestamp that was set
await Client.viewChannel(teamId, channelId, prevChannelId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.UPDATE_LAST_VIEWED_FAILURE, error}, getState);
return;
}
const {channels} = getState().entities.channels;
const actions = [{
type: ChannelTypes.RECEIVED_LAST_VIEWED,
data: {
channel_id: channelId,
last_viewed_at: new Date().getTime(),
total_msg_count: channels[channelId].total_msg_count
}
}];
if (prevChannelId) {
actions.push({
type: ChannelTypes.RECEIVED_LAST_VIEWED,
data: {
channel_id: prevChannelId,
last_viewed_at: new Date().getTime(),
total_msg_count: channels[prevChannelId].total_msg_count
}
});
}
dispatch(batchActions([
...actions,
{
type: ChannelTypes.UPDATE_LAST_VIEWED_SUCCESS
}
]), getState);
};
}
export function getMoreChannels(teamId, offset, limit = Constants.CHANNELS_CHUNK_SIZE) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.MORE_CHANNELS_REQUEST}, getState);
let channels;
try {
channels = await Client.getMoreChannels(teamId, offset, limit);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.MORE_CHANNELS_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_MORE_CHANNELS,
data: await channels
},
{
type: ChannelTypes.MORE_CHANNELS_SUCCESS
}
]), getState);
};
}
export function getChannelStats(teamId, channelId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.CHANNEL_STATS_REQUEST}, getState);
let stat;
try {
stat = await Client.getChannelStats(teamId, channelId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.CHANNEL_STATS_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: ChannelTypes.RECEIVED_CHANNEL_STATS,
data: stat
},
{
type: ChannelTypes.CHANNEL_STATS_SUCCESS
}
]), getState);
};
}
export function addChannelMember(teamId, channelId, userId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.ADD_CHANNEL_MEMBER_REQUEST}, getState);
try {
await Client.addChannelMember(teamId, channelId, userId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.ADD_CHANNEL_MEMBER_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: UsersTypes.RECEIVED_PROFILE_IN_CHANNEL,
data: {user_id: userId},
id: channelId
},
{
type: ChannelTypes.ADD_CHANNEL_MEMBER_SUCCESS
}
]), getState);
};
}
export function removeChannelMember(teamId, channelId, userId) {
return async (dispatch, getState) => {
dispatch({type: ChannelTypes.REMOVE_CHANNEL_MEMBER_REQUEST}, getState);
try {
await Client.removeChannelMember(teamId, channelId, userId);
} catch (error) {
forceLogoutIfNecessary(error, dispatch);
dispatch({type: ChannelTypes.REMOVE_CHANNEL_MEMBER_FAILURE, error}, getState);
return;
}
dispatch(batchActions([
{
type: UsersTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
data: {user_id: userId},
id: channelId
},
{
type: ChannelTypes.REMOVE_CHANNEL_MEMBER_SUCCESS
}
]), getState);
};
}
export default {
selectChannel,
createChannel,
createDirectChannel,
updateChannel,
updateChannelNotifyProps,
getChannel,
fetchMyChannelsAndMembers,
getMyChannelMembers,
leaveChannel,
joinChannel,
deleteChannel,
viewChannel,
getMoreChannels,
getChannelStats,
addChannelMember,
removeChannelMember
};