Start moving webapp to Redux (#6140)
* Start moving webapp to Redux * Fix localforage import * Updates per feedback * Feedback udpates and a few fixes * Minor updates * Fix statuses, config not loading properly, getMe sanitizing too much * Fix preferences * Fix user autocomplete * Fix sessions and audits * Fix error handling for all redux actions * Use new directory structure for components and containers * Refresh immediately on logout instead of after timeout * Add fetch polyfill
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
cc07c00507
Коммит
6c4c706313
@@ -8,6 +8,10 @@ import EventEmitter from 'events';
|
||||
|
||||
const CHANGE_EVENT = 'change';
|
||||
|
||||
import store from 'stores/redux_store.jsx';
|
||||
import * as Selectors from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {PreferenceTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
class PreferenceStore extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
@@ -16,6 +20,23 @@ class PreferenceStore extends EventEmitter {
|
||||
this.dispatchToken = AppDispatcher.register(this.handleEventPayload);
|
||||
|
||||
this.preferences = new Map();
|
||||
this.entities = Selectors.getMyPreferences(store.getState());
|
||||
Object.keys(this.entities).forEach((key) => {
|
||||
this.preferences.set(key, this.entities[key].value);
|
||||
});
|
||||
|
||||
store.subscribe(() => {
|
||||
const newEntities = Selectors.getMyPreferences(store.getState());
|
||||
if (this.entities !== newEntities) {
|
||||
this.preferences = new Map();
|
||||
Object.keys(newEntities).forEach((key) => {
|
||||
this.preferences.set(key, newEntities[key].value);
|
||||
});
|
||||
this.emitChange();
|
||||
}
|
||||
|
||||
this.entities = newEntities;
|
||||
});
|
||||
|
||||
this.setMaxListeners(600);
|
||||
}
|
||||
@@ -79,21 +100,24 @@ class PreferenceStore extends EventEmitter {
|
||||
}
|
||||
|
||||
setPreference(category, name, value) {
|
||||
this.preferences.set(this.getKey(category, name), value);
|
||||
store.dispatch({
|
||||
type: PreferenceTypes.RECEIVED_PREFERENCES,
|
||||
data: [{category, name, value}]
|
||||
});
|
||||
}
|
||||
|
||||
setPreferencesFromServer(newPreferences) {
|
||||
for (const preference of newPreferences) {
|
||||
this.setPreference(preference.category, preference.name, preference.value);
|
||||
}
|
||||
store.dispatch({
|
||||
type: PreferenceTypes.RECEIVED_PREFERENCES,
|
||||
data: newPreferences
|
||||
});
|
||||
}
|
||||
|
||||
deletePreference(preference) {
|
||||
this.preferences.delete(this.getKey(preference.category, preference.name));
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.preferences.clear();
|
||||
store.dispatch({
|
||||
type: PreferenceTypes.DELETED_PREFERENCES,
|
||||
data: [preference]
|
||||
});
|
||||
}
|
||||
|
||||
emitChange(category) {
|
||||
|
||||
19
webapp/stores/redux_store.jsx
Обычный файл
19
webapp/stores/redux_store.jsx
Обычный файл
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
// This is a temporary store while we are transitioning from Flux to Redux. This file exports
|
||||
// the configured Redux store for use by actions and selectors.
|
||||
|
||||
import configureStore from 'store';
|
||||
const store = configureStore();
|
||||
|
||||
export function bindActionToRedux(action, ...args) {
|
||||
return async () => {
|
||||
await action(...args)(store.dispatch, store.getState);
|
||||
};
|
||||
}
|
||||
|
||||
window.store = store;
|
||||
|
||||
export default store;
|
||||
|
||||
@@ -17,17 +17,33 @@ const CHANGE_EVENT = 'change';
|
||||
const STATS_EVENT = 'stats';
|
||||
const UNREAD_EVENT = 'unread';
|
||||
|
||||
import store from 'stores/redux_store.jsx';
|
||||
import * as Selectors from 'mattermost-redux/selectors/entities/teams';
|
||||
import {TeamTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
var Utils;
|
||||
|
||||
class TeamStoreClass extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.clear();
|
||||
|
||||
store.subscribe(() => {
|
||||
const newEntities = store.getState().entities.teams;
|
||||
|
||||
if (newEntities.teams !== this.entities.teams) {
|
||||
this.emitChange();
|
||||
}
|
||||
if (newEntities.myMembers !== this.entities.myMembers) {
|
||||
this.emitChange();
|
||||
}
|
||||
|
||||
this.entities = newEntities;
|
||||
});
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.teams = {};
|
||||
this.my_team_members = [];
|
||||
this.entities = {};
|
||||
this.members_in_team = {};
|
||||
this.members_not_in_team = {};
|
||||
this.stats = {};
|
||||
@@ -91,7 +107,7 @@ class TeamStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return this.teams;
|
||||
return store.getState().entities.teams.teams;
|
||||
}
|
||||
|
||||
getCurrentId() {
|
||||
@@ -100,10 +116,14 @@ class TeamStoreClass extends EventEmitter {
|
||||
|
||||
setCurrentId(id) {
|
||||
this.currentTeamId = id;
|
||||
store.dispatch({
|
||||
type: TeamTypes.SELECT_TEAM,
|
||||
data: id
|
||||
});
|
||||
}
|
||||
|
||||
getCurrent() {
|
||||
const team = this.teams[this.currentTeamId];
|
||||
const team = this.getAll()[this.currentTeamId];
|
||||
|
||||
if (team) {
|
||||
return team;
|
||||
@@ -165,17 +185,21 @@ class TeamStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
saveTeam(team) {
|
||||
this.teams[team.id] = team;
|
||||
this.saveTeams([team]);
|
||||
}
|
||||
|
||||
saveTeams(teams) {
|
||||
this.teams = teams;
|
||||
store.dispatch({
|
||||
type: TeamTypes.RECEIVED_TEAMS_LIST,
|
||||
data: teams
|
||||
});
|
||||
}
|
||||
|
||||
updateTeam(team) {
|
||||
const t = JSON.parse(team);
|
||||
if (this.teams && this.teams[t.id]) {
|
||||
this.teams[t.id] = t;
|
||||
const teams = this.getAll();
|
||||
if (teams && teams[t.id]) {
|
||||
this.saveTeam(t);
|
||||
}
|
||||
|
||||
if (this.teamListings && this.teamListings[t.id]) {
|
||||
@@ -193,7 +217,7 @@ class TeamStoreClass extends EventEmitter {
|
||||
|
||||
saveMyTeam(team) {
|
||||
this.saveTeam(team);
|
||||
this.currentTeamId = team.id;
|
||||
this.setCurrentId(team.id);
|
||||
}
|
||||
|
||||
saveStats(teamId, stats) {
|
||||
@@ -201,20 +225,26 @@ class TeamStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
saveMyTeamMembers(members) {
|
||||
this.my_team_members = members;
|
||||
store.dispatch({
|
||||
type: TeamTypes.RECEIVED_MY_TEAM_MEMBERS,
|
||||
data: members
|
||||
});
|
||||
}
|
||||
|
||||
appendMyTeamMember(member) {
|
||||
this.my_team_members.push(member);
|
||||
const members = this.getMyTeamMembers();
|
||||
members.push(member);
|
||||
this.saveMyTeamMembers(members);
|
||||
}
|
||||
|
||||
saveMyTeamMembersUnread(members) {
|
||||
for (let i = 0; i < this.my_team_members.length; i++) {
|
||||
const team = this.my_team_members[i];
|
||||
const myMembers = this.getMyTeamMembers();
|
||||
for (let i = 0; i < myMembers.length; i++) {
|
||||
const team = myMembers[i];
|
||||
const member = members.filter((m) => m.team_id === team.team_id)[0];
|
||||
|
||||
if (member) {
|
||||
this.my_team_members[i] = Object.assign({},
|
||||
myMembers[i] = Object.assign({},
|
||||
team,
|
||||
{
|
||||
msg_count: member.msg_count,
|
||||
@@ -222,19 +252,23 @@ class TeamStoreClass extends EventEmitter {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.saveMyTeamMembers(myMembers);
|
||||
}
|
||||
|
||||
removeMyTeamMember(teamId) {
|
||||
for (let i = 0; i < this.my_team_members.length; i++) {
|
||||
if (this.my_team_members[i].team_id === teamId) {
|
||||
this.my_team_members.splice(i, 1);
|
||||
const myMembers = this.getMyTeamMembers();
|
||||
for (let i = 0; i < myMembers.length; i++) {
|
||||
if (myMembers[i].team_id === teamId) {
|
||||
myMembers.splice(i, 1);
|
||||
}
|
||||
}
|
||||
this.emitChange();
|
||||
|
||||
this.saveMyTeamMembers(myMembers);
|
||||
}
|
||||
|
||||
getMyTeamMembers() {
|
||||
return this.my_team_members;
|
||||
return Object.values(Selectors.getTeamMemberships(store.getState()));
|
||||
}
|
||||
|
||||
saveMembersInTeam(teamId = this.getCurrentId(), members) {
|
||||
@@ -320,19 +354,21 @@ class TeamStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
updateUnreadCount(teamId, totalMsgCount, channelMember) {
|
||||
const member = this.my_team_members.filter((m) => m.team_id === teamId)[0];
|
||||
let member = this.getMyTeamMembers().filter((m) => m.team_id === teamId)[0];
|
||||
if (member) {
|
||||
member = Object.assign({}, member);
|
||||
member.msg_count -= (totalMsgCount - channelMember.msg_count);
|
||||
member.mention_count -= channelMember.mention_count;
|
||||
}
|
||||
}
|
||||
|
||||
subtractUnread(teamId, msgs, mentions) {
|
||||
const member = this.my_team_members.filter((m) => m.team_id === teamId)[0];
|
||||
let member = this.getMyTeamMembers().filter((m) => m.team_id === teamId)[0];
|
||||
if (member) {
|
||||
const msgCount = member.msg_count - msgs;
|
||||
const mentionCount = member.mention_count - mentions;
|
||||
|
||||
member = Object.assign({}, member);
|
||||
member.msg_count = (msgCount > 0) ? msgCount : 0;
|
||||
member.mention_count = (mentionCount > 0) ? mentionCount : 0;
|
||||
}
|
||||
@@ -344,7 +380,7 @@ class TeamStoreClass extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
const member = this.my_team_members.filter((m) => m.team_id === id)[0];
|
||||
const member = Object.assign({}, this.getMyTeamMembers().filter((m) => m.team_id === id)[0]);
|
||||
member.msg_count++;
|
||||
}
|
||||
|
||||
@@ -355,7 +391,7 @@ class TeamStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
if (mentions.indexOf(UserStore.getCurrentId()) !== -1) {
|
||||
const member = this.my_team_members.filter((m) => m.team_id === id)[0];
|
||||
const member = Object.assign({}, this.getMyTeamMembers().filter((m) => m.team_id === id)[0]);
|
||||
member.mention_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
|
||||
import EventEmitter from 'events';
|
||||
|
||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||
import LocalizationStore from './localization_store.jsx';
|
||||
import ChannelStore from 'stores/channel_store.jsx';
|
||||
import TeamStore from 'stores/team_store.jsx';
|
||||
|
||||
import Constants from 'utils/constants.jsx';
|
||||
const ActionTypes = Constants.ActionTypes;
|
||||
const UserStatuses = Constants.UserStatuses;
|
||||
|
||||
const CHANGE_EVENT_NOT_IN_CHANNEL = 'change_not_in_channel';
|
||||
@@ -23,48 +19,52 @@ const CHANGE_EVENT_SESSIONS = 'change_sessions';
|
||||
const CHANGE_EVENT_AUDITS = 'change_audits';
|
||||
const CHANGE_EVENT_STATUSES = 'change_statuses';
|
||||
|
||||
import store from 'stores/redux_store.jsx';
|
||||
import * as Selectors from 'mattermost-redux/selectors/entities/users';
|
||||
import {UserTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
var Utils;
|
||||
|
||||
class UserStoreClass extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.clear();
|
||||
}
|
||||
|
||||
clear() {
|
||||
// All the profiles, regardless of where they came from
|
||||
this.profiles = {};
|
||||
this.paging_offset = 0;
|
||||
this.paging_count = 0;
|
||||
|
||||
// Lists of sorted IDs for users in a team
|
||||
this.profiles_not_in_team = {};
|
||||
this.not_in_team_offset = 0;
|
||||
this.not_in_team_count = 0;
|
||||
|
||||
// Lists of sorted IDs for users in a team
|
||||
this.profiles_in_team = {};
|
||||
this.in_team_offset = 0;
|
||||
this.in_team_count = 0;
|
||||
|
||||
// Lists of sorted IDs for users in a channel
|
||||
this.profiles_in_channel = {};
|
||||
this.in_channel_offset = {};
|
||||
this.in_channel_count = {};
|
||||
|
||||
// Lists of sorted IDs for users not in a channel
|
||||
this.profiles_not_in_channel = {};
|
||||
this.not_in_channel_offset = {};
|
||||
this.not_in_channel_count = {};
|
||||
|
||||
// Lists of sorted IDs for users without a team
|
||||
this.profiles_without_team = {};
|
||||
|
||||
this.statuses = {};
|
||||
this.sessions = {};
|
||||
this.audits = [];
|
||||
this.currentUserId = '';
|
||||
this.noAccounts = false;
|
||||
this.entities = {};
|
||||
|
||||
store.subscribe(() => {
|
||||
const newEntities = store.getState().entities.users;
|
||||
|
||||
if (newEntities.profiles !== this.entities.profiles) {
|
||||
this.emitChange();
|
||||
}
|
||||
if (newEntities.profilesInChannel !== this.entities.profilesInChannel) {
|
||||
this.emitInChannelChange();
|
||||
}
|
||||
if (newEntities.profilesNotInChannel !== this.entities.profilesNotInChannel) {
|
||||
this.emitNotInChannelChange();
|
||||
}
|
||||
if (newEntities.profilesInTeam !== this.entities.profilesInTeam) {
|
||||
this.emitInTeamChange();
|
||||
}
|
||||
if (newEntities.profilesNotInTeam !== this.entities.profilesNotInTeam) {
|
||||
this.emitNotInTeamChange();
|
||||
}
|
||||
if (newEntities.profilesWithoutTeam !== this.entities.profilesWithoutTeam) {
|
||||
this.emitWithoutTeamChange();
|
||||
}
|
||||
if (newEntities.statuses !== this.entities.statuses) {
|
||||
this.emitStatusesChange();
|
||||
}
|
||||
if (newEntities.myAudits !== this.entities.myAudits) {
|
||||
this.emitAuditsChange();
|
||||
}
|
||||
if (newEntities.mySessions !== this.entities.mySessions) {
|
||||
this.emitSessionsChange();
|
||||
}
|
||||
|
||||
this.entities = newEntities;
|
||||
});
|
||||
}
|
||||
|
||||
emitChange(userId) {
|
||||
@@ -178,49 +178,21 @@ class UserStoreClass extends EventEmitter {
|
||||
// General
|
||||
|
||||
getCurrentUser() {
|
||||
return this.getProfiles()[this.currentUserId];
|
||||
}
|
||||
|
||||
setCurrentUser(user) {
|
||||
this.saveProfile(user);
|
||||
this.currentUserId = user.id;
|
||||
global.window.mm_current_user_id = this.currentUserId;
|
||||
if (LocalizationStore.getLocale() !== user.locale) {
|
||||
setTimeout(() => GlobalActions.newLocalizationSelected(user.locale), 0);
|
||||
}
|
||||
return Selectors.getCurrentUser(store.getState());
|
||||
}
|
||||
|
||||
getCurrentId() {
|
||||
var user = this.getCurrentUser();
|
||||
|
||||
if (user) {
|
||||
return user.id;
|
||||
}
|
||||
|
||||
return null;
|
||||
return Selectors.getCurrentUserId(store.getState());
|
||||
}
|
||||
|
||||
// System-Wide Profiles
|
||||
|
||||
saveProfiles(profiles) {
|
||||
const newProfiles = Object.assign({}, profiles);
|
||||
const currentId = this.getCurrentId();
|
||||
if (newProfiles[currentId]) {
|
||||
Reflect.deleteProperty(newProfiles, currentId);
|
||||
}
|
||||
this.profiles = Object.assign({}, this.profiles, newProfiles);
|
||||
}
|
||||
|
||||
getProfiles() {
|
||||
return this.profiles;
|
||||
return Selectors.getUsers(store.getState());
|
||||
}
|
||||
|
||||
getProfile(userId) {
|
||||
if (this.profiles[userId]) {
|
||||
return Object.assign({}, this.profiles[userId]);
|
||||
}
|
||||
|
||||
return null;
|
||||
return Selectors.getUser(store.getState(), userId);
|
||||
}
|
||||
|
||||
getProfileListForIds(userIds, skipCurrent = false, skipInactive = false) {
|
||||
@@ -257,17 +229,7 @@ class UserStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
getProfilesUsernameMap() {
|
||||
var profileUsernameMap = {};
|
||||
|
||||
var profiles = this.getProfiles();
|
||||
for (var key in profiles) {
|
||||
if (profiles.hasOwnProperty(key)) {
|
||||
var profile = profiles[key];
|
||||
profileUsernameMap[profile.username] = profile;
|
||||
}
|
||||
}
|
||||
|
||||
return profileUsernameMap;
|
||||
return Selectors.getUsersByUsername(store.getState());
|
||||
}
|
||||
|
||||
getActiveOnlyProfiles(skipCurrent) {
|
||||
@@ -310,10 +272,11 @@ class UserStoreClass extends EventEmitter {
|
||||
getProfileList(skipCurrent = false, allowInactive = false) {
|
||||
const profiles = [];
|
||||
const currentId = this.getCurrentId();
|
||||
const profileMap = this.getProfiles();
|
||||
|
||||
for (const id in this.profiles) {
|
||||
if (this.profiles.hasOwnProperty(id)) {
|
||||
var profile = this.profiles[id];
|
||||
for (const id in profileMap) {
|
||||
if (profileMap.hasOwnProperty(id)) {
|
||||
var profile = profileMap[id];
|
||||
|
||||
if (skipCurrent && id === currentId) {
|
||||
continue;
|
||||
@@ -339,103 +302,32 @@ class UserStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
saveProfile(profile) {
|
||||
this.profiles[profile.id] = profile;
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE,
|
||||
data: profile
|
||||
});
|
||||
}
|
||||
|
||||
// Team-Wide Profiles
|
||||
|
||||
saveProfilesInTeam(teamId, profiles) {
|
||||
const oldProfileList = this.profiles_in_team[teamId] || [];
|
||||
const oldProfileMap = {};
|
||||
for (let i = 0; i < oldProfileList.length; i++) {
|
||||
oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]);
|
||||
}
|
||||
|
||||
const newProfileMap = Object.assign({}, oldProfileMap, profiles);
|
||||
const newProfileList = Object.keys(newProfileMap);
|
||||
|
||||
newProfileList.sort((a, b) => {
|
||||
const aProfile = newProfileMap[a];
|
||||
const bProfile = newProfileMap[b];
|
||||
|
||||
if (aProfile.username < bProfile.username) {
|
||||
return -1;
|
||||
}
|
||||
if (aProfile.username > bProfile.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
this.profiles_in_team[teamId] = newProfileList;
|
||||
this.saveProfiles(profiles);
|
||||
}
|
||||
|
||||
getProfileListInTeam(teamId = TeamStore.getCurrentId(), skipCurrent = false, skipInactive = false) {
|
||||
const userIds = this.profiles_in_team[teamId] || [];
|
||||
const userIds = Array.from(Selectors.getUserIdsInTeams(store.getState())[teamId] || []);
|
||||
|
||||
return this.getProfileListForIds(userIds, skipCurrent, skipInactive);
|
||||
}
|
||||
|
||||
removeProfileFromTeam(teamId, userId) {
|
||||
const userIds = this.profiles_in_team[teamId];
|
||||
if (!userIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = userIds.indexOf(userId);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
userIds.splice(index, 1);
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_NOT_IN_TEAM,
|
||||
data: {user_id: userId},
|
||||
id: teamId
|
||||
});
|
||||
}
|
||||
|
||||
// Not In Team Profiles
|
||||
|
||||
saveProfilesNotInTeam(teamId, profiles) {
|
||||
const oldProfileList = this.profiles_not_in_team[teamId] || [];
|
||||
const oldProfileMap = {};
|
||||
for (let i = 0; i < oldProfileList.length; i++) {
|
||||
oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]);
|
||||
}
|
||||
|
||||
const newProfileMap = Object.assign({}, oldProfileMap, profiles);
|
||||
const newProfileList = Object.keys(newProfileMap);
|
||||
|
||||
newProfileList.sort((a, b) => {
|
||||
const aProfile = newProfileMap[a];
|
||||
const bProfile = newProfileMap[b];
|
||||
|
||||
if (aProfile.username < bProfile.username) {
|
||||
return -1;
|
||||
}
|
||||
if (aProfile.username > bProfile.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
this.profiles_not_in_team[teamId] = newProfileList;
|
||||
this.saveProfiles(profiles);
|
||||
}
|
||||
|
||||
removeProfileNotInTeam(teamId, userId) {
|
||||
const userIds = this.profiles_not_in_team[teamId];
|
||||
if (!userIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = userIds.indexOf(userId);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
userIds.splice(index, 1);
|
||||
}
|
||||
|
||||
getProfileListNotInTeam(teamId = TeamStore.getCurrentId(), skipCurrent = false, skipInactive = false) {
|
||||
const userIds = this.profiles_not_in_team[teamId] || [];
|
||||
const userIds = Array.from(Selectors.getUserIdsNotInTeams(store.getState())[teamId] || []);
|
||||
const profiles = [];
|
||||
const currentId = this.getCurrentId();
|
||||
|
||||
@@ -460,178 +352,84 @@ class UserStoreClass extends EventEmitter {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
// Channel-Wide Profiles
|
||||
|
||||
saveProfilesInChannel(channelId = ChannelStore.getCurrentId(), profiles) {
|
||||
const oldProfileList = this.profiles_in_channel[channelId] || [];
|
||||
const oldProfileMap = {};
|
||||
for (let i = 0; i < oldProfileList.length; i++) {
|
||||
oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]);
|
||||
}
|
||||
|
||||
const newProfileMap = Object.assign({}, oldProfileMap, profiles);
|
||||
const newProfileList = Object.keys(newProfileMap);
|
||||
|
||||
newProfileList.sort((a, b) => {
|
||||
const aProfile = newProfileMap[a];
|
||||
const bProfile = newProfileMap[b];
|
||||
|
||||
if (aProfile.username < bProfile.username) {
|
||||
return -1;
|
||||
}
|
||||
if (aProfile.username > bProfile.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
removeProfileNotInTeam(teamId, userId) {
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_IN_TEAM,
|
||||
data: {user_id: userId},
|
||||
id: teamId
|
||||
});
|
||||
|
||||
this.profiles_in_channel[channelId] = newProfileList;
|
||||
this.saveProfiles(profiles);
|
||||
}
|
||||
|
||||
// Channel-Wide Profiles
|
||||
|
||||
saveProfileInChannel(channelId = ChannelStore.getCurrentId(), profile) {
|
||||
const profileMap = {};
|
||||
profileMap[profile.id] = profile;
|
||||
this.saveProfilesInChannel(channelId, profileMap);
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
||||
data: {user_id: profile.id},
|
||||
id: channelId
|
||||
});
|
||||
}
|
||||
|
||||
saveUserIdInChannel(channelId = ChannelStore.getCurrentId(), userId) {
|
||||
const profile = this.getProfile(userId);
|
||||
|
||||
// Must have profile or we can't sort the list
|
||||
if (!profile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.saveProfileInChannel(channelId, profile);
|
||||
|
||||
return true;
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
||||
data: {user_id: userId},
|
||||
id: channelId
|
||||
});
|
||||
}
|
||||
|
||||
removeProfileInChannel(channelId, userId) {
|
||||
const userIds = this.profiles_in_channel[channelId];
|
||||
if (!userIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = userIds.indexOf(userId);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
userIds.splice(index, 1);
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
|
||||
data: {user_id: userId},
|
||||
id: channelId
|
||||
});
|
||||
}
|
||||
|
||||
getProfileListInChannel(channelId = ChannelStore.getCurrentId(), skipCurrent = false) {
|
||||
const userIds = this.profiles_in_channel[channelId] || [];
|
||||
const userIds = Array.from(Selectors.getUserIdsInChannels(store.getState())[channelId] || []);
|
||||
|
||||
return this.getProfileListForIds(userIds, skipCurrent, false);
|
||||
}
|
||||
|
||||
saveProfilesNotInChannel(channelId = ChannelStore.getCurrentId(), profiles) {
|
||||
const oldProfileList = this.profiles_not_in_channel[channelId] || [];
|
||||
const oldProfileMap = {};
|
||||
for (let i = 0; i < oldProfileList.length; i++) {
|
||||
oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]);
|
||||
}
|
||||
|
||||
const newProfileMap = Object.assign({}, oldProfileMap, profiles);
|
||||
const newProfileList = Object.keys(newProfileMap);
|
||||
|
||||
newProfileList.sort((a, b) => {
|
||||
const aProfile = newProfileMap[a];
|
||||
const bProfile = newProfileMap[b];
|
||||
|
||||
if (aProfile.username < bProfile.username) {
|
||||
return -1;
|
||||
}
|
||||
if (aProfile.username > bProfile.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
this.profiles_not_in_channel[channelId] = newProfileList;
|
||||
this.saveProfiles(profiles);
|
||||
}
|
||||
|
||||
saveProfileNotInChannel(channelId = ChannelStore.getCurrentId(), profile) {
|
||||
const profileMap = {};
|
||||
profileMap[profile.id] = profile;
|
||||
this.saveProfilesNotInChannel(channelId, profileMap);
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
|
||||
data: {user_id: profile.id},
|
||||
id: channelId
|
||||
});
|
||||
}
|
||||
|
||||
removeProfileNotInChannel(channelId, userId) {
|
||||
const userIds = this.profiles_not_in_channel[channelId];
|
||||
if (!userIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = userIds.indexOf(userId);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
userIds.splice(index, 1);
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
||||
data: {user_id: userId},
|
||||
id: channelId
|
||||
});
|
||||
}
|
||||
|
||||
getProfileListNotInChannel(channelId = ChannelStore.getCurrentId(), skipInactive = false) {
|
||||
const userIds = this.profiles_not_in_channel[channelId] || [];
|
||||
const userIds = Array.from(Selectors.getUserIdsNotInChannels(store.getState())[channelId] || []);
|
||||
|
||||
return this.getProfileListForIds(userIds, false, skipInactive);
|
||||
}
|
||||
|
||||
// Profiles without any teams
|
||||
|
||||
saveProfilesWithoutTeam(profiles) {
|
||||
const oldProfileList = this.profiles_without_team;
|
||||
const oldProfileMap = {};
|
||||
for (let i = 0; i < oldProfileList.length; i++) {
|
||||
oldProfileMap[oldProfileList[i]] = this.getProfile(oldProfileList[i]);
|
||||
}
|
||||
|
||||
const newProfileMap = Object.assign({}, oldProfileMap, profiles);
|
||||
const newProfileList = Object.keys(newProfileMap);
|
||||
|
||||
newProfileList.sort((a, b) => {
|
||||
const aProfile = newProfileMap[a];
|
||||
const bProfile = newProfileMap[b];
|
||||
|
||||
if (aProfile.username < bProfile.username) {
|
||||
return -1;
|
||||
}
|
||||
if (aProfile.username > bProfile.username) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
this.profiles_without_team = newProfileList;
|
||||
this.saveProfiles(profiles);
|
||||
}
|
||||
|
||||
getProfileListWithoutTeam(skipCurrent = false, skipInactive = false) {
|
||||
const userIds = this.profiles_without_team || [];
|
||||
const userIds = Array.from(Selectors.getUserIdsWithoutTeam(store.getState()) || []);
|
||||
|
||||
return this.getProfileListForIds(userIds, skipCurrent, skipInactive);
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
setSessions(sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
getSessions() {
|
||||
return this.sessions;
|
||||
}
|
||||
|
||||
setAudits(audits) {
|
||||
this.audits = audits;
|
||||
return store.getState().entities.users.mySessions;
|
||||
}
|
||||
|
||||
getAudits() {
|
||||
return this.audits;
|
||||
return store.getState().entities.users.myAudits;
|
||||
}
|
||||
|
||||
getCurrentMentionKeys() {
|
||||
@@ -668,17 +466,16 @@ class UserStoreClass extends EventEmitter {
|
||||
return keys;
|
||||
}
|
||||
|
||||
setStatuses(statuses) {
|
||||
this.statuses = Object.assign(this.statuses, statuses);
|
||||
}
|
||||
|
||||
setStatus(userId, status) {
|
||||
this.statuses[userId] = status;
|
||||
this.emitStatusesChange();
|
||||
const data = [{user_id: userId, status}];
|
||||
store.dispatch({
|
||||
type: UserTypes.RECEIVED_STATUSES,
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
getStatuses() {
|
||||
return this.statuses;
|
||||
return store.getState().entities.users.statuses;
|
||||
}
|
||||
|
||||
getStatus(id) {
|
||||
@@ -686,7 +483,7 @@ class UserStoreClass extends EventEmitter {
|
||||
}
|
||||
|
||||
getNoAccounts() {
|
||||
return this.noAccounts;
|
||||
return global.window.mm_config.NoAccounts === 'true';
|
||||
}
|
||||
|
||||
setNoAccounts(noAccounts) {
|
||||
@@ -706,141 +503,9 @@ class UserStoreClass extends EventEmitter {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
setPage(offset, count) {
|
||||
this.paging_offset = offset + count;
|
||||
this.paging_count = this.paging_count + count;
|
||||
}
|
||||
|
||||
getPagingOffset() {
|
||||
return this.paging_offset;
|
||||
}
|
||||
|
||||
getPagingCount() {
|
||||
return this.paging_count;
|
||||
}
|
||||
|
||||
setInTeamPage(offset, count) {
|
||||
this.in_team_offset = offset + count;
|
||||
this.in_team_count = this.in_team_count + count;
|
||||
}
|
||||
|
||||
getInTeamPagingOffset() {
|
||||
return this.in_team_offset;
|
||||
}
|
||||
|
||||
getInTeamPagingCount() {
|
||||
return this.in_team_count;
|
||||
}
|
||||
|
||||
setNotInTeamPage(offset, count) {
|
||||
this.not_in_team_offset = offset + count;
|
||||
this.not_in_team_count = this.not_in_team_count + count;
|
||||
}
|
||||
|
||||
getNotInTeamPagingOffset() {
|
||||
return this.not_in_team_offset;
|
||||
}
|
||||
|
||||
getNotInTeamPagingCount() {
|
||||
return this.not_in_team_count;
|
||||
}
|
||||
|
||||
setInChannelPage(channelId, offset, count) {
|
||||
this.in_channel_offset[channelId] = offset + count;
|
||||
this.in_channel_count[channelId] = this.dm_paging_count + count;
|
||||
}
|
||||
|
||||
getInChannelPagingOffset(channelId) {
|
||||
return this.in_channel_offset[channelId] | 0;
|
||||
}
|
||||
|
||||
getInChannelPagingCount(channelId) {
|
||||
return this.in_channel_count[channelId] | 0;
|
||||
}
|
||||
|
||||
setNotInChannelPage(channelId, offset, count) {
|
||||
this.not_in_channel_offset[channelId] = offset + count;
|
||||
this.not_in_channel_count[channelId] = this.dm_paging_count + count;
|
||||
}
|
||||
|
||||
getNotInChannelPagingOffset(channelId) {
|
||||
return this.not_in_channel_offset[channelId] | 0;
|
||||
}
|
||||
|
||||
getNotInChannelPagingCount(channelId) {
|
||||
return this.not_in_channel_count[channelId] | 0;
|
||||
}
|
||||
}
|
||||
|
||||
var UserStore = new UserStoreClass();
|
||||
UserStore.setMaxListeners(600);
|
||||
|
||||
UserStore.dispatchToken = AppDispatcher.register((payload) => {
|
||||
var action = payload.action;
|
||||
|
||||
switch (action.type) {
|
||||
case ActionTypes.RECEIVED_PROFILES:
|
||||
UserStore.saveProfiles(action.profiles);
|
||||
if (action.offset != null && action.count != null) {
|
||||
UserStore.setPage(action.offset, action.count);
|
||||
}
|
||||
UserStore.emitChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILES_IN_TEAM:
|
||||
UserStore.saveProfilesInTeam(action.team_id, action.profiles);
|
||||
if (action.offset != null && action.count != null) {
|
||||
UserStore.setInTeamPage(action.offset, action.count);
|
||||
}
|
||||
UserStore.emitInTeamChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILES_NOT_IN_TEAM:
|
||||
UserStore.saveProfilesNotInTeam(action.team_id, action.profiles);
|
||||
if (action.offset != null && action.count != null) {
|
||||
UserStore.setNotInTeamPage(action.offset, action.count);
|
||||
}
|
||||
UserStore.emitNotInTeamChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILES_IN_CHANNEL:
|
||||
UserStore.saveProfilesInChannel(action.channel_id, action.profiles);
|
||||
if (action.offset != null && action.count != null) {
|
||||
UserStore.setInChannelPage(action.offset, action.count);
|
||||
}
|
||||
UserStore.emitInChannelChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILES_NOT_IN_CHANNEL:
|
||||
UserStore.saveProfilesNotInChannel(action.channel_id, action.profiles);
|
||||
if (action.offset != null && action.count != null) {
|
||||
UserStore.setNotInChannelPage(action.offset, action.count);
|
||||
}
|
||||
UserStore.emitNotInChannelChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILES_WITHOUT_TEAM:
|
||||
UserStore.saveProfilesWithoutTeam(action.profiles);
|
||||
UserStore.emitWithoutTeamChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_PROFILE:
|
||||
UserStore.saveProfile(action.profile);
|
||||
UserStore.emitChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_ME:
|
||||
UserStore.setCurrentUser(action.me);
|
||||
UserStore.emitChange(action.me.id);
|
||||
break;
|
||||
case ActionTypes.RECEIVED_SESSIONS:
|
||||
UserStore.setSessions(action.sessions);
|
||||
UserStore.emitSessionsChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_AUDITS:
|
||||
UserStore.setAudits(action.audits);
|
||||
UserStore.emitAuditsChange();
|
||||
break;
|
||||
case ActionTypes.RECEIVED_STATUSES:
|
||||
UserStore.setStatuses(action.statuses);
|
||||
UserStore.emitStatusesChange();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
export {UserStore as default};
|
||||
|
||||
Ссылка в новой задаче
Block a user