Refactor login, claim and create_team into views and add actions (#3110)

Этот коммит содержится в:
Joram Wilander
2016-05-26 09:46:18 -04:00
коммит произвёл Harrison Healey
родитель 9c0caaa765
Коммит 6fecfcc7ca
44 изменённых файлов: 163 добавлений и 149 удалений

12
webapp/actions/analytics_actions.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,12 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Client from 'utils/web_client.jsx';
export function track(category, action, label, property, value) {
Client.track(category, action, label, property, value);
}
export function trackPage() {
Client.trackPage();
}

470
webapp/actions/global_actions.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,470 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import PostStore from 'stores/post_store.jsx';
import UserStore from 'stores/user_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import SearchStore from 'stores/search_store.jsx';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
import * as AsyncClient from 'utils/async_client.jsx';
import Client from 'utils/web_client.jsx';
import * as Utils from 'utils/utils.jsx';
import * as Websockets from './websocket_actions.jsx';
import * as I18n from 'i18n/i18n.jsx';
import {trackPage} from 'actions/analytics_actions.jsx';
import {browserHistory} from 'react-router';
import en from 'i18n/en.json';
export function emitChannelClickEvent(channel) {
function userVisitedFakeChannel(chan, success, fail) {
const otherUserId = Utils.getUserIdFromChannelName(chan);
Client.createDirectChannel(
otherUserId,
(data) => {
success(data);
},
() => {
fail();
}
);
}
function switchToChannel(chan) {
AsyncClient.getChannels(true);
AsyncClient.getChannelExtraInfo(chan.id);
AsyncClient.updateLastViewedAt(chan.id);
AsyncClient.getPosts(chan.id);
trackPage();
AppDispatcher.handleViewAction({
type: ActionTypes.CLICK_CHANNEL,
name: chan.name,
id: chan.id,
prev: ChannelStore.getCurrentId()
});
}
if (channel.fake) {
userVisitedFakeChannel(
channel,
(data) => {
switchToChannel(data);
},
() => {
browserHistory.push('/' + this.state.currentTeam.name);
}
);
} else {
switchToChannel(channel);
}
}
export function emitInitialLoad(callback) {
Client.getInitialLoad(
(data) => {
global.window.mm_config = data.client_cfg;
global.window.mm_license = data.license_cfg;
UserStore.setNoAccounts(data.no_accounts);
if (data.user && data.user.id) {
global.window.mm_user = data.user;
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ME,
me: data.user
});
}
if (data.preferences) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PREFERENCES,
preferences: data.preferences
});
}
if (data.teams) {
var teams = {};
data.teams.forEach((team) => {
teams[team.id] = team;
});
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_ALL_TEAMS,
teams
});
}
if (data.team_members) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_TEAM_MEMBERS,
team_members: data.team_members
});
}
if (data.direct_profiles) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_DIRECT_PROFILES,
profiles: data.direct_profiles
});
}
if (callback) {
callback();
}
},
(err) => {
AsyncClient.dispatchError(err, 'getInitialLoad');
if (callback) {
callback();
}
}
);
}
export function doFocusPost(channelId, postId, data) {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_FOCUSED_POST,
postId,
post_list: data
});
AsyncClient.getChannels(true);
AsyncClient.getChannelExtraInfo(channelId);
AsyncClient.getPostsBefore(postId, 0, Constants.POST_FOCUS_CONTEXT_RADIUS);
AsyncClient.getPostsAfter(postId, 0, Constants.POST_FOCUS_CONTEXT_RADIUS);
}
export function emitPostFocusEvent(postId) {
AsyncClient.getChannels(true);
Client.getPermalinkTmp(
postId,
(data) => {
if (!data) {
return;
}
const channelId = data.posts[data.order[0]].channel_id;
doFocusPost(channelId, postId, data);
},
() => {
browserHistory.push('/error?message=' + encodeURIComponent(Utils.localizeMessage('permalink.error.access', 'Permalink belongs to a channel you do not have access to')));
}
);
}
export function emitProfilesForDmList() {
AsyncClient.getProfilesForDirectMessageList();
AsyncClient.getTeamMembers(TeamStore.getCurrentId());
}
export function emitCloseRightHandSide() {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH,
results: null
});
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POST_SELECTED,
postId: null
});
}
export function emitPostFocusRightHandSideFromSearch(post, isMentionSearch) {
Client.getPost(
post.channel_id,
post.id,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POSTS,
id: post.channel_id,
numRequested: 0,
post_list: data
});
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POST_SELECTED,
postId: Utils.getRootId(post),
from_search: SearchStore.getSearchTerm()
});
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_SEARCH,
results: null,
is_mention_search: isMentionSearch
});
},
(err) => {
AsyncClient.dispatchError(err, 'getPost');
}
);
}
export function emitLoadMorePostsEvent() {
const id = ChannelStore.getCurrentId();
loadMorePostsTop(id);
}
export function emitLoadMorePostsFocusedTopEvent() {
const id = PostStore.getFocusedPostId();
loadMorePostsTop(id);
}
export function loadMorePostsTop(id) {
const earliestPostId = PostStore.getEarliestPost(id).id;
if (PostStore.requestVisibilityIncrease(id, Constants.POST_CHUNK_SIZE)) {
AsyncClient.getPostsBefore(earliestPostId, 0, Constants.POST_CHUNK_SIZE);
}
}
export function emitLoadMorePostsFocusedBottomEvent() {
const id = PostStore.getFocusedPostId();
const latestPostId = PostStore.getLatestPost(id).id;
AsyncClient.getPostsAfter(latestPostId, 0, Constants.POST_CHUNK_SIZE);
}
export function emitPostRecievedEvent(post, msg) {
if (ChannelStore.getCurrentId() === post.channel_id) {
if (window.isActive) {
AsyncClient.updateLastViewedAt();
} else {
AsyncClient.getChannel(post.channel_id);
}
} else if (msg && (TeamStore.getCurrentId() === msg.team_id || msg.props.channel_type === Constants.DM_CHANNEL)) {
AsyncClient.getChannel(post.channel_id);
}
var websocketMessageProps = null;
if (msg) {
websocketMessageProps = msg.props;
}
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_POST,
post,
websocketMessageProps
});
}
export function emitUserPostedEvent(post) {
AppDispatcher.handleServerAction({
type: ActionTypes.CREATE_POST,
post
});
}
export function emitPostDeletedEvent(post) {
AppDispatcher.handleServerAction({
type: ActionTypes.POST_DELETED,
post
});
}
export function showDeletePostModal(post, commentCount = 0) {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_DELETE_POST_MODAL,
value: true,
post,
commentCount
});
}
export function showGetPostLinkModal(post) {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_GET_POST_LINK_MODAL,
value: true,
post
});
}
export function showGetPublicLinkModal(filename) {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_GET_PUBLIC_LINK_MODAL,
value: true,
filename
});
}
export function showGetTeamInviteLinkModal() {
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.TOGGLE_GET_TEAM_INVITE_LINK_MODAL,
value: true
});
}
export function showInviteMemberModal() {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_INVITE_MEMBER_MODAL,
value: true
});
}
export function showRegisterAppModal() {
AppDispatcher.handleViewAction({
type: ActionTypes.TOGGLE_REGISTER_APP_MODAL,
value: true
});
}
export function emitSuggestionPretextChanged(suggestionId, pretext) {
AppDispatcher.handleViewAction({
type: ActionTypes.SUGGESTION_PRETEXT_CHANGED,
id: suggestionId,
pretext
});
}
export function emitSelectNextSuggestion(suggestionId) {
AppDispatcher.handleViewAction({
type: ActionTypes.SUGGESTION_SELECT_NEXT,
id: suggestionId
});
}
export function emitSelectPreviousSuggestion(suggestionId) {
AppDispatcher.handleViewAction({
type: ActionTypes.SUGGESTION_SELECT_PREVIOUS,
id: suggestionId
});
}
export function emitCompleteWordSuggestion(suggestionId, term = '') {
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.SUGGESTION_COMPLETE_WORD,
id: suggestionId,
term
});
}
export function emitClearSuggestions(suggestionId) {
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.SUGGESTION_CLEAR_SUGGESTIONS,
id: suggestionId
});
}
export function emitPreferenceChangedEvent(preference) {
if (preference.category === Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW) {
AsyncClient.getDirectProfiles();
}
AppDispatcher.handleServerAction({
type: Constants.ActionTypes.RECEIVED_PREFERENCE,
preference
});
}
export function emitRemovePost(post) {
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.REMOVE_POST,
post
});
}
export function sendEphemeralPost(message, channelId) {
const timestamp = Utils.getTimestamp();
const post = {
id: Utils.generateId(),
user_id: '0',
channel_id: channelId || ChannelStore.getCurrentId(),
message,
type: Constants.POST_TYPE_EPHEMERAL,
create_at: timestamp,
update_at: timestamp,
filenames: [],
props: {}
};
emitPostRecievedEvent(post);
}
export function newLocalizationSelected(locale) {
if (locale === 'en') {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_LOCALE,
locale,
translations: en
});
} else {
Client.getTranslations(
I18n.getLanguageInfo(locale).url,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_LOCALE,
locale,
translations: data
});
},
(err) => {
AsyncClient.dispatchError(err, 'getTranslations');
}
);
}
}
export function loadBrowserLocale() {
let locale = (navigator.languages && navigator.languages.length > 0 ? navigator.languages[0] :
(navigator.language || navigator.userLanguage)).split('-')[0];
if (!I18n.getLanguages()[locale]) {
locale = 'en';
}
return newLocalizationSelected(locale);
}
export function viewLoggedIn() {
AsyncClient.getChannels();
AsyncClient.getChannelExtraInfo();
// Clear pending posts (shouldn't have pending posts if we are loading)
PostStore.clearPendingPosts();
}
var lastTimeTypingSent = 0;
export function emitLocalUserTypingEvent(channelId, parentId) {
const t = Date.now();
if ((t - lastTimeTypingSent) > Constants.UPDATE_TYPING_MS) {
Websockets.sendMessage({channel_id: channelId, action: 'typing', props: {parent_id: parentId}, state: {}});
lastTimeTypingSent = t;
}
}
export function emitRemoteUserTypingEvent(channelId, userId, postParentId) {
AppDispatcher.handleViewAction({
type: Constants.ActionTypes.USER_TYPING,
channelId,
userId,
postParentId
});
}
export function emitUserLoggedOutEvent(redirectTo) {
const rURL = (redirectTo && typeof redirectTo === 'string') ? redirectTo : '/';
Client.logout(
() => {
BrowserStore.signalLogout();
BrowserStore.clear();
ErrorStore.clearLastError();
PreferenceStore.clear();
UserStore.clear();
TeamStore.clear();
browserHistory.push(rURL);
},
() => {
browserHistory.push(rURL);
}
);
}
export function emitJoinChannelEvent(channel, success, failure) {
Client.joinChannel(
channel.id,
success,
failure,
);
}

38
webapp/actions/team_actions.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,38 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import UserStore from 'stores/user_store.jsx';
import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes;
import * as AsyncClient from 'utils/async_client.jsx';
import Client from 'utils/web_client.jsx';
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import {browserHistory} from 'react-router';
export function checkIfTeamExists(teamName, onSuccess, onError) {
Client.findTeamByName(teamName, onSuccess, onError);
}
export function createTeam(team, onSuccess, onError) {
Client.createTeam(team,
(rteam) => {
AsyncClient.getDirectProfiles();
AppDispatcher.handleServerAction({
type: ActionTypes.CREATED_TEAM,
team: rteam,
member: {team_id: rteam.id, user_id: UserStore.getCurrentId(), roles: 'admin'}
});
browserHistory.push('/' + rteam.name + '/channels/town-square');
if (onSuccess) {
onSuccess(rteam);
}
},
onError
);
}

270
webapp/actions/websocket_actions.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,270 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import $ from 'jquery';
import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import PostStore from 'stores/post_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import BrowserStore from 'stores/browser_store.jsx';
import ErrorStore from 'stores/error_store.jsx';
import NotificationStore from 'stores/notification_store.jsx'; //eslint-disable-line no-unused-vars
import Client from 'utils/web_client.jsx';
import * as Utils from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import Constants from 'utils/constants.jsx';
const SocketEvents = Constants.SocketEvents;
import {browserHistory} from 'react-router';
const MAX_WEBSOCKET_FAILS = 7;
const WEBSOCKET_RETRY_TIME = 3000;
var conn = null;
var connectFailCount = 0;
var pastFirstInit = false;
var manuallyClosed = false;
export function initialize() {
if (window.WebSocket && !conn) {
let protocol = 'ws://';
if (window.location.protocol === 'https:') {
protocol = 'wss://';
}
const connUrl = protocol + location.host + ((/:\d+/).test(location.host) ? '' : Utils.getWebsocketPort(protocol)) + Client.getUsersRoute() + '/websocket';
if (connectFailCount === 0) {
console.log('websocket connecting to ' + connUrl); //eslint-disable-line no-console
}
manuallyClosed = false;
conn = new WebSocket(connUrl);
conn.onopen = () => {
if (connectFailCount > 0) {
console.log('websocket re-established connection'); //eslint-disable-line no-console
AsyncClient.getChannels();
AsyncClient.getPosts(ChannelStore.getCurrentId());
}
if (pastFirstInit) {
ErrorStore.clearLastError();
ErrorStore.emitChange();
}
pastFirstInit = true;
connectFailCount = 0;
};
conn.onclose = () => {
conn = null;
if (connectFailCount === 0) {
console.log('websocket closed'); //eslint-disable-line no-console
}
if (manuallyClosed) {
return;
}
connectFailCount = connectFailCount + 1;
if (connectFailCount > MAX_WEBSOCKET_FAILS) {
ErrorStore.storeLastError({message: Utils.localizeMessage('channel_loader.socketError', 'Please check connection, Mattermost unreachable. If issue persists, ask administrator to check WebSocket port.')});
}
ErrorStore.setConnectionErrorCount(connectFailCount);
ErrorStore.emitChange();
setTimeout(
() => {
initialize();
},
WEBSOCKET_RETRY_TIME
);
};
conn.onerror = (evt) => {
if (connectFailCount <= 1) {
console.log('websocket error'); //eslint-disable-line no-console
console.log(evt); //eslint-disable-line no-console
}
};
conn.onmessage = (evt) => {
const msg = JSON.parse(evt.data);
handleMessage(msg);
};
}
}
function handleMessage(msg) {
// Let the store know we are online. This probably shouldn't be here.
UserStore.setStatus(msg.user_id, 'online');
switch (msg.action) {
case SocketEvents.POSTED:
case SocketEvents.EPHEMERAL_MESSAGE:
handleNewPostEvent(msg);
break;
case SocketEvents.POST_EDITED:
handlePostEditEvent(msg);
break;
case SocketEvents.POST_DELETED:
handlePostDeleteEvent(msg);
break;
case SocketEvents.NEW_USER:
handleNewUserEvent();
break;
case SocketEvents.USER_ADDED:
handleUserAddedEvent(msg);
break;
case SocketEvents.USER_REMOVED:
handleUserRemovedEvent(msg);
break;
case SocketEvents.CHANNEL_VIEWED:
handleChannelViewedEvent(msg);
break;
case SocketEvents.CHANNEL_DELETED:
handleChannelDeletedEvent(msg);
break;
case SocketEvents.DIRECT_ADDED:
handleDirectAddedEvent(msg);
break;
case SocketEvents.PREFERENCE_CHANGED:
handlePreferenceChangedEvent(msg);
break;
case SocketEvents.TYPING:
handleUserTypingEvent(msg);
break;
default:
}
}
export function sendMessage(msg) {
if (conn && conn.readyState === WebSocket.OPEN) {
var teamId = TeamStore.getCurrentId();
if (teamId && teamId.length > 0) {
msg.team_id = teamId;
}
conn.send(JSON.stringify(msg));
} else if (!conn || conn.readyState === WebSocket.Closed) {
conn = null;
initialize();
}
}
export function close() {
manuallyClosed = true;
connectFailCount = 0;
if (conn && conn.readyState === WebSocket.OPEN) {
conn.close();
}
}
function handleNewPostEvent(msg) {
const post = JSON.parse(msg.props.post);
GlobalActions.emitPostRecievedEvent(post, msg);
}
function handlePostEditEvent(msg) {
// Store post
const post = JSON.parse(msg.props.post);
PostStore.storePost(post);
PostStore.emitChange();
// Update channel state
if (ChannelStore.getCurrentId() === msg.channel_id) {
if (window.isActive) {
AsyncClient.updateLastViewedAt();
}
}
}
function handlePostDeleteEvent(msg) {
const post = JSON.parse(msg.props.post);
GlobalActions.emitPostDeletedEvent(post);
}
function handleNewUserEvent() {
AsyncClient.getProfiles();
AsyncClient.getDirectProfiles();
AsyncClient.getChannelExtraInfo();
}
function handleDirectAddedEvent(msg) {
AsyncClient.getChannel(msg.channel_id);
AsyncClient.getDirectProfiles();
}
function handleUserAddedEvent(msg) {
if (ChannelStore.getCurrentId() === msg.channel_id) {
AsyncClient.getChannelExtraInfo();
}
if (TeamStore.getCurrentId() === msg.team_id && UserStore.getCurrentId() === msg.user_id) {
AsyncClient.getChannel(msg.channel_id);
}
}
function handleUserRemovedEvent(msg) {
if (UserStore.getCurrentId() === msg.user_id) {
AsyncClient.getChannels();
if (msg.props.remover_id !== msg.user_id &&
msg.channel_id === ChannelStore.getCurrentId() &&
$('#removed_from_channel').length > 0) {
var sentState = {};
sentState.channelName = ChannelStore.getCurrent().display_name;
sentState.remover = UserStore.getProfile(msg.props.remover_id).username;
BrowserStore.setItem('channel-removed-state', sentState);
$('#removed_from_channel').modal('show');
}
} else if (ChannelStore.getCurrentId() === msg.channel_id) {
AsyncClient.getChannelExtraInfo();
}
}
function handleChannelViewedEvent(msg) {
// Useful for when multiple devices have the app open to different channels
if (TeamStore.getCurrentId() === msg.team_id && ChannelStore.getCurrentId() !== msg.channel_id && UserStore.getCurrentId() === msg.user_id) {
AsyncClient.getChannel(msg.channel_id);
}
}
function handleChannelDeletedEvent(msg) {
if (ChannelStore.getCurrentId() === msg.channel_id) {
const teamUrl = TeamStore.getCurrentTeamRelativeUrl();
browserHistory.push(teamUrl + '/channels/' + Constants.DEFAULT_CHANNEL);
}
AsyncClient.getChannels();
}
function handlePreferenceChangedEvent(msg) {
const preference = JSON.parse(msg.props.preference);
GlobalActions.emitPreferenceChangedEvent(preference);
}
function handleUserTypingEvent(msg) {
if (TeamStore.getCurrentId() === msg.team_id) {
GlobalActions.emitRemoteUserTypingEvent(msg.channel_id, msg.user_id, msg.props.parent_id);
}
}