PLT-5566 Added clientside handling to automatically show direct channels (#270)
* Added TestServerUrl config setting * Added clientside handling to show direct channels in the sidebar when a DM is received
This commit is contained in:
parent
9ecf23ceb5
commit
1115d882ca
8 changed files with 107 additions and 39 deletions
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"DefaultServerUrl": "http://localhost:8065",
|
||||
"TestServerUrl": "http://localhost:8065",
|
||||
"DefaultLocale": "en",
|
||||
"DefaultTheme": "default"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import Client from 'service/client';
|
||||
|
||||
import {PreferencesTypes} from 'service/constants';
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
|
||||
import {batchActions} from 'redux-batched-actions';
|
||||
|
||||
import Client from 'service/client';
|
||||
import {Preferences, PreferencesTypes} from 'service/constants';
|
||||
import {getMyPreferences as getMyPreferencesSelector} from 'service/selectors/entities/preferences';
|
||||
import {getCurrentUserId} from 'service/selectors/entities/users';
|
||||
import {getPreferenceKey} from 'service/utils/preference_utils';
|
||||
|
||||
import {bindClientFunc, forceLogoutIfNecessary} from './helpers';
|
||||
|
||||
export function getMyPreferences() {
|
||||
return bindClientFunc(
|
||||
Client.getMyPreferences,
|
||||
|
|
@ -65,8 +68,23 @@ export function deletePreferences(preferences) {
|
|||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
getMyPreferences,
|
||||
savePreferences,
|
||||
deletePreferences
|
||||
};
|
||||
export function makeDirectChannelVisibleIfNecessary(otherUserId) {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const myPreferences = getMyPreferencesSelector(state);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
|
||||
let preference = myPreferences[getPreferenceKey(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, otherUserId)];
|
||||
|
||||
if (!preference || preference.value === 'false') {
|
||||
preference = {
|
||||
user_id: currentUserId,
|
||||
category: Preferences.CATEGORY_DIRECT_CHANNEL_SHOW,
|
||||
name: otherUserId,
|
||||
value: 'true'
|
||||
};
|
||||
|
||||
await savePreferences([preference])(dispatch, getState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import {getProfilesByIds, getStatusesByIds} from 'service/actions/users';
|
||||
import Client from 'service/client';
|
||||
import EventEmitter from 'service/utils/event_emitter';
|
||||
import websocketClient from 'service/client/websocket_client';
|
||||
import {
|
||||
fetchMyChannelsAndMembers,
|
||||
getChannel,
|
||||
getChannelStats,
|
||||
updateChannelHeader,
|
||||
updateChannelPurpose,
|
||||
markChannelAsUnread,
|
||||
markChannelAsRead
|
||||
} from 'service/actions/channels';
|
||||
import {
|
||||
getPosts,
|
||||
getPostsSince
|
||||
} from 'service/actions/posts';
|
||||
import {makeDirectChannelVisibleIfNecessary} from 'service/actions/preferences';
|
||||
import {
|
||||
Constants,
|
||||
ChannelTypes,
|
||||
|
|
@ -14,23 +28,8 @@ import {
|
|||
UsersTypes,
|
||||
WebsocketEvents
|
||||
} from 'service/constants';
|
||||
|
||||
import {
|
||||
fetchMyChannelsAndMembers,
|
||||
getChannel,
|
||||
getChannelStats,
|
||||
updateChannelHeader,
|
||||
updateChannelPurpose,
|
||||
markChannelAsUnread,
|
||||
markChannelAsRead
|
||||
} from 'service/actions/channels';
|
||||
|
||||
import {
|
||||
getPosts,
|
||||
getPostsSince
|
||||
} from 'service/actions/posts';
|
||||
|
||||
import {getProfilesByIds, getStatusesByIds} from 'service/actions/users';
|
||||
import {getUserIdFromChannelName} from 'service/utils/channel_utils';
|
||||
import EventEmitter from 'service/utils/event_emitter';
|
||||
|
||||
export function init(siteUrl, token, optionalWebSocket) {
|
||||
return async (dispatch, getState) => {
|
||||
|
|
@ -167,6 +166,12 @@ async function handleNewPostEvent(msg, dispatch, getState) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (msg.data.channel_type === Constants.DM_CHANNEL) {
|
||||
const otherUserId = getUserIdFromChannelName(users.currentId, msg.data.channel_name);
|
||||
|
||||
makeDirectChannelVisibleIfNecessary(otherUserId)(dispatch, getState);
|
||||
}
|
||||
|
||||
if (post.root_id && !posts[post.root_id]) {
|
||||
await Client.getPost(teamId, post.channel_id, post.root_id).then((data) => {
|
||||
const rootUserId = data.posts[post.root_id].user_id;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import Config from 'assets/config.json';
|
|||
import Themes from 'assets/themes.json';
|
||||
|
||||
import {Preferences} from 'service/constants';
|
||||
import {getPreferenceKey} from 'service/utils/preference_utils';
|
||||
|
||||
import {getCurrentTeamId} from './teams';
|
||||
|
||||
|
|
@ -21,11 +22,11 @@ export const getTheme = createSelector(
|
|||
// Prefer the user's current team-specific theme over the user's current global theme over the default theme
|
||||
let themePreference;
|
||||
if (currentTeamId) {
|
||||
themePreference = myPreferences[`${Preferences.CATEGORY_THEME}--${currentTeamId}`];
|
||||
themePreference = myPreferences[getPreferenceKey(Preferences.CATEGORY_THEME, currentTeamId)];
|
||||
}
|
||||
|
||||
if (!themePreference) {
|
||||
themePreference = myPreferences[`${Preferences.CATEGORY_THEME}--`];
|
||||
themePreference = myPreferences[getPreferenceKey(Preferences.CATEGORY_THEME, '')];
|
||||
}
|
||||
|
||||
let theme;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ function isDirectChannel(channel) {
|
|||
}
|
||||
|
||||
export function isDirectChannelVisible(userId, myPreferences, channel) {
|
||||
const channelId = getUserIdFromChannelName(userId, channel);
|
||||
const channelId = getUserIdFromChannelName(userId, channel.name);
|
||||
const dm = myPreferences[`${Constants.CATEGORY_DIRECT_CHANNEL_SHOW}--${channelId}`];
|
||||
return dm && dm.value === 'true';
|
||||
}
|
||||
|
|
@ -114,11 +114,11 @@ function createMissingDirectChannels(currentUserId, allChannels, myPreferences)
|
|||
}
|
||||
|
||||
function isDirectChannelForUser(userId, otherUserId, channel) {
|
||||
return channel.type === Constants.DM_CHANNEL && getUserIdFromChannelName(userId, channel) === otherUserId;
|
||||
return channel.type === Constants.DM_CHANNEL && getUserIdFromChannelName(userId, channel.name) === otherUserId;
|
||||
}
|
||||
|
||||
export function getUserIdFromChannelName(userId, channel) {
|
||||
const ids = channel.name.split('__');
|
||||
export function getUserIdFromChannelName(userId, channelName) {
|
||||
const ids = channelName.split('__');
|
||||
let otherUserId = '';
|
||||
if (ids[0] === userId) {
|
||||
otherUserId = ids[1];
|
||||
|
|
@ -149,7 +149,7 @@ export function completeDirectChannelInfo(usersState, myPreferences, channel) {
|
|||
}
|
||||
|
||||
const dmChannelClone = {...channel};
|
||||
const teammateId = getUserIdFromChannelName(usersState.currentId, channel);
|
||||
const teammateId = getUserIdFromChannelName(usersState.currentId, channel.name);
|
||||
|
||||
return Object.assign(dmChannelClone, {
|
||||
display_name: displayUsername(usersState.profiles[teammateId], myPreferences),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
export function getPreferenceKey(category, name) {
|
||||
return `${category}--${name}`;
|
||||
}
|
||||
|
||||
export function getPreferencesByCategory(myPreferences, category) {
|
||||
const prefix = `${category}--`;
|
||||
const preferences = new Map();
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@
|
|||
|
||||
import assert from 'assert';
|
||||
|
||||
import * as Actions from 'service/actions/preferences';
|
||||
import Client from 'service/client';
|
||||
import configureStore from 'app/store';
|
||||
import {RequestStatus} from 'service/constants';
|
||||
|
||||
import * as Actions from 'service/actions/preferences';
|
||||
import {login} from 'service/actions/users';
|
||||
import Client from 'service/client';
|
||||
import {Preferences, RequestStatus} from 'service/constants';
|
||||
|
||||
import TestHelper from 'test/test_helper';
|
||||
|
||||
describe('Actions.Preferences', () => {
|
||||
|
|
@ -147,4 +150,40 @@ describe('Actions.Preferences', () => {
|
|||
assert.deepEqual(existingPreferences[1], myPreferences['test--test2']);
|
||||
assert.ok(!myPreferences['test--test3'], 'third preference doesn\'t exist');
|
||||
});
|
||||
|
||||
it('makeDirectChannelVisibleIfNecessary', async () => {
|
||||
const user = TestHelper.basicUser;
|
||||
const user2 = await TestHelper.createClient().createUser(TestHelper.fakeUser());
|
||||
|
||||
await login(user.email, 'password1')(store.dispatch, store.getState);
|
||||
|
||||
// Test that a new preference is created if non exists
|
||||
await Actions.makeDirectChannelVisibleIfNecessary(user2.id)(store.dispatch, store.getState);
|
||||
|
||||
let state = store.getState();
|
||||
let myPreferences = state.entities.preferences.myPreferences;
|
||||
let preference = myPreferences[`${Preferences.CATEGORY_DIRECT_CHANNEL_SHOW}--${user2.id}`];
|
||||
assert.ok(preference, 'preference for showing direct channel doesn\'t exist');
|
||||
assert.equal(preference.value, 'true', 'preference for showing direct channel is not true');
|
||||
|
||||
// Test that nothing changes if the preference already exists and is true
|
||||
await Actions.makeDirectChannelVisibleIfNecessary(user2.id)(store.dispatch, store.getState);
|
||||
|
||||
const state2 = store.getState();
|
||||
assert.equal(state, state2, 'store should not change since direct channel is already visible');
|
||||
|
||||
// Test that the preference is updated if it already exists and is false
|
||||
await Actions.savePreferences([{
|
||||
...preference,
|
||||
value: 'false'
|
||||
}])(store.dispatch, store.getState);
|
||||
|
||||
await Actions.makeDirectChannelVisibleIfNecessary(user2.id)(store.dispatch, store.getState);
|
||||
|
||||
state = store.getState();
|
||||
myPreferences = state.entities.preferences.myPreferences;
|
||||
preference = myPreferences[`${Preferences.CATEGORY_DIRECT_CHANNEL_SHOW}--${user2.id}`];
|
||||
assert.ok(preference, 'preference for showing direct channel doesn\'t exist');
|
||||
assert.equal(preference.value, 'true', 'preference for showing direct channel is not true');
|
||||
}).timeout(2000);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class TestHelper {
|
|||
};
|
||||
|
||||
initBasic = async (client = this.createClient()) => {
|
||||
client.setUrl(Config.DefaultServerUrl);
|
||||
client.setUrl(Config.TestServerUrl || Config.DefaultServerUrl);
|
||||
this.basicClient = client;
|
||||
|
||||
this.basicUser = await client.createUser(this.fakeUser());
|
||||
|
|
|
|||
Loading…
Reference in a new issue