Add files
This commit is contained in:
commit
bb80829159
18195 changed files with 2122994 additions and 0 deletions
605
509bba001a76711dd089.css
Executable file
605
509bba001a76711dd089.css
Executable file
File diff suppressed because one or more lines are too long
1
509bba001a76711dd089.css.map
Executable file
1
509bba001a76711dd089.css.map
Executable file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":[],"names":[],"mappings":"","file":"509bba001a76711dd089.css","sourceRoot":""}
|
2
509bba001a76711dd089.js
Executable file
2
509bba001a76711dd089.js
Executable file
File diff suppressed because one or more lines are too long
1
509bba001a76711dd089.js.map
Executable file
1
509bba001a76711dd089.js.map
Executable file
File diff suppressed because one or more lines are too long
191208
509bba001a76711dd089_formatted.js
Executable file
191208
509bba001a76711dd089_formatted.js
Executable file
File diff suppressed because one or more lines are too long
215639
509bba001a76711dd089_mapped.js
Executable file
215639
509bba001a76711dd089_mapped.js
Executable file
File diff suppressed because one or more lines are too long
2718
509bba0_supplemented_files_log.txt
Executable file
2718
509bba0_supplemented_files_log.txt
Executable file
File diff suppressed because it is too large
Load diff
8
509bba0_unpacked/CHANGELOG.md
Executable file
8
509bba0_unpacked/CHANGELOG.md
Executable file
File diff suppressed because one or more lines are too long
2154
509bba0_unpacked/discord_app/Constants.js
Executable file
2154
509bba0_unpacked/discord_app/Constants.js
Executable file
File diff suppressed because it is too large
Load diff
79
509bba0_unpacked/discord_app/Dispatcher.js
Executable file
79
509bba0_unpacked/discord_app/Dispatcher.js
Executable file
|
@ -0,0 +1,79 @@
|
|||
/* @flow */
|
||||
|
||||
import Flux from 'flux';
|
||||
import Store from './lib/flux/Store';
|
||||
import type {Action} from './flow/Action';
|
||||
|
||||
type Interceptor = (payload: mixed) => boolean;
|
||||
|
||||
export class Dispatcher<Action> extends Flux.Dispatcher<Action> {
|
||||
_interceptor: ?Interceptor;
|
||||
_afterDispatch: ?Function;
|
||||
|
||||
// Super hacky but to avoid forking and rewriting Facebook's Flux Dispatcher
|
||||
// this is a way to hook into the dispatch call's cleanup method to trigger
|
||||
// all the stores' at the same time. This makes it so setState is going to
|
||||
// be the same on all emits and `shouldComponentUpdate1 will be even more
|
||||
// effective.
|
||||
_stopDispatching(...args: Array<any>) {
|
||||
try {
|
||||
Store.emitChanges();
|
||||
} finally {
|
||||
super._stopDispatching(...args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this in situations where a user action should trigger a Dispatch but
|
||||
* an action that occurs during a dispatch does not need to trigger it.
|
||||
*/
|
||||
maybeDispatch(payload: Action) {
|
||||
if (!this.isDispatching()) {
|
||||
this.dispatch(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to Dispatch in a situation where you have no other choice but to
|
||||
* defer it to the next event loop tick. This should be used in VERY special cases
|
||||
* because it can result in performance issues.
|
||||
*/
|
||||
dirtyDispatch(payload: Action) {
|
||||
if (this.isDispatching()) {
|
||||
setImmediate(this.dispatch.bind(this, payload));
|
||||
} else {
|
||||
this.dispatch(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a payload to all registered callbacks.
|
||||
*/
|
||||
dispatch(payload: Action) {
|
||||
if (this._interceptor == null || !this._interceptor(payload)) {
|
||||
super.dispatch(payload);
|
||||
this._afterDispatch && this._afterDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set interceptor that might consume payloads.
|
||||
*/
|
||||
setInterceptor(interceptor: ?Interceptor) {
|
||||
this._interceptor = interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to run after a dispatch.
|
||||
*/
|
||||
setAfterDispatch(callback: ?Function) {
|
||||
this._afterDispatch = callback;
|
||||
}
|
||||
}
|
||||
|
||||
export default (new Dispatcher(): Dispatcher<Action>);
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/Dispatcher.js
|
29
509bba0_unpacked/discord_app/actions/AccessibilityActionCreators.js
Executable file
29
509bba0_unpacked/discord_app/actions/AccessibilityActionCreators.js
Executable file
|
@ -0,0 +1,29 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export function fontScaleTo(fontScale: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.ACCESSIBILITY_FONT_SCALE_TO,
|
||||
fontScale,
|
||||
});
|
||||
}
|
||||
|
||||
export function zoomTo(zoom: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.ACCESSIBILITY_ZOOM_TO,
|
||||
zoom,
|
||||
});
|
||||
}
|
||||
|
||||
export function resetToDefault() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.ACCESSIBILITY_RESET_TO_DEFAULT,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AccessibilityActionCreators.js
|
17
509bba0_unpacked/discord_app/actions/AlertActionCreators.js
Executable file
17
509bba0_unpacked/discord_app/actions/AlertActionCreators.js
Executable file
|
@ -0,0 +1,17 @@
|
|||
let AlertActionCreators = {};
|
||||
if (__SDK__) {
|
||||
AlertActionCreators = {
|
||||
show() {},
|
||||
};
|
||||
} else if (__IOS__) {
|
||||
AlertActionCreators = require('./ios/AlertActionCreators');
|
||||
} else {
|
||||
AlertActionCreators = require('./web/AlertActionCreators');
|
||||
}
|
||||
|
||||
export default AlertActionCreators;
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AlertActionCreators.js
|
237
509bba0_unpacked/discord_app/actions/AudioActionCreators.js
Executable file
237
509bba0_unpacked/discord_app/actions/AudioActionCreators.js
Executable file
|
@ -0,0 +1,237 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, InputModes} from '../Constants';
|
||||
import MediaEngineStore from '../stores/MediaEngineStore';
|
||||
import type {InputModeOptions} from '../flow/Client';
|
||||
import {MediaEngineImplementations} from '../lib/MediaEngine';
|
||||
import type {Application} from '../lib/native/rpc_server/RPCTypes';
|
||||
|
||||
let AudioActionCreators = {
|
||||
isNotSupported() {
|
||||
return false;
|
||||
},
|
||||
|
||||
enable() {
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_ENABLE});
|
||||
},
|
||||
};
|
||||
|
||||
if (__WEB__ && !__SDK__) {
|
||||
AudioActionCreators = require('./web/AudioActionCreators');
|
||||
}
|
||||
|
||||
const {enable, isNotSupported} = AudioActionCreators;
|
||||
|
||||
export default {
|
||||
enable: enable,
|
||||
|
||||
toggleSelfMute() {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
if (MediaEngineStore.isEnabled()) {
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_TOGGLE_SELF_MUTE});
|
||||
} else {
|
||||
this.enable();
|
||||
}
|
||||
},
|
||||
|
||||
setTemporarySelfMute(mute: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_SET_TEMPORARY_SELF_MUTE, mute});
|
||||
},
|
||||
|
||||
toggleSelfDeaf() {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_TOGGLE_SELF_DEAF});
|
||||
},
|
||||
|
||||
toggleLocalMute(userId: string) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_TOGGLE_LOCAL_MUTE, userId});
|
||||
},
|
||||
|
||||
setLocalVolume(userId: string, volume: number) {
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_SET_LOCAL_VOLUME, userId, volume});
|
||||
},
|
||||
|
||||
setLocalPan(userId: string, left: number, right: number) {
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIO_SET_LOCAL_PAN, userId, left, right});
|
||||
},
|
||||
|
||||
setMode(mode: $Keys<typeof InputModes>, options?: InputModeOptions) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
if (options == null) {
|
||||
options = MediaEngineStore.getModeOptions();
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_MODE,
|
||||
mode,
|
||||
options,
|
||||
});
|
||||
},
|
||||
|
||||
setInputVolume(volume: number) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_INPUT_VOLUME,
|
||||
volume,
|
||||
});
|
||||
},
|
||||
|
||||
setOutputVolume(volume: number) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_OUTPUT_VOLUME,
|
||||
volume,
|
||||
});
|
||||
},
|
||||
|
||||
setInputDevice(id: string) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_INPUT_DEVICE,
|
||||
id,
|
||||
});
|
||||
},
|
||||
|
||||
setOutputDevice(id: string) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_OUTPUT_DEVICE,
|
||||
id,
|
||||
});
|
||||
},
|
||||
|
||||
setVideoDevice(id: string) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MEDIA_ENGINE_SET_VIDEO_DEVICE,
|
||||
id,
|
||||
});
|
||||
},
|
||||
|
||||
setEchoCancellation(enabled: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_ECHO_CANCELLATION,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
setNoiseSuppression(enabled: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_NOISE_SUPPRESSION,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
setAutomaticGainControl(enabled: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_AUTOMATIC_GAIN_CONTROL,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
setAttenuation(attenuation: number, attenuateWhileSpeakingSelf: boolean, attenuateWhileSpeakingOthers: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_ATTENUATION,
|
||||
attenuation,
|
||||
attenuateWhileSpeakingSelf,
|
||||
attenuateWhileSpeakingOthers,
|
||||
});
|
||||
},
|
||||
|
||||
setQoS(enabled: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_QOS,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
reset() {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_RESET,
|
||||
});
|
||||
},
|
||||
|
||||
setSilenceWarning(enabled: boolean) {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_DISPLAY_SILENCE_WARNING,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
switchSubsystem() {
|
||||
if (isNotSupported()) return;
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SWITCH_SUBSYSTEM,
|
||||
});
|
||||
},
|
||||
|
||||
setCurrentApp(application: Application) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIO_SET_CURRENT_APP,
|
||||
application,
|
||||
});
|
||||
},
|
||||
|
||||
setMediaEngine(implementation: $Keys<typeof MediaEngineImplementations>) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.SET_MEDIA_ENGINE,
|
||||
implementation,
|
||||
});
|
||||
},
|
||||
|
||||
setVideoEnabled(enabled: boolean, channelId?: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MEDIA_ENGINE_SET_VIDEO_ENABLED,
|
||||
enabled,
|
||||
channelId,
|
||||
});
|
||||
|
||||
if (!MediaEngineStore.isEnabled()) {
|
||||
enable(true);
|
||||
}
|
||||
},
|
||||
|
||||
setDesktopSource(sourceId: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MEDIA_ENGINE_SET_DESKTOP_SOURCE,
|
||||
sourceId,
|
||||
});
|
||||
|
||||
if (!MediaEngineStore.isEnabled()) {
|
||||
enable();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AudioActionCreators.js
|
121
509bba0_unpacked/discord_app/actions/AuditLogActionCreators.js
Executable file
121
509bba0_unpacked/discord_app/actions/AuditLogActionCreators.js
Executable file
|
@ -0,0 +1,121 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import GuildSettingsAuditLogStore from '../stores/GuildSettingsAuditLogStore';
|
||||
import {ActionTypes, Endpoints, AUDIT_LOG_PAGE_LIMIT} from '../Constants';
|
||||
|
||||
function transformQuery({before, userId, action}: *) {
|
||||
userId = userId || GuildSettingsAuditLogStore.userIdFilter;
|
||||
action = action || GuildSettingsAuditLogStore.actionFilter;
|
||||
|
||||
const query = {};
|
||||
query.limit = AUDIT_LOG_PAGE_LIMIT;
|
||||
if (before != null) {
|
||||
query.before = before;
|
||||
}
|
||||
if (userId != null) {
|
||||
// eslint-disable-next-line camelcase
|
||||
query.user_id = userId;
|
||||
}
|
||||
if (action != null) {
|
||||
// eslint-disable-next-line camelcase
|
||||
query.action_type = action;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
function isLoading() {
|
||||
return GuildSettingsAuditLogStore.isLoading || GuildSettingsAuditLogStore.isLoadingNextPage;
|
||||
}
|
||||
|
||||
function makeRequest(guildId: *, query: {before?: ?string, userId?: ?string, action?: ?number}) {
|
||||
const transformedQuery = transformQuery(query);
|
||||
return HTTPUtils.get({url: Endpoints.GUILD_AUDIT_LOG(guildId), query: transformedQuery});
|
||||
}
|
||||
|
||||
export function fetchLogs(guildId: string, userId?: ?string, action?: ?number) {
|
||||
if (isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.AUDIT_LOG_FETCH_START});
|
||||
|
||||
return makeRequest(guildId, {userId, action}).then(
|
||||
res => {
|
||||
const {audit_log_entries: logs, users, webhooks} = res.body;
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIT_LOG_FETCH_SUCCESS,
|
||||
logs,
|
||||
users,
|
||||
webhooks,
|
||||
});
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.AUDIT_LOG_FETCH_FAIL})
|
||||
);
|
||||
}
|
||||
|
||||
export function fetchNextLogPage(guildId: string, isGroupedFetch: boolean = false) {
|
||||
if (!GuildSettingsAuditLogStore.hasOlderLogs || isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const logs = GuildSettingsAuditLogStore.logs;
|
||||
const last = logs[logs.length - 1];
|
||||
let before = null;
|
||||
if (last != null) {
|
||||
before = last.id;
|
||||
}
|
||||
|
||||
// This can happen as a result of loading more logs
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.AUDIT_LOG_FETCH_NEXT_PAGE_START,
|
||||
before,
|
||||
isGroupedFetch,
|
||||
});
|
||||
|
||||
return makeRequest(guildId, {before}).then(
|
||||
res => {
|
||||
const {audit_log_entries: logs, users, webhooks} = res.body;
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIT_LOG_FETCH_NEXT_PAGE_SUCCESS,
|
||||
logs,
|
||||
users,
|
||||
webhooks,
|
||||
});
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.AUDIT_LOG_FETCH_NEXT_PAGE_FAIL})
|
||||
);
|
||||
}
|
||||
|
||||
export function filterByAction(action: number, guildId: string) {
|
||||
if (isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIT_LOG_FILTER_BY_ACTION,
|
||||
action,
|
||||
});
|
||||
|
||||
return fetchLogs(guildId, null, action);
|
||||
}
|
||||
|
||||
export function filterByUserId(userId: string, guildId: string) {
|
||||
if (isLoading()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.AUDIT_LOG_FILTER_BY_USER,
|
||||
userId,
|
||||
});
|
||||
|
||||
return fetchLogs(guildId, userId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AuditLogActionCreators.js
|
229
509bba0_unpacked/discord_app/actions/AuthenticationActionCreators.js
Executable file
229
509bba0_unpacked/discord_app/actions/AuthenticationActionCreators.js
Executable file
|
@ -0,0 +1,229 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
import RouterUtils from '../utils/RouterUtils';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import Storage from '../lib/Storage';
|
||||
import i18n from '../i18n';
|
||||
import {ActionTypes, Endpoints, Routes, DEVICE_TOKEN, DEVICE_PUSH_PROVIDER} from '../Constants';
|
||||
|
||||
export default {
|
||||
startSession(token: string) {
|
||||
// This is a Flux anti-pattern. This can currently get triggered by mounting
|
||||
// a component which could have been triggered by a store event during a dispatch.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.START_SESSION,
|
||||
token,
|
||||
});
|
||||
},
|
||||
|
||||
login(email: string, password: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.LOGIN,
|
||||
body: {email, password},
|
||||
retries: 2,
|
||||
}).then(
|
||||
res => {
|
||||
if (res.body.mfa) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_MFA_STEP, ticket: res.body.ticket});
|
||||
} else {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token: res.body.token});
|
||||
}
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOGIN_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
// Extra login step for multi-factor auth'd users
|
||||
loginMFA(code: string, ticket: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_MFA});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.LOGIN_MFA,
|
||||
body: {code, ticket},
|
||||
retries: 2,
|
||||
}).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token: res.body.token}),
|
||||
res =>
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOGIN_MFA_FAILURE,
|
||||
message: res.body ? res.body.message : i18n.Messages.NETWORK_ERROR_REST_REQUEST,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
loginToken(token: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token});
|
||||
this.startSession(token);
|
||||
},
|
||||
|
||||
loginReset() {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_RESET});
|
||||
},
|
||||
|
||||
register(username: string, invite: ?string = null, captchaKey: ?string = null) {
|
||||
this.registerFull(undefined, username, undefined, invite, captchaKey);
|
||||
},
|
||||
|
||||
registerFull(email: string, username: string, password: string, invite: ?string = null, captchaKey: ?string = null) {
|
||||
Dispatcher.dispatch({type: ActionTypes.REGISTER});
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.REGISTER,
|
||||
body: {
|
||||
fingerprint: AuthenticationStore.getFingerprint(),
|
||||
email,
|
||||
username,
|
||||
password,
|
||||
invite,
|
||||
// eslint-disable-next-line camelcase
|
||||
captcha_key: captchaKey,
|
||||
},
|
||||
}).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.REGISTER_SUCCESS, token: res.body.token}),
|
||||
res => Dispatcher.dispatch({type: ActionTypes.REGISTER_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
logout() {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.LOGOUT,
|
||||
body: {
|
||||
provider: DEVICE_PUSH_PROVIDER,
|
||||
token: Storage.get(DEVICE_TOKEN),
|
||||
},
|
||||
}).then(() => Dispatcher.dispatch({type: ActionTypes.LOGOUT}));
|
||||
},
|
||||
|
||||
verify(token: string, captchaKey: ?string = null) {
|
||||
if (token != null) {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.VERIFY,
|
||||
body: {
|
||||
token,
|
||||
// eslint-disable-next-line camelcase
|
||||
captcha_key: captchaKey,
|
||||
},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token: res.body.token});
|
||||
RouterUtils.replaceWith(Routes.ME);
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.VERIFY_FAILURE, errors: res.body})
|
||||
);
|
||||
} else {
|
||||
Dispatcher.dispatch({type: ActionTypes.VERIFY_FAILURE, errors: {}});
|
||||
}
|
||||
},
|
||||
|
||||
authorizeIPAddress(token: string) {
|
||||
if (token != null) {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.AUTHORIZE_IP,
|
||||
body: {token},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.VERIFY_SUCCESS}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.VERIFY_FAILURE, errors: {}})
|
||||
);
|
||||
} else {
|
||||
Dispatcher.dispatch({type: ActionTypes.VERIFY_FAILURE, errors: {}});
|
||||
}
|
||||
},
|
||||
|
||||
verifyResend() {
|
||||
HTTPUtils.post(Endpoints.VERIFY_RESEND);
|
||||
},
|
||||
|
||||
resetPassword(token: string, password: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN});
|
||||
|
||||
const body: any = {
|
||||
token,
|
||||
password,
|
||||
};
|
||||
// Only send these values if we have them.
|
||||
const pushToken = Storage.get(DEVICE_TOKEN);
|
||||
if (DEVICE_PUSH_PROVIDER != null && pushToken != null) {
|
||||
body['push_provider'] = DEVICE_PUSH_PROVIDER;
|
||||
body['push_token'] = pushToken;
|
||||
}
|
||||
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.RESET_PASSWORD,
|
||||
body,
|
||||
}).then(
|
||||
res => {
|
||||
if (res.body.mfa) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_MFA_STEP, ticket: res.body.ticket});
|
||||
} else {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token: res.body.token});
|
||||
RouterUtils.replaceWith(Routes.ME);
|
||||
}
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOGIN_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
resetPasswordMFA(code: string, ticket: string, password: string, token: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_MFA});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.RESET_PASSWORD,
|
||||
body: {code, ticket, password, token},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN_SUCCESS, token: res.body.token});
|
||||
RouterUtils.replaceWith(Routes.ME);
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOGIN_MFA_FAILURE, message: res.body.message})
|
||||
);
|
||||
},
|
||||
|
||||
forgotPassword(email: string, callback: () => void) {
|
||||
Dispatcher.dispatch({type: ActionTypes.LOGIN});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.FORGOT_PASSWORD,
|
||||
body: {email},
|
||||
}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.FORGOT_PASSWORD_SENT});
|
||||
callback && callback();
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOGIN_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fingerprint a user based on the location they are currently viewing.
|
||||
*
|
||||
* If the user is already registered or been previously fingerprinted
|
||||
* then those tokens are returned.
|
||||
*/
|
||||
fingerprint(location: string): Promise<?string> {
|
||||
const fingerprint = AuthenticationStore.getFingerprint() || AuthenticationStore.getToken();
|
||||
if (fingerprint != null) {
|
||||
return Promise.resolve(fingerprint);
|
||||
}
|
||||
|
||||
return HTTPUtils.get({
|
||||
url: Endpoints.EXPERIMENTS,
|
||||
context: {
|
||||
location,
|
||||
},
|
||||
retries: 3,
|
||||
}).then(
|
||||
res => {
|
||||
const fingerprint = res.body.fingerprint;
|
||||
Dispatcher.dispatch({type: ActionTypes.FINGERPRINT, token: fingerprint});
|
||||
return fingerprint;
|
||||
},
|
||||
// Better to return null then to stop user from registering.
|
||||
// This request already retries.
|
||||
() => null
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AuthenticationActionCreators.js
|
25
509bba0_unpacked/discord_app/actions/AuthorizedAppsActionCreators.js
Executable file
25
509bba0_unpacked/discord_app/actions/AuthorizedAppsActionCreators.js
Executable file
|
@ -0,0 +1,25 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
fetch() {
|
||||
HTTPUtils.get(Endpoints.OAUTH2_TOKENS).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.USER_AUTHORIZED_APPS_UPDATE, apps: res.body}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.USER_AUTHORIZED_APPS_UPDATE, apps: []})
|
||||
);
|
||||
},
|
||||
|
||||
delete(id: string) {
|
||||
HTTPUtils.delete(Endpoints.OAUTH2_TOKEN(id)).then(() => {
|
||||
this.fetch();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/AuthorizedAppsActionCreators.js
|
284
509bba0_unpacked/discord_app/actions/BillingActionCreators.js
Executable file
284
509bba0_unpacked/discord_app/actions/BillingActionCreators.js
Executable file
|
@ -0,0 +1,284 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {ensureStripeIsLoaded} from '../utils/StripeUtils';
|
||||
import {
|
||||
ActionTypes,
|
||||
Endpoints,
|
||||
PaymentSettings,
|
||||
PremiumPlans,
|
||||
PremiumStatusTypes,
|
||||
PaymentModelModes,
|
||||
} from '../Constants';
|
||||
import AlertActionCreators from './AlertActionCreators';
|
||||
import i18n from '../i18n';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
|
||||
export type CardInfo = {
|
||||
number: string,
|
||||
exp: string,
|
||||
cvc: string,
|
||||
addressZip: string,
|
||||
};
|
||||
|
||||
type SubscribeModes = 'NEW' | 'RESUBSCRIBE';
|
||||
|
||||
export function getBillingInfo() {
|
||||
return Promise.all([
|
||||
HTTPUtils.get({url: Endpoints.BILLING}).then(response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.BILLING_SYNC_PROFILE_SUCCESS,
|
||||
profile: response.body,
|
||||
});
|
||||
}),
|
||||
HTTPUtils.get({url: Endpoints.BILLING_HISTORY}).then(response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.BILLING_SYNC_HISTORY_SUCCESS,
|
||||
history: response.body,
|
||||
});
|
||||
}),
|
||||
]).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.BILLING_SYNC_SUCCESS}),
|
||||
response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.BILLING_SYNC_ERROR,
|
||||
errors: response.body,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function unsubscribe() {
|
||||
return HTTPUtils.delete({
|
||||
url: Endpoints.BILLING_PREMIUM_SUBSCRIPTION,
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE}),
|
||||
response => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
return Promise.reject(response.body);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function subscribe(mode: SubscribeModes, token: ?string, plan: string = PremiumPlans.MONTHLY) {
|
||||
const props = {
|
||||
url: Endpoints.BILLING_PREMIUM_SUBSCRIPTION,
|
||||
body: {},
|
||||
};
|
||||
let method;
|
||||
|
||||
// New subscription
|
||||
if (mode === PaymentModelModes.NEW) {
|
||||
method = 'put';
|
||||
props.body = {
|
||||
token,
|
||||
// eslint-disable-next-line camelcase
|
||||
payment_gateway: PaymentSettings.STRIPE.PAYMENT_GATEWAY,
|
||||
plan,
|
||||
};
|
||||
} else {
|
||||
// Resubscribing a canceled subscription, may or may not have a token
|
||||
method = 'patch';
|
||||
props.body = {
|
||||
status: PremiumStatusTypes.ACTIVE,
|
||||
token,
|
||||
};
|
||||
}
|
||||
const event = mode === PaymentModelModes.NEW ? 'premium_purchase_completed' : 'premium_resubscribed';
|
||||
return HTTPUtils[method](props).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
Dispatcher.dispatch({type: ActionTypes.PAYMENT_UPDATE_SUCCESS});
|
||||
Dispatcher.dispatch({type: ActionTypes.SUBSCRIBE_SUCCESS});
|
||||
AnalyticsUtils.track(event, {success: true, plan});
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_UPDATE_FAILURE,
|
||||
error: res.body,
|
||||
});
|
||||
AnalyticsUtils.track(event, {
|
||||
success: false,
|
||||
// eslint-disable-next-line camelcase
|
||||
error_code: res.body.message,
|
||||
plan,
|
||||
});
|
||||
return Promise.reject(res.body);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function changeCard(token) {
|
||||
return HTTPUtils.put({
|
||||
url: Endpoints.BILLING_PAYMENT_SOURCE,
|
||||
body: {
|
||||
// eslint-disable-next-line camelcase
|
||||
payment_gateway: PaymentSettings.STRIPE.PAYMENT_GATEWAY,
|
||||
token,
|
||||
},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.PAYMENT_UPDATE_SUCCESS}),
|
||||
response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_UPDATE_FAILURE,
|
||||
error: response.body,
|
||||
});
|
||||
return Promise.reject(response.body);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function upgrade(plan) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.BILLING_PREMIUM_SUBSCRIPTION,
|
||||
body: {
|
||||
// eslint-disable-next-line camelcase
|
||||
payment_gateway: PaymentSettings.STRIPE.PAYMENT_GATEWAY,
|
||||
plan,
|
||||
},
|
||||
}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
AnalyticsUtils.track('premium_upgrade_completed', {
|
||||
success: true,
|
||||
plan,
|
||||
});
|
||||
},
|
||||
response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_UPDATE_FAILURE,
|
||||
error: response.body,
|
||||
});
|
||||
AnalyticsUtils.track('premium_upgrade_completed', {
|
||||
success: false,
|
||||
plan,
|
||||
// eslint-disable-next-line camelcase
|
||||
error_code: response.body.message,
|
||||
});
|
||||
return Promise.reject(response.body);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getStripeToken({number, exp, cvc, addressZip}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ensureStripeIsLoaded().then(Stripe => {
|
||||
Dispatcher.dispatch({type: ActionTypes.PAYMENT_PROCESSING});
|
||||
|
||||
Stripe.card.createToken(
|
||||
{
|
||||
number,
|
||||
cvc,
|
||||
exp,
|
||||
// eslint-disable-next-line camelcase
|
||||
address_zip: addressZip,
|
||||
},
|
||||
(response, body) => {
|
||||
if (response !== 200 || !body || !body.id) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.STRIPE_TOKEN_FAILURE,
|
||||
error: body ? body.error : null,
|
||||
});
|
||||
reject(body);
|
||||
} else {
|
||||
resolve(body);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
subscribe(cardInfo: CardInfo, mode: SubscribeModes = PaymentModelModes.NEW, plan: string = PremiumPlans.MONTHLY) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getStripeToken(cardInfo).then(
|
||||
response => subscribe(mode, response.id, plan).then(resolve, reject),
|
||||
response => {
|
||||
AnalyticsUtils.track('premium_purchase_completed', {
|
||||
success: false,
|
||||
// eslint-disable-next-line camelcase
|
||||
error_code: `${response.error.type}:${response.error.code}`,
|
||||
plan,
|
||||
});
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
reject(response);
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
// Only useable if there already is a payment source, subscribe should be
|
||||
// used if adding a payment source as well, even for re-subscribe
|
||||
resubscribe() {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE});
|
||||
return subscribe(PaymentModelModes.RESUBSCRIBE);
|
||||
},
|
||||
|
||||
unsubscribe(body: ?string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
AlertActionCreators.show({
|
||||
body: body || i18n.Messages.PREMIUM_CANCEL_CONFIRM_BODY,
|
||||
confirmText: i18n.Messages.PREMIUM_CANCEL_CONFIRM,
|
||||
cancelText: i18n.Messages.PREMIUM_CANCEL_CANCEL,
|
||||
onConfirm: () => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE});
|
||||
return unsubscribe().then(resolve).catch(body => {
|
||||
AlertActionCreators.show({body: i18n.Messages.PREMIUM_CANCEL_FAILED_BODY});
|
||||
reject(body);
|
||||
});
|
||||
},
|
||||
onCancel: () => reject(),
|
||||
className: 'premium-unsubscribe',
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
upgrade(plan: string = PremiumPlans.YEARLY, body: ?string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
AlertActionCreators.show({
|
||||
body: body || i18n.Messages.PREMIUM_UPGRADE_CONFIRM_BODY,
|
||||
confirmText: i18n.Messages.PREMIUM_UPGRADE_CONFIRM,
|
||||
cancelText: i18n.Messages.PREMIUM_UPGRADE_CANCEL,
|
||||
onConfirm: () =>
|
||||
upgrade(plan).then(resolve).catch(body => {
|
||||
AlertActionCreators.show({body: i18n.Messages.PREMIUM_UPGRADE_FAILED_BODY});
|
||||
reject(body);
|
||||
}),
|
||||
onCancel: () => reject(),
|
||||
className: 'premium-upgrade',
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
changeCard(cardInfo: CardInfo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getStripeToken(cardInfo).then(response => changeCard(response.id).then(resolve, reject), reject);
|
||||
});
|
||||
},
|
||||
|
||||
removeCard() {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE});
|
||||
return HTTPUtils.delete({url: Endpoints.BILLING_PAYMENT_SOURCE}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE});
|
||||
return AnalyticsUtils.track('premium_cc_removed');
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.BILLING_INFO_UPDATE_COMPLETE})
|
||||
);
|
||||
},
|
||||
|
||||
getBillingInfo() {
|
||||
// getBillingInfo can be executed during a dispatch - since it gets called
|
||||
// when the settings modal mounts
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.BILLING_SYNC});
|
||||
return getBillingInfo();
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/BillingActionCreators.js
|
34
509bba0_unpacked/discord_app/actions/CallActionCreators.js
Executable file
34
509bba0_unpacked/discord_app/actions/CallActionCreators.js
Executable file
|
@ -0,0 +1,34 @@
|
|||
/* @flow */
|
||||
|
||||
import CallStore from '../stores/CallStore';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {Endpoints} from '../Constants';
|
||||
|
||||
export default {
|
||||
_getCallContext(channelId: string): {message_id: ?string} {
|
||||
return {
|
||||
message_id: CallStore.getMessageId(channelId), // eslint-disable-line camelcase
|
||||
};
|
||||
},
|
||||
|
||||
ring(channelId: string, recipients?: Array<string>): Promise {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.CALL_RING(channelId),
|
||||
body: {recipients},
|
||||
context: this._getCallContext(channelId),
|
||||
});
|
||||
},
|
||||
|
||||
stopRinging(channelId: string, recipients?: Array<string>): Promise {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.CALL_STOP_RINGING(channelId),
|
||||
body: {recipients},
|
||||
context: this._getCallContext(channelId),
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/CallActionCreators.js
|
23
509bba0_unpacked/discord_app/actions/ChangeLogActionCreators.js
Executable file
23
509bba0_unpacked/discord_app/actions/ChangeLogActionCreators.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
showChangeLog() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_LOG_OPEN,
|
||||
});
|
||||
},
|
||||
|
||||
hideChangeLog() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_LOG_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChangeLogActionCreators.js
|
35
509bba0_unpacked/discord_app/actions/ChangeNicknameActionCreators.js
Executable file
35
509bba0_unpacked/discord_app/actions/ChangeNicknameActionCreators.js
Executable file
|
@ -0,0 +1,35 @@
|
|||
/* @flow */
|
||||
|
||||
import {Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import i18n from '../i18n';
|
||||
import MessageActionCreators from './MessageActionCreators';
|
||||
|
||||
export default {
|
||||
changeNickname(guildId: string, channelId: string, userId: string, nick: string): Promise {
|
||||
return HTTPUtils.patch({
|
||||
url: `${Endpoints.GUILD_MEMBERS(guildId)}/${userId}/nick`,
|
||||
body: {nick},
|
||||
}).then(
|
||||
res => {
|
||||
nick = res.body.nick;
|
||||
MessageActionCreators.sendBotMessage(
|
||||
channelId,
|
||||
nick ? i18n.Messages.COMMAND_NICK_SUCCESS.plainFormat({nick}) : i18n.Messages.COMMAND_NICK_RESET
|
||||
);
|
||||
},
|
||||
res => {
|
||||
if (res.status === 403) {
|
||||
MessageActionCreators.sendBotMessage(channelId, i18n.Messages.COMMAND_NICK_FAILURE_PERMISSION.plainFormat());
|
||||
} else {
|
||||
MessageActionCreators.sendBotMessage(channelId, i18n.Messages.COMMAND_NICK_FAILURE);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChangeNicknameActionCreators.js
|
48
509bba0_unpacked/discord_app/actions/ChangeNicknameModalActionCreators.js
Executable file
48
509bba0_unpacked/discord_app/actions/ChangeNicknameModalActionCreators.js
Executable file
|
@ -0,0 +1,48 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, ME} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
|
||||
export default {
|
||||
open(guildId: string, userId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_NICKNAME_MODAL_OPEN,
|
||||
guildId,
|
||||
userId,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_NICKNAME_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
changeNickname(guildId: string, userId: string, nick: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_NICKNAME_MODAL_SUBMIT,
|
||||
});
|
||||
let url;
|
||||
if (AuthenticationStore.getId() === userId) {
|
||||
url = `${Endpoints.GUILD_MEMBERS(guildId)}/${ME}/nick`;
|
||||
} else {
|
||||
url = `${Endpoints.GUILD_MEMBERS(guildId)}/${userId}`;
|
||||
}
|
||||
HTTPUtils.patch({url, body: {nick}}).then(
|
||||
() => this.close(),
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_NICKNAME_MODAL_SUBMIT_FAILURE,
|
||||
errors: res.body || {},
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChangeNicknameModalActionCreators.js
|
90
509bba0_unpacked/discord_app/actions/ChangeVanityURLActionCreators.js
Executable file
90
509bba0_unpacked/discord_app/actions/ChangeVanityURLActionCreators.js
Executable file
|
@ -0,0 +1,90 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
openModal(guildId: string, code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_VANITY_URL_MODAL_OPEN,
|
||||
guildId,
|
||||
code,
|
||||
});
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_VANITY_URL_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
removeVanityURL(guildId: string) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_VANITY_URL(guildId),
|
||||
body: {
|
||||
code: null,
|
||||
},
|
||||
}).then(() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_VANITY_URL,
|
||||
code: null,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Deprecated: This is used for the old settings modal and should not be used anymore
|
||||
// Use `setVanityURL` instead
|
||||
changeVanityURL(guildId: string, code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_VANITY_URL_MODAL_SUBMIT,
|
||||
});
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_VANITY_URL(guildId),
|
||||
body: {
|
||||
code,
|
||||
},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_VANITY_URL,
|
||||
code: res.body.code,
|
||||
});
|
||||
this.closeModal();
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_VANITY_URL_MODAL_SUBMIT_FAILURE,
|
||||
hasError: true,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
setVanityURL(guildId: string, code: string) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_VANITY_URL(guildId),
|
||||
body: {
|
||||
code,
|
||||
},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_VANITY_URL,
|
||||
code: res.body.code,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANGE_VANITY_URL_MODAL_SUBMIT_FAILURE,
|
||||
hasError: true,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChangeVanityURLActionCreators.js
|
165
509bba0_unpacked/discord_app/actions/ChannelActionCreators.js
Executable file
165
509bba0_unpacked/discord_app/actions/ChannelActionCreators.js
Executable file
|
@ -0,0 +1,165 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import RouterUtils from '../utils/RouterUtils';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import ChannelStore from '../stores/ChannelStore';
|
||||
import SelectedChannelActionCreators from '../actions/SelectedChannelActionCreators';
|
||||
import CallActionCreators from '../actions/CallActionCreators';
|
||||
import {ActionTypes, Endpoints, ME, Routes} from '../Constants';
|
||||
import type {Channel} from '../flow/Server';
|
||||
|
||||
type OverwriteType = {
|
||||
id: string,
|
||||
type: string,
|
||||
allow: number,
|
||||
deny: number,
|
||||
};
|
||||
|
||||
export default {
|
||||
openPrivateChannel(userId: string, recipientIds?: Array<string> | string, joinCall: boolean = false) {
|
||||
const joinCallIfRequested = channelId => {
|
||||
if (joinCall) {
|
||||
SelectedChannelActionCreators.selectVoiceChannel(null, channelId);
|
||||
CallActionCreators.ring(channelId);
|
||||
}
|
||||
};
|
||||
|
||||
// If we are are trying to open a DM, let's see if the client already knows about that channel,
|
||||
// so we don't have to wait for the network call to navigate.
|
||||
if (recipientIds != null && recipientIds.length == 1) {
|
||||
const channelId = this._openCachedDMChannel(recipientIds[0]);
|
||||
if (channelId != null) {
|
||||
joinCallIfRequested(channelId);
|
||||
return Promise.resolve(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
const recipients = this._getRecipients(recipientIds);
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.USER_CHANNELS(userId),
|
||||
body: {recipients},
|
||||
}).then(res => {
|
||||
this._openPrivateChannel(res.body);
|
||||
joinCallIfRequested(res.body.id);
|
||||
return res.body.id;
|
||||
});
|
||||
},
|
||||
|
||||
_openCachedDMChannel(recipientId: string): ?string {
|
||||
const channelId = ChannelStore.getDMFromUserId(recipientId);
|
||||
const channel = channelId != null ? ChannelStore.getChannel(channelId) : null;
|
||||
if (channel) {
|
||||
SelectedChannelActionCreators.selectPrivateChannel(channel.id);
|
||||
return channel.id;
|
||||
}
|
||||
},
|
||||
|
||||
ensurePrivateChannel(userId: string, recipientIds?: Array<string> | string): Promise<string> {
|
||||
const recipients = this._getRecipients(recipientIds);
|
||||
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.USER_CHANNELS(userId),
|
||||
body: {recipients},
|
||||
}).then(res => {
|
||||
const channel = res.body;
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_CREATE, channel});
|
||||
return channel.id;
|
||||
});
|
||||
},
|
||||
|
||||
_getRecipients(recipientIds?: Array<string> | string): Array<string> {
|
||||
if (recipientIds != null) {
|
||||
return Array.isArray(recipientIds) ? recipientIds : [recipientIds];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
_openPrivateChannel(channel: Channel) {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_CREATE, channel});
|
||||
SelectedChannelActionCreators.selectPrivateChannel(channel.id);
|
||||
},
|
||||
|
||||
closePrivateChannel(channelId: string, unselect: boolean = false) {
|
||||
// TODO: do something better if an error happens
|
||||
HTTPUtils.delete(`${Endpoints.CHANNELS}/${channelId}`);
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_DELETE,
|
||||
channel: {
|
||||
id: channelId,
|
||||
// eslint-disable-next-line camelcase
|
||||
guild_id: null,
|
||||
},
|
||||
});
|
||||
if (unselect) {
|
||||
if (__WEB__) {
|
||||
RouterUtils.transitionTo(Routes.FRIENDS);
|
||||
} else {
|
||||
SelectedChannelActionCreators.selectChannel(ME, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// FIXME: remove fromNewSettings when settings modals are removed
|
||||
updatePermissionOverwrite(channelId: string, overwrite: OverwriteType, fromNewSettings: boolean = false) {
|
||||
// eslint-disable-next-line camelcase
|
||||
const query = fromNewSettings ? {_is_new_settings_screen: true} : {};
|
||||
return HTTPUtils.put({
|
||||
url: `${Endpoints.CHANNEL_PERMISSIONS(channelId)}/${overwrite.id}`,
|
||||
body: overwrite,
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
||||
clearPermissionOverwrite(channelId: string, overwriteId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.CHANNEL_PERMISSIONS(channelId)}/${overwriteId}`);
|
||||
},
|
||||
|
||||
// Group DM
|
||||
|
||||
addRecipient(channelId: string, userId: string) {
|
||||
return HTTPUtils.put(`${Endpoints.CHANNEL_RECIPIENTS(channelId)}/${userId}`).then(res => {
|
||||
if (res.status === 201 /* CREATED */) {
|
||||
this._openPrivateChannel(res.body);
|
||||
return res.body.id;
|
||||
} else {
|
||||
return channelId;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addRecipients(channelId: string, userIds: Array<string>) {
|
||||
return this.addRecipient(channelId, userIds[0]).then(channelId => {
|
||||
return Promise.all(userIds.slice(1).map(userId => this.addRecipient(channelId, userId))).then(() => channelId);
|
||||
});
|
||||
},
|
||||
|
||||
removeRecipient(channelId: string, userId: string) {
|
||||
return HTTPUtils.delete(`${Endpoints.CHANNEL_RECIPIENTS(channelId)}/${userId}`);
|
||||
},
|
||||
|
||||
setName(channelId: string, name: string) {
|
||||
HTTPUtils.patch({
|
||||
url: `${Endpoints.CHANNELS}/${channelId}`,
|
||||
body: {name},
|
||||
});
|
||||
},
|
||||
|
||||
setIcon(channelId: string, icon: ?string) {
|
||||
HTTPUtils.patch({
|
||||
url: `${Endpoints.CHANNELS}/${channelId}`,
|
||||
body: {icon},
|
||||
});
|
||||
},
|
||||
|
||||
convertToGuild(channelId: string): Promise {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.CHANNEL_CONVERT(channelId),
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelActionCreators.js
|
22
509bba0_unpacked/discord_app/actions/ChannelCollapseActionCreators.js
Executable file
22
509bba0_unpacked/discord_app/actions/ChannelCollapseActionCreators.js
Executable file
|
@ -0,0 +1,22 @@
|
|||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
update(channelId) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_COLLAPSE,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
updateMuted() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_COLLAPSE_MUTED,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelCollapseActionCreators.js
|
30
509bba0_unpacked/discord_app/actions/ChannelNoticeActionCreators.js
Executable file
30
509bba0_unpacked/discord_app/actions/ChannelNoticeActionCreators.js
Executable file
|
@ -0,0 +1,30 @@
|
|||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import GuildRecord from '../records/GuildRecord';
|
||||
|
||||
export function showNotice(noticeType, guild: GuildRecord) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.CHANNEL_NOTICE_SHOW,
|
||||
noticeType,
|
||||
guild,
|
||||
});
|
||||
}
|
||||
|
||||
export function hideNotice(noticeType) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.CHANNEL_NOTICE_HIDE,
|
||||
noticeType,
|
||||
});
|
||||
}
|
||||
|
||||
export function handleForceCreateInvite(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_NOTICE_INVITE_FORCE_CREATE,
|
||||
guildId,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelNoticeActionCreators.js
|
91
509bba0_unpacked/discord_app/actions/ChannelPinActionCreators.js
Executable file
91
509bba0_unpacked/discord_app/actions/ChannelPinActionCreators.js
Executable file
|
@ -0,0 +1,91 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import ChannelPinsStore from '../stores/ChannelPinsStore';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import i18n from '../i18n';
|
||||
import ChannelRecord from '../records/ChannelRecord';
|
||||
import AlertActionCreators from '../actions/AlertActionCreators';
|
||||
import {ActionTypes, Endpoints, MAX_PINS_PER_CHANNEL} from '../Constants';
|
||||
|
||||
export default {
|
||||
pinMessage(channel: ChannelRecord, messageId: string) {
|
||||
const {id: channelId, name} = channel;
|
||||
|
||||
HTTPUtils.put({
|
||||
url: Endpoints.PIN(channelId, messageId),
|
||||
}).catch(() => {
|
||||
let body;
|
||||
if (channel.isPrivate()) {
|
||||
body = i18n.Messages.PIN_MESSAGE_TOO_MANY_BODY_PRIVATE_CHANNEL.format({maxPins: MAX_PINS_PER_CHANNEL});
|
||||
} else {
|
||||
body = i18n.Messages.PIN_MESSAGE_TOO_MANY_BODY.format({maxPins: MAX_PINS_PER_CHANNEL, channelName: name});
|
||||
}
|
||||
|
||||
AlertActionCreators.show({
|
||||
title: i18n.Messages.PIN_MESSAGE_TOO_MANY_TITLE,
|
||||
body,
|
||||
confirmText: i18n.Messages.OKAY,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
unpinMessage(channel: ChannelRecord, messageId: string) {
|
||||
HTTPUtils.delete({
|
||||
url: Endpoints.PIN(channel.id, messageId),
|
||||
}).catch(() =>
|
||||
AlertActionCreators.show({
|
||||
title: i18n.Messages.UNPIN_MESSAGE_FAILED_TITLE,
|
||||
body: i18n.Messages.UNPIN_MESSAGE_FAILED_BODY,
|
||||
confirmText: i18n.Messages.TRY_AGAIN,
|
||||
cancelText: i18n.Messages.CANCEL,
|
||||
onConfirm: this.unpinMessage.bind(this, channel, messageId),
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
ackPins(channelId: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.CHANNEL_PINS_ACK,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
fetchPins(channelId: string) {
|
||||
const pins = ChannelPinsStore.getPinnedMessages(channelId);
|
||||
if (pins && (pins.loaded || pins.loading)) {
|
||||
// we got all pins once, so that means we will be updating with deltas as they happen.
|
||||
// don't need to fetch them all again.
|
||||
return;
|
||||
}
|
||||
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LOAD_PINNED_MESSAGES,
|
||||
channelId,
|
||||
});
|
||||
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.PINS(channelId),
|
||||
retries: 2,
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_PINNED_MESSAGES_SUCCESS,
|
||||
messages: res.body,
|
||||
channelId: channelId,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_PINNED_MESSAGES_FAILURE,
|
||||
channelId: channelId,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelPinActionCreators.js
|
18
509bba0_unpacked/discord_app/actions/ChannelSectionActionCreators.js
Executable file
18
509bba0_unpacked/discord_app/actions/ChannelSectionActionCreators.js
Executable file
|
@ -0,0 +1,18 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
toggleSection(section: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_TOGGLE_SECTION,
|
||||
section,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelSectionActionCreators.js
|
101
509bba0_unpacked/discord_app/actions/ChannelSettingsActionCreators.js
Executable file
101
509bba0_unpacked/discord_app/actions/ChannelSettingsActionCreators.js
Executable file
|
@ -0,0 +1,101 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {pushLayer} from './LayerActionCreators';
|
||||
import {ActionTypes, Endpoints, Layers} from '../Constants';
|
||||
|
||||
type ChannelSettingsObject = {
|
||||
name?: string,
|
||||
position?: string,
|
||||
topic?: string,
|
||||
bitrate?: number,
|
||||
userLimit?: number,
|
||||
};
|
||||
|
||||
export function init(channelId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_INIT,
|
||||
channelId,
|
||||
});
|
||||
}
|
||||
|
||||
export function open(channelId: string) {
|
||||
if (__IOS__) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_OPEN,
|
||||
channelId,
|
||||
});
|
||||
} else {
|
||||
init(channelId);
|
||||
pushLayer(Layers.CHANNEL_SETTINGS);
|
||||
}
|
||||
}
|
||||
|
||||
export function close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_CLOSE,
|
||||
});
|
||||
}
|
||||
|
||||
export function setSection(section: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_SET_SECTION,
|
||||
section,
|
||||
});
|
||||
}
|
||||
|
||||
export function selectPermissionOverwrite(overwriteId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_OVERWRITE_SELECT,
|
||||
overwriteId,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateChannel({name, topic, bitrate, userLimit}: ChannelSettingsObject) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_UPDATE,
|
||||
name,
|
||||
topic,
|
||||
bitrate,
|
||||
userLimit,
|
||||
});
|
||||
}
|
||||
|
||||
export function saveChannel(channelId: string, {name, position, topic, bitrate, userLimit}: ChannelSettingsObject) {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_SUBMIT});
|
||||
return HTTPUtils.patch({
|
||||
url: `${Endpoints.CHANNELS}/${channelId}`,
|
||||
// eslint-disable-next-line camelcase
|
||||
body: {name, position, topic, bitrate, user_limit: userLimit},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_SUBMIT_SUCCESS, channelId});
|
||||
return res;
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_SUBMIT_FAILURE, errors: res.body});
|
||||
return res;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function deleteChannel(channelId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.CHANNELS}/${channelId}`).then(() => close());
|
||||
}
|
||||
|
||||
export default {
|
||||
init,
|
||||
open,
|
||||
close,
|
||||
setSection,
|
||||
selectPermissionOverwrite,
|
||||
updateChannel,
|
||||
saveChannel,
|
||||
deleteChannel,
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelSettingsActionCreators.js
|
|
@ -0,0 +1,55 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import ChannelActionCreators from './ChannelActionCreators';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export function updatePermission(id: string, allow: number, deny: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_PERMISSIONS_UPDATE_PERMISSION,
|
||||
id,
|
||||
allow,
|
||||
deny,
|
||||
});
|
||||
}
|
||||
|
||||
export function selectPermission(id: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_SETTINGS_PERMISSIONS_SELECT_PERMISSION,
|
||||
id,
|
||||
});
|
||||
}
|
||||
|
||||
export function init() {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_PERMISSIONS_INIT});
|
||||
}
|
||||
|
||||
type OverwriteType = {
|
||||
id: string,
|
||||
type: string,
|
||||
allow: number,
|
||||
deny: number,
|
||||
};
|
||||
|
||||
export function savePermissionUpdates(channelId: string, overwrites: Array<OverwriteType>) {
|
||||
Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_PERMISSIONS_SUBMITTING});
|
||||
return new Promise(resolve => {
|
||||
const chain = () => {
|
||||
if (overwrites.length === 0) {
|
||||
return resolve();
|
||||
}
|
||||
const overwrite = overwrites.pop();
|
||||
if (overwrite == null) {
|
||||
return chain();
|
||||
}
|
||||
ChannelActionCreators.updatePermissionOverwrite(channelId, overwrite, true).then(chain, chain);
|
||||
};
|
||||
|
||||
chain();
|
||||
}).then(() => Dispatcher.dispatch({type: ActionTypes.CHANNEL_SETTINGS_PERMISSIONS_SAVE_SUCCESS}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ChannelSettingsPermissionsActionCreators.js
|
80
509bba0_unpacked/discord_app/actions/ConnectedAccountsActionCreators.js
Executable file
80
509bba0_unpacked/discord_app/actions/ConnectedAccountsActionCreators.js
Executable file
|
@ -0,0 +1,80 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, UNSAFE_PLATFORM_TYPES} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
fetch() {
|
||||
HTTPUtils.get(Endpoints.CONNECTIONS).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.USER_CONNECTIONS_UPDATE, local: true, accounts: res.body}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.USER_CONNECTIONS_UPDATE, local: true, accounts: []})
|
||||
);
|
||||
},
|
||||
|
||||
authorize(platformType: string) {
|
||||
return HTTPUtils.get(Endpoints.CONNECTIONS_AUTHORIZE(platformType));
|
||||
},
|
||||
|
||||
callback(
|
||||
platformType: string,
|
||||
body: {code: string, openid_params: Object, state: string},
|
||||
insecure: boolean = false
|
||||
) {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.CONNECTIONS_CALLBACK(platformType),
|
||||
body: {...body, insecure},
|
||||
});
|
||||
},
|
||||
|
||||
connect(platformType: string, accountId: string, name: string, location?: string) {
|
||||
HTTPUtils.put({
|
||||
url: Endpoints.CONNECTION(platformType, encodeURIComponent(accountId)),
|
||||
body: {
|
||||
name,
|
||||
friend_sync: UNSAFE_PLATFORM_TYPES.has(platformType), // eslint-disable-line camelcase
|
||||
},
|
||||
context: {location},
|
||||
});
|
||||
},
|
||||
|
||||
disconnect(platformType: string, accountId: string) {
|
||||
HTTPUtils.delete(Endpoints.CONNECTION(platformType, encodeURIComponent(accountId)));
|
||||
},
|
||||
|
||||
setVisibility(platformType: string, id: string, visibility: number): Promise {
|
||||
return this.update(platformType, id, {visibility});
|
||||
},
|
||||
|
||||
setFriendSync(platformType: string, id: string, friendSync: boolean): Promise {
|
||||
return this.update(platformType, id, {friend_sync: friendSync}); // eslint-disable-line camelcase
|
||||
},
|
||||
|
||||
update(platformType: string, accountId: string, body: {visibility?: boolean, friend_sync?: boolean}): Promise {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.CONNECTION(platformType, encodeURIComponent(accountId)),
|
||||
body,
|
||||
});
|
||||
},
|
||||
|
||||
joinServer(integrationId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_CONNECTIONS_INTEGRATION_JOINING,
|
||||
integrationId,
|
||||
joining: true,
|
||||
});
|
||||
|
||||
HTTPUtils.post(Endpoints.INTEGRATIONS_JOIN(integrationId), () => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_CONNECTIONS_INTEGRATION_JOINING,
|
||||
integrationId,
|
||||
joining: false,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ConnectedAccountsActionCreators.js
|
25
509bba0_unpacked/discord_app/actions/ContextMenuActionCreators.js
Executable file
25
509bba0_unpacked/discord_app/actions/ContextMenuActionCreators.js
Executable file
|
@ -0,0 +1,25 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import type {ContextMenuProps} from '../flow/Client';
|
||||
|
||||
export default {
|
||||
open(contextMenu: ContextMenuProps) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CONTEXT_MENU_OPEN,
|
||||
contextMenu,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CONTEXT_MENU_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ContextMenuActionCreators.js
|
65
509bba0_unpacked/discord_app/actions/CreateChannelModalActionCreators.js
Executable file
65
509bba0_unpacked/discord_app/actions/CreateChannelModalActionCreators.js
Executable file
|
@ -0,0 +1,65 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, BITRATE_DEFAULT} from '../Constants';
|
||||
import type {PermissionOverwrite} from '../records/ChannelRecord';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
open(channelId: ?string, channelType: ?number, guildId: ?string, cloneChannelId: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_CHANNEL_MODAL_OPEN,
|
||||
channelId,
|
||||
channelType,
|
||||
guildId,
|
||||
cloneChannelId,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_CHANNEL_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
createChannel(
|
||||
guildId: string,
|
||||
type: number,
|
||||
name: string,
|
||||
permissionOverwrites: Array<PermissionOverwrite> = [],
|
||||
bitrate: ?number,
|
||||
userLimit: ?number
|
||||
) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_CHANNEL_MODAL_SUBMIT,
|
||||
});
|
||||
|
||||
const body: any = {
|
||||
type,
|
||||
name,
|
||||
// eslint-disable-next-line camelcase
|
||||
permission_overwrites: permissionOverwrites,
|
||||
};
|
||||
|
||||
if (bitrate != null && bitrate !== BITRATE_DEFAULT) {
|
||||
body.bitrate = bitrate;
|
||||
}
|
||||
|
||||
if (userLimit != null && userLimit > 0) {
|
||||
body['user_limit'] = userLimit;
|
||||
}
|
||||
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILD_CHANNELS(guildId),
|
||||
body,
|
||||
}).then(
|
||||
() => this.close(),
|
||||
res => Dispatcher.dispatch({type: ActionTypes.CREATE_CHANNEL_MODAL_SUBMIT_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/CreateChannelModalActionCreators.js
|
65
509bba0_unpacked/discord_app/actions/CreateGuildModalActionCreators.js
Executable file
65
509bba0_unpacked/discord_app/actions/CreateGuildModalActionCreators.js
Executable file
|
@ -0,0 +1,65 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
|
||||
export default {
|
||||
open(screen: ?number, source: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_GUILD_MODAL_OPEN,
|
||||
screen,
|
||||
});
|
||||
|
||||
AnalyticsUtils.track('Open Modal', {
|
||||
Type: 'Create Guild',
|
||||
Source: source,
|
||||
});
|
||||
},
|
||||
|
||||
setScreen(screen: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_GUILD_MODAL_SET_SCREEN,
|
||||
screen,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_GUILD_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
join(code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.JOIN_GUILD_MODAL,
|
||||
text: code,
|
||||
});
|
||||
},
|
||||
|
||||
updateTemporaryGuild(update: {icon?: string, name?: string, region?: string}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_GUILD_MODAL_UPDATE,
|
||||
guild: update,
|
||||
});
|
||||
},
|
||||
|
||||
createGuild(name: string, region: string, icon: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CREATE_GUILD_MODAL_SUBMIT,
|
||||
});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILDS,
|
||||
body: {name, region, icon},
|
||||
}).then(
|
||||
() => this.close(),
|
||||
res => Dispatcher.dispatch({type: ActionTypes.CREATE_GUILD_MODAL_SUBMIT_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/CreateGuildModalActionCreators.js
|
33
509bba0_unpacked/discord_app/actions/DelayedSelectionActionCreators.js
Executable file
33
509bba0_unpacked/discord_app/actions/DelayedSelectionActionCreators.js
Executable file
|
@ -0,0 +1,33 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
selectGuild(guildId?: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.DELAYED_GUILD_SELECT,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
selectChannel(guildId: ?string, channelId: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.DELAYED_CHANNEL_SELECT,
|
||||
guildId,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
flushSelection(immediate?: boolean = false) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.DELAYED_SELECT_FLUSH,
|
||||
immediate,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/DelayedSelectionActionCreators.js
|
59
509bba0_unpacked/discord_app/actions/DimensionActionCreators.js
Executable file
59
509bba0_unpacked/discord_app/actions/DimensionActionCreators.js
Executable file
|
@ -0,0 +1,59 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
updateChannelDimensions(channelId: string, scrollTop: ?number, scrollHeight: ?number, offsetHeight: ?number) {
|
||||
// This is a Flux anti-pattern because you cannot dispatch
|
||||
// while the Dispatcher is dispatching, but to keep the scroll
|
||||
// in sync with the DOM we have to dispatch right after a re-render.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.UPDATE_CHANNEL_DIMENSIONS,
|
||||
channelId,
|
||||
scrollTop,
|
||||
scrollHeight,
|
||||
offsetHeight,
|
||||
});
|
||||
},
|
||||
|
||||
updateChannelListScroll(guildId: string, scrollTop: ?number) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.UPDATE_CHANNEL_LIST_DIMENSIONS,
|
||||
guildId,
|
||||
scrollTop,
|
||||
});
|
||||
},
|
||||
|
||||
channelListScrollTo(guildId: string, scrollTo: ?string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.UPDATE_CHANNEL_LIST_DIMENSIONS,
|
||||
guildId,
|
||||
scrollTo,
|
||||
});
|
||||
},
|
||||
|
||||
clearChannelListScrollTo(guildId: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.UPDATE_CHANNEL_LIST_DIMENSIONS,
|
||||
guildId,
|
||||
scrollTo: null,
|
||||
});
|
||||
},
|
||||
|
||||
clearChannelDimensions(channelId: string) {
|
||||
this.updateChannelDimensions(channelId, null, null, null);
|
||||
},
|
||||
|
||||
updateGuildListScrollTo(scrollTop: number) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.UPDATE_GUILD_LIST_DIMENSIONS,
|
||||
scrollTop,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/DimensionActionCreators.js
|
23
509bba0_unpacked/discord_app/actions/EmailVerificationModalActionCreators.js
Executable file
23
509bba0_unpacked/discord_app/actions/EmailVerificationModalActionCreators.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
open() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EMAIL_VERIFICATION_MODAL_OPEN,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EMAIL_VERIFICATION_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/EmailVerificationModalActionCreators.js
|
64
509bba0_unpacked/discord_app/actions/EmojiActionCreators.js
Executable file
64
509bba0_unpacked/discord_app/actions/EmojiActionCreators.js
Executable file
|
@ -0,0 +1,64 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
|
||||
export default {
|
||||
setDiversityColor(color: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EMOJI_DIVERSITY_COLOR_CHANGE,
|
||||
color,
|
||||
});
|
||||
},
|
||||
|
||||
fetchEmoji(guildId: string) {
|
||||
Dispatcher.maybeDispatch({type: ActionTypes.EMOJI_FETCH, guildId});
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.GUILD_EMOJIS(guildId),
|
||||
}).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.EMOJI_FETCH_SUCCESS, guildId, emojis: res.body}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.EMOJI_FETCH_FAILURE, guildId})
|
||||
);
|
||||
},
|
||||
|
||||
uploadEmoji(guildId: string, image: string, name: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EMOJI_UPLOAD_START,
|
||||
guildId,
|
||||
});
|
||||
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILD_EMOJIS(guildId),
|
||||
body: {
|
||||
image,
|
||||
name,
|
||||
},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.EMOJI_UPLOAD_STOP, guildId}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.EMOJI_UPLOAD_STOP, guildId})
|
||||
);
|
||||
},
|
||||
|
||||
deleteEmoji(guildId: string, emojiId: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.EMOJI_DELETE, guildId, emojiId});
|
||||
|
||||
HTTPUtils.delete({
|
||||
url: Endpoints.GUILD_EMOJI(guildId, emojiId),
|
||||
});
|
||||
},
|
||||
|
||||
updateEmoji(guildId: string, emojiId: string, name: string) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_EMOJI(guildId, emojiId),
|
||||
body: {
|
||||
name,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/EmojiActionCreators.js
|
66
509bba0_unpacked/discord_app/actions/ExperimentActionCreators.js
Executable file
66
509bba0_unpacked/discord_app/actions/ExperimentActionCreators.js
Executable file
|
@ -0,0 +1,66 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import type Flux from '../lib/flux';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
import type {ExperimentDescriptor, RenderFunctions} from '../flow/Client';
|
||||
|
||||
export default {
|
||||
trigger(experimentDescriptor: ExperimentDescriptor) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.EXPERIMENT_TRIGGER,
|
||||
experimentDescriptor,
|
||||
});
|
||||
},
|
||||
|
||||
register(store: Flux.Store, renderFunctions: RenderFunctions) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EXPERIMENT_REGISTER,
|
||||
store,
|
||||
renderFunctions,
|
||||
});
|
||||
},
|
||||
|
||||
overrideType(experimentId: string, experimentType: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EXPERIMENT_OVERRIDE_TYPE,
|
||||
experimentId,
|
||||
experimentType,
|
||||
});
|
||||
},
|
||||
|
||||
overrideBucket(experimentId: string, experimentBucket: ?number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.EXPERIMENT_OVERRIDE_BUCKET,
|
||||
experimentId,
|
||||
experimentBucket,
|
||||
});
|
||||
},
|
||||
|
||||
fetchExperiments() {
|
||||
const headers = {};
|
||||
const currentFingerprint = AuthenticationStore.getFingerprint();
|
||||
if (currentFingerprint) {
|
||||
headers['X-Fingerprint'] = currentFingerprint;
|
||||
}
|
||||
|
||||
return HTTPUtils.get({
|
||||
url: Endpoints.EXPERIMENTS,
|
||||
headers,
|
||||
}).then(res => {
|
||||
const {fingerprint, assignments} = res.body;
|
||||
if (fingerprint) {
|
||||
Dispatcher.dispatch({type: ActionTypes.FINGERPRINT, token: fingerprint});
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.EXPERIMENTS_FETCH_SUCCESS, experiments: assignments});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ExperimentActionCreators.js
|
23
509bba0_unpacked/discord_app/actions/FriendSuggestionActionCreators.js
Executable file
23
509bba0_unpacked/discord_app/actions/FriendSuggestionActionCreators.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {Endpoints, ActionTypes} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
fetch() {
|
||||
HTTPUtils.get(Endpoints.FRIEND_SUGGESTIONS).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOAD_FRIEND_SUGGESTIONS_SUCCESS, suggestions: res.body}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.LOAD_FRIEND_SUGGESTIONS_FAILURE})
|
||||
);
|
||||
},
|
||||
|
||||
ignore(userId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.FRIEND_SUGGESTIONS}/${userId}`);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/FriendSuggestionActionCreators.js
|
18
509bba0_unpacked/discord_app/actions/FriendsActionCreators.js
Executable file
18
509bba0_unpacked/discord_app/actions/FriendsActionCreators.js
Executable file
|
@ -0,0 +1,18 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
setSection(section: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.FRIENDS_SET_SECTION,
|
||||
section,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/FriendsActionCreators.js
|
38
509bba0_unpacked/discord_app/actions/GamesActionCreators.js
Executable file
38
509bba0_unpacked/discord_app/actions/GamesActionCreators.js
Executable file
|
@ -0,0 +1,38 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
addGame(pid: number) {
|
||||
Dispatcher.dispatch({type: ActionTypes.RUNNING_GAME_ADD_OVERRIDE, pid});
|
||||
},
|
||||
|
||||
toggleOverlay(game: Object) {
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.RUNNING_GAME_TOGGLE_OVERLAY, game});
|
||||
},
|
||||
|
||||
editName(game: Object, newName: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.RUNNING_GAME_EDIT_NAME, game, newName});
|
||||
},
|
||||
|
||||
setRunningGame(name: string) {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.USER_GAMES_START,
|
||||
body: {
|
||||
name,
|
||||
},
|
||||
retries: 3,
|
||||
});
|
||||
},
|
||||
|
||||
deleteEntry(game: Object) {
|
||||
Dispatcher.dispatch({type: ActionTypes.RUNNING_GAME_DELETE_ENTRY, game});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/GamesActionCreators.js
|
167
509bba0_unpacked/discord_app/actions/GuildActionCreators.js
Executable file
167
509bba0_unpacked/discord_app/actions/GuildActionCreators.js
Executable file
|
@ -0,0 +1,167 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, ME, Routes} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import RouterUtils from '../utils/RouterUtils';
|
||||
import type {CreatedGuild} from '../flow/Server';
|
||||
import ChannelStore from '../stores/ChannelStore';
|
||||
import SelectedChannelActionCreators from '../actions/SelectedChannelActionCreators';
|
||||
import GuildActionCreators from '../actions/GuildActionCreators';
|
||||
|
||||
export default {
|
||||
selectGuild(guildId: string, focus: boolean = false) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SELECT,
|
||||
guildId: guildId === ME ? null : guildId,
|
||||
focus,
|
||||
});
|
||||
},
|
||||
|
||||
createGuild(guild: CreatedGuild) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_CREATE,
|
||||
guild,
|
||||
});
|
||||
},
|
||||
|
||||
syncGuild(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SYNC_ADD,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
markGuildAsRead(guildId: string): Promise {
|
||||
return HTTPUtils.post(Endpoints.GUILD_ACK(guildId)).then(() =>
|
||||
Dispatcher.dispatch({type: ActionTypes.GUILD_ACK, guildId})
|
||||
);
|
||||
},
|
||||
|
||||
setServerMute(guildId: string, userId: string, mute: boolean) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_MEMBER(guildId, userId),
|
||||
body: {mute},
|
||||
});
|
||||
},
|
||||
|
||||
setServerDeaf(guildId: string, userId: string, deaf: boolean) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_MEMBER(guildId, userId),
|
||||
body: {deaf},
|
||||
});
|
||||
},
|
||||
|
||||
setChannel(guildId: string, userId: string, channelId: string) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_MEMBER(guildId, userId),
|
||||
// eslint-disable-next-line camelcase
|
||||
body: {channel_id: channelId},
|
||||
});
|
||||
},
|
||||
|
||||
kickUser(guildId: string, userId: string, reason: string) {
|
||||
return HTTPUtils.delete({url: Endpoints.GUILD_MEMBER(guildId, userId), query: {reason}});
|
||||
},
|
||||
|
||||
banUser(guildId: string, userId: string, deleteMessageForDays: string, reason: ?string) {
|
||||
const query = {'delete-message-days': deleteMessageForDays, reason};
|
||||
return HTTPUtils.put({url: Endpoints.GUILD_BAN(guildId, userId), query});
|
||||
},
|
||||
|
||||
unbanUser(guildId: string, userId: string) {
|
||||
return HTTPUtils.delete(Endpoints.GUILD_BAN(guildId, userId));
|
||||
},
|
||||
|
||||
createRole(guildId: string) {
|
||||
HTTPUtils.post(Endpoints.GUILD_ROLES(guildId));
|
||||
},
|
||||
|
||||
// FIXME: remove fromNewSettings when settings modals are removed
|
||||
updateRole(
|
||||
guildId: string,
|
||||
roleId: string,
|
||||
name: string,
|
||||
permissions: number,
|
||||
color: number,
|
||||
hoist: boolean,
|
||||
mentionable: boolean,
|
||||
fromNewSettings: boolean = false
|
||||
) {
|
||||
// eslint-disable-next-line camelcase
|
||||
const query = fromNewSettings ? {_is_new_settings_screen: true} : {};
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_ROLE(guildId, roleId),
|
||||
body: {name, permissions, color: color || 0, hoist, mentionable},
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
||||
deleteRole(guildId: string, roleId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.GUILD_ROLES(guildId)}/${roleId}`);
|
||||
},
|
||||
|
||||
batchChannelUpdate(guildId: string, channels: Array<{id: string, position: number}>) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_CHANNELS(guildId),
|
||||
body: channels,
|
||||
});
|
||||
},
|
||||
|
||||
batchRoleUpdate(guildId: string, roles: Array<{id: string, position: number}>) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_ROLES(guildId),
|
||||
body: roles,
|
||||
});
|
||||
},
|
||||
|
||||
requestMembers(guildId: string, query: string = '', limit: number = 10) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.GUILD_MEMBERS_REQUEST,
|
||||
guildId,
|
||||
query,
|
||||
limit,
|
||||
});
|
||||
},
|
||||
|
||||
move(fromIndex: number, toIndex: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_MOVE,
|
||||
fromIndex,
|
||||
toIndex,
|
||||
});
|
||||
},
|
||||
|
||||
nsfwAgree(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_NSFW_AGREE,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
nsfwDisagree(guildId: string) {
|
||||
// Attempt to punt user to the default channel if it is not NSFW.
|
||||
const defaultChannel = ChannelStore.getChannel(guildId);
|
||||
if (defaultChannel != null && !defaultChannel.isNSFW()) {
|
||||
if (__WEB__) {
|
||||
RouterUtils.transitionTo(Routes.CHANNEL(guildId, defaultChannel.id));
|
||||
} else {
|
||||
SelectedChannelActionCreators.selectChannel(guildId, defaultChannel.id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise just take user to the friends list.
|
||||
if (__WEB__) {
|
||||
RouterUtils.transitionTo(Routes.FRIENDS);
|
||||
} else {
|
||||
GuildActionCreators.selectGuild(ME);
|
||||
SelectedChannelActionCreators.selectChannel(ME, null);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/GuildActionCreators.js
|
270
509bba0_unpacked/discord_app/actions/GuildSettingsActionCreators.js
Executable file
270
509bba0_unpacked/discord_app/actions/GuildSettingsActionCreators.js
Executable file
|
@ -0,0 +1,270 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import i18n from '../i18n';
|
||||
import {ActionTypes, Endpoints, Layers} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import mfaInterceptor from '../utils/MFAInterceptionUtils';
|
||||
import {pushLayer} from './LayerActionCreators';
|
||||
|
||||
export type GuildUpdate = {
|
||||
name?: string,
|
||||
icon?: string,
|
||||
splash?: string,
|
||||
region?: string,
|
||||
afkChannelId?: ?string,
|
||||
afkTimeout?: number,
|
||||
verificationLevel?: number,
|
||||
defaultMessageNotifications?: string,
|
||||
explicitContentFilter?: number,
|
||||
};
|
||||
|
||||
export default {
|
||||
init(guildId: string, section: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_INIT,
|
||||
guildId,
|
||||
section,
|
||||
});
|
||||
},
|
||||
|
||||
open(guildId: string, section?: string) {
|
||||
if (__IOS__) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_OPEN,
|
||||
guildId,
|
||||
section,
|
||||
});
|
||||
} else {
|
||||
this.init(guildId, section);
|
||||
pushLayer(Layers.GUILD_SETTINGS);
|
||||
}
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
setSection(section: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_SECTION,
|
||||
section,
|
||||
});
|
||||
},
|
||||
|
||||
setSearchQuery(searchQuery: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_SEARCH_QUERY,
|
||||
searchQuery,
|
||||
});
|
||||
},
|
||||
|
||||
selectRole(roleId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLE_SELECT,
|
||||
roleId,
|
||||
});
|
||||
},
|
||||
|
||||
updateEmbed(guildId: string, enabled: boolean, channelId: string) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_EMBED(guildId),
|
||||
// eslint-disable-next-line camelcase
|
||||
body: {enabled, channel_id: channelId},
|
||||
}).then(res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_EMBED,
|
||||
guildId: guildId,
|
||||
enabled: res.body.enabled,
|
||||
channelId: res.body['channel_id'],
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
updateMFALevel({guildId, level, isEnabled}: {guildId: string, level: number, isEnabled: boolean}) {
|
||||
mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.GUILD_SECURITY_REQ_MFA_LABEL,
|
||||
actionText: isEnabled
|
||||
? i18n.Messages.GUILD_SECURITY_REQ_MFA_TURN_OFF
|
||||
: i18n.Messages.GUILD_SECURITY_REQ_MFA_TURN_ON,
|
||||
},
|
||||
extraBody =>
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILD_MFA(guildId),
|
||||
body: {level, ...extraBody},
|
||||
})
|
||||
).then(res => Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_SET_MFA_SUCCESS, level: res.body.level}));
|
||||
},
|
||||
|
||||
// For iOS only
|
||||
updateIcon(guildId: string, icon: string) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD(guildId),
|
||||
body: {icon},
|
||||
}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_UPDATE,
|
||||
icon,
|
||||
});
|
||||
},
|
||||
res => Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_SUBMIT_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
// For iOS only
|
||||
cancelChanges(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_CANCEL_CHANGES,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
updateGuild(update: GuildUpdate) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_UPDATE,
|
||||
...update,
|
||||
});
|
||||
},
|
||||
|
||||
saveGuild(
|
||||
guildId: string,
|
||||
{
|
||||
name,
|
||||
icon,
|
||||
splash,
|
||||
region,
|
||||
afkChannelId,
|
||||
afkTimeout,
|
||||
verificationLevel,
|
||||
defaultMessageNotifications,
|
||||
explicitContentFilter,
|
||||
}: GuildUpdate
|
||||
) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SUBMIT,
|
||||
});
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD(guildId),
|
||||
body: {
|
||||
name,
|
||||
icon,
|
||||
splash,
|
||||
region,
|
||||
/* eslint-disable camelcase */
|
||||
afk_channel_id: afkChannelId,
|
||||
afk_timeout: afkTimeout,
|
||||
verification_level: verificationLevel,
|
||||
default_message_notifications: defaultMessageNotifications,
|
||||
explicit_content_filter: explicitContentFilter,
|
||||
/* eslint-enable camelcase */
|
||||
},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_SUBMIT_SUCCESS}),
|
||||
res => Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_SUBMIT_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
updateGuildModeration(guildId: string, update: {verificationLevel: number, explicitContentFilter: number}) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD(guildId),
|
||||
body: {
|
||||
/* eslint-disable camelcase */
|
||||
verification_level: update.verificationLevel,
|
||||
explicit_content_filter: update.explicitContentFilter,
|
||||
/* eslint-enable camelcase */
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
transferOwnership(guildId: string, ownerId: string) {
|
||||
return mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.TRANSFER_OWNERSHIP,
|
||||
actionText: i18n.Messages.TRANSFER_OWNERSHIP,
|
||||
},
|
||||
extraBody =>
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.GUILD(guildId),
|
||||
// eslint-disable-next-line camelcase
|
||||
body: {owner_id: ownerId, ...extraBody},
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
deleteGuild(guildId: string, guildName: string) {
|
||||
mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.DELETE_SERVER_TITLE.format({name: guildName}),
|
||||
actionText: i18n.Messages.DELETE_SERVER,
|
||||
},
|
||||
body =>
|
||||
HTTPUtils.post({
|
||||
url: `${Endpoints.GUILD(guildId)}/delete`,
|
||||
body,
|
||||
})
|
||||
).then(() => this.close());
|
||||
},
|
||||
|
||||
leaveGuild(guildId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.ME}${Endpoints.GUILD(guildId)}`).then(() => this.close());
|
||||
},
|
||||
|
||||
updateMemberRoles(guildId: string, userId: string, roles: Array<string>) {
|
||||
HTTPUtils.patch({
|
||||
url: `${Endpoints.GUILD_MEMBERS(guildId)}/${userId}`,
|
||||
body: {roles},
|
||||
});
|
||||
},
|
||||
|
||||
enableIntegration(guildId: string, type: string, id: string) {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILD_INTEGRATIONS(guildId),
|
||||
body: {type, id},
|
||||
});
|
||||
},
|
||||
|
||||
disableIntegration(guildId: string, integrationId: string) {
|
||||
HTTPUtils.delete(`${Endpoints.GUILD_INTEGRATIONS(guildId)}/${integrationId}`);
|
||||
},
|
||||
|
||||
updateIntegration(
|
||||
guildId: string,
|
||||
integrationId: string,
|
||||
expireBehavior: number,
|
||||
expireGracePeriod: number,
|
||||
enableEmoticons: boolean
|
||||
) {
|
||||
const params = {
|
||||
/* eslint-disable camelcase */
|
||||
expire_behavior: expireBehavior,
|
||||
expire_grace_period: expireGracePeriod,
|
||||
enable_emoticons: enableEmoticons,
|
||||
/* eslint-enable camelcase */
|
||||
};
|
||||
|
||||
HTTPUtils.patch({
|
||||
url: `${Endpoints.GUILD_INTEGRATIONS(guildId)}/${integrationId}`,
|
||||
body: params,
|
||||
});
|
||||
},
|
||||
|
||||
enableCustomEmoji(guildId: string, integrationId: string, enableCustomEmoji: boolean) {
|
||||
HTTPUtils.patch({
|
||||
url: `${Endpoints.GUILD_INTEGRATIONS(guildId)}/${integrationId}/custom_emoji`,
|
||||
body: {enable: enableCustomEmoji},
|
||||
});
|
||||
},
|
||||
|
||||
syncIntegration(guildId: string, integrationId: string) {
|
||||
HTTPUtils.post(`${Endpoints.GUILD_INTEGRATIONS(guildId)}/${integrationId}/sync`);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/GuildSettingsActionCreators.js
|
99
509bba0_unpacked/discord_app/actions/GuildSettingsRolesActionCreators.js
Executable file
99
509bba0_unpacked/discord_app/actions/GuildSettingsRolesActionCreators.js
Executable file
|
@ -0,0 +1,99 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import GuildActionCreators from './GuildActionCreators';
|
||||
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
import type {GuildRole} from '../flow/Server';
|
||||
|
||||
export function updateRoleSort(roles: Array<string>) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_SORT_UPDATE,
|
||||
roles,
|
||||
});
|
||||
}
|
||||
|
||||
export function init() {
|
||||
Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_ROLES_INIT});
|
||||
}
|
||||
|
||||
export function updateRolePermissions(id: string, flag: number, allow: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_UPDATE_PERMISSIONS,
|
||||
id,
|
||||
flag,
|
||||
allow,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateRoleName(id: string, name: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_UPDATE_NAME,
|
||||
id,
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateRoleColor(id: string, color: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_UPDATE_COLOR,
|
||||
id,
|
||||
color,
|
||||
});
|
||||
}
|
||||
|
||||
export function toggleRoleSettings(id: string, hoist: boolean, mentionable: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_UPDATE_SETTINGS,
|
||||
id,
|
||||
hoist,
|
||||
mentionable,
|
||||
});
|
||||
}
|
||||
|
||||
export function saveRoleSettings(
|
||||
guildId: string,
|
||||
roles?: Array<GuildRole>,
|
||||
deltas?: Array<{id: string, position: number}>
|
||||
) {
|
||||
Dispatcher.dispatch({type: ActionTypes.GUILD_SETTINGS_ROLES_SUBMITTING});
|
||||
// Save all role update changes consecutively, starting with order
|
||||
return new Promise(resolve => {
|
||||
const chain = () => {
|
||||
if (roles == null || roles.length === 0) {
|
||||
return resolve();
|
||||
}
|
||||
const role = roles.pop();
|
||||
if (role == null || role.name === '') {
|
||||
return chain();
|
||||
}
|
||||
|
||||
GuildActionCreators.updateRole(
|
||||
guildId,
|
||||
role.id,
|
||||
role.name,
|
||||
role.permissions,
|
||||
role.color,
|
||||
role.hoist,
|
||||
role.mentionable,
|
||||
true
|
||||
).then(chain, chain);
|
||||
};
|
||||
|
||||
if (deltas != null && deltas.length > 0) {
|
||||
GuildActionCreators.batchRoleUpdate(guildId, deltas).then(chain, chain);
|
||||
} else {
|
||||
chain();
|
||||
}
|
||||
}).then(() =>
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_ROLES_SAVE_SUCCESS,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/GuildSettingsRolesActionCreators.js
|
52
509bba0_unpacked/discord_app/actions/GuildSettingsVanityURLActionCreators.js
Executable file
52
509bba0_unpacked/discord_app/actions/GuildSettingsVanityURLActionCreators.js
Executable file
|
@ -0,0 +1,52 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_VANITY_URL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
resetCode() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_VANITY_URL_RESET,
|
||||
});
|
||||
},
|
||||
|
||||
setCode(code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_VANITY_URL_SET,
|
||||
code,
|
||||
});
|
||||
},
|
||||
|
||||
saveCode(guildId: string, code: string) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.GUILD_VANITY_URL(guildId),
|
||||
body: {
|
||||
code,
|
||||
},
|
||||
}).then(
|
||||
({body}: {body: {code: string}}) => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_SET_VANITY_URL,
|
||||
code: body.code,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.GUILD_SETTINGS_VANITY_URL_ERROR,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/GuildSettingsVanityURLActionCreators.js
|
23
509bba0_unpacked/discord_app/actions/HelpdeskActionCreators.js
Executable file
23
509bba0_unpacked/discord_app/actions/HelpdeskActionCreators.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import HelpdeskUtils from '../utils/HelpdeskUtils';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
loadFeaturedArticles() {
|
||||
HTTPUtils.get(HelpdeskUtils.getFeaturedArticlesJsonURL()).then(res => {
|
||||
const articles = res.body.articles || [];
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.FEATURED_HELP_ARTICLES,
|
||||
articles,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/HelpdeskActionCreators.js
|
27
509bba0_unpacked/discord_app/actions/InProgressTextCreators.js
Executable file
27
509bba0_unpacked/discord_app/actions/InProgressTextCreators.js
Executable file
|
@ -0,0 +1,27 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
saveCurrentText(channelId: string, textSoFar: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.IN_PROGRESS_TEXT_SAVE,
|
||||
channelId,
|
||||
textSoFar,
|
||||
});
|
||||
},
|
||||
|
||||
changeCurrentText(channelId: string, textSoFar: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.IN_PROGRESS_TEXT_CHANGE,
|
||||
channelId,
|
||||
textSoFar,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/InProgressTextCreators.js
|
19
509bba0_unpacked/discord_app/actions/IncomingCallActionCreators.js
Executable file
19
509bba0_unpacked/discord_app/actions/IncomingCallActionCreators.js
Executable file
|
@ -0,0 +1,19 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
move(x: number, y: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INCOMING_CALL_MOVE,
|
||||
x,
|
||||
y,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/IncomingCallActionCreators.js
|
233
509bba0_unpacked/discord_app/actions/InstantInviteActionCreators.js
Executable file
233
509bba0_unpacked/discord_app/actions/InstantInviteActionCreators.js
Executable file
|
@ -0,0 +1,233 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, ChannelTypes, Routes, ME, RPCCommands} from '../Constants';
|
||||
import SelectedChannelActionCreators from './SelectedChannelActionCreators';
|
||||
import ChannelStore from '../stores/ChannelStore';
|
||||
import ProtocolUtils from '../utils/web/ProtocolUtils';
|
||||
import RouterUtils from '../utils/RouterUtils';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import platform from 'platform';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
|
||||
const ANDROID_HREF =
|
||||
'intent://invite/%s#Intent;scheme=discord;package=com.discord;S.browser_fallback_url=http://discordapp.com;end';
|
||||
|
||||
export type Invite = {
|
||||
code: string,
|
||||
channel?: {
|
||||
id: string,
|
||||
name: string,
|
||||
},
|
||||
guild?: {
|
||||
id: string,
|
||||
name: string,
|
||||
},
|
||||
temporary?: boolean,
|
||||
revoked?: boolean,
|
||||
max_uses?: number,
|
||||
max_age?: number,
|
||||
created_at: ?number,
|
||||
};
|
||||
|
||||
export default {
|
||||
createInvite(channelId: string, options: any = {}, location: string): any {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.INSTANT_INVITES(channelId),
|
||||
body: options,
|
||||
context: {location},
|
||||
}).then(res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INSTANT_INVITE_CREATE_SUCCESS,
|
||||
channelId,
|
||||
invite: res.body,
|
||||
});
|
||||
|
||||
return res;
|
||||
});
|
||||
},
|
||||
|
||||
revokeInvite(code: string) {
|
||||
HTTPUtils.delete(`${Endpoints.INVITE}/${code}`).then(() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INSTANT_INVITE_REVOKE_SUCCESS,
|
||||
code,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
resolveInvite(code: string, location?: string, extraOptions?: any): Promise<*> {
|
||||
Dispatcher.maybeDispatch({
|
||||
type: ActionTypes.INVITE_RESOLVE,
|
||||
code,
|
||||
});
|
||||
return HTTPUtils.get({
|
||||
url: `${Endpoints.INVITE}/${code}`,
|
||||
query: extraOptions,
|
||||
}).then(
|
||||
res => {
|
||||
// While this may be a large number of events, we need it if we want to see
|
||||
// success rates. It also makes tracking viewing the instant invite page
|
||||
// unnecessary, and lets us also see how people are using the other ways
|
||||
// of accepting invites
|
||||
const invite = res.body;
|
||||
|
||||
if (location) {
|
||||
AnalyticsUtils.track('resolve_invite', {
|
||||
resolved: true,
|
||||
guild_id: invite.guild.id, // eslint-disable-line camelcase
|
||||
channel_id: invite.channel.id, // eslint-disable-line camelcase
|
||||
channel_type: invite.channel.type, // eslint-disable-line camelcase
|
||||
inviter_id: invite.inviter ? invite.inviter.id : null, // eslint-disable-line camelcase
|
||||
code,
|
||||
location,
|
||||
authenticated: AuthenticationStore.isAuthenticated(),
|
||||
});
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.INVITE_RESOLVE_SUCCESS, invite, code});
|
||||
return {invite, code};
|
||||
},
|
||||
() => {
|
||||
if (location) {
|
||||
AnalyticsUtils.track('resolve_invite', {
|
||||
resolved: false,
|
||||
code,
|
||||
location,
|
||||
authenticated: AuthenticationStore.isAuthenticated(),
|
||||
});
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({type: ActionTypes.INVITE_RESOLVE_FAILURE, code});
|
||||
return {invite: null, code};
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
acceptInvite(code: string, userLocation: string, callback: (invite: Invite) => void) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.INVITE_ACCEPT,
|
||||
code,
|
||||
});
|
||||
|
||||
HTTPUtils.post({
|
||||
url: `${Endpoints.INVITE}/${code}`,
|
||||
context: {
|
||||
Location: userLocation,
|
||||
},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_ACCEPT_SUCCESS,
|
||||
invite: res.body,
|
||||
code,
|
||||
});
|
||||
if (callback) {
|
||||
callback(res.body);
|
||||
} else {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_APP_NOT_OPENED,
|
||||
code,
|
||||
});
|
||||
}
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.INVITE_ACCEPT_FAILURE, code})
|
||||
);
|
||||
},
|
||||
|
||||
acceptInviteAndTransitionToInviteChannel(code: string, userLocation: string) {
|
||||
this.acceptInvite(code, userLocation, invite => {
|
||||
if (invite.channel != null) {
|
||||
this.transitionToInviteChannelSync(invite.channel.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
transitionToInviteChannel(guildId: string, channelId: string, channelType: number = ChannelTypes.GUILD_TEXT) {
|
||||
if (channelType === ChannelTypes.GUILD_VOICE) {
|
||||
SelectedChannelActionCreators.selectVoiceChannel(guildId, channelId);
|
||||
RouterUtils.transitionTo(Routes.CHANNEL(guildId, guildId));
|
||||
} else {
|
||||
RouterUtils.transitionTo(Routes.CHANNEL(guildId, channelId));
|
||||
}
|
||||
},
|
||||
|
||||
transitionToInviteChannelSync(channelId: string) {
|
||||
ChannelStore.addConditionalChangeListener(() => {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (channel != null) {
|
||||
this.transitionToInviteChannel(channel.getGuildId() || ME, channel.id, channel.type);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
openNativeAppModal(code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_NATIVE_APP_MODAL_OPENING,
|
||||
code,
|
||||
});
|
||||
|
||||
if (!__IOS__) {
|
||||
const RPCSocket = require('../lib/RPCSocket');
|
||||
|
||||
// $FlowFixMe
|
||||
RPCSocket.request(RPCCommands.INVITE_BROWSER, {code})
|
||||
.then(({code}) => this.nativeModalOpened(code))
|
||||
.catch(() => this.nativeModalOpenFailed(code))
|
||||
// $FlowFixMe
|
||||
.then(() => RPCSocket.disconnect());
|
||||
}
|
||||
},
|
||||
|
||||
nativeModalOpened(code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_NATIVE_APP_MODAL_OPENED,
|
||||
code,
|
||||
});
|
||||
},
|
||||
|
||||
nativeModalOpenFailed(code: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_NATIVE_APP_MODAL_OPEN_FAILED,
|
||||
code,
|
||||
});
|
||||
},
|
||||
|
||||
openApp(code: string, channelId: string) {
|
||||
Dispatcher.maybeDispatch({
|
||||
type: ActionTypes.INVITE_APP_OPENING,
|
||||
code,
|
||||
});
|
||||
|
||||
let path;
|
||||
if (platform.os.family === 'Android') {
|
||||
path = ANDROID_HREF.replace(/%s/g, code);
|
||||
} else {
|
||||
if (platform.os.family === 'iOS') {
|
||||
path = Routes.INVITE(code);
|
||||
} else {
|
||||
path = Routes.INVITE_PROXY(channelId);
|
||||
}
|
||||
|
||||
if (path[0] === '#') {
|
||||
path = path.slice(1);
|
||||
}
|
||||
|
||||
path = `discord://${path}`;
|
||||
}
|
||||
|
||||
ProtocolUtils.launch(path, supported => {
|
||||
Dispatcher.dispatch({
|
||||
type: supported ? ActionTypes.INVITE_APP_OPENED : ActionTypes.INVITE_APP_NOT_OPENED,
|
||||
code,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/InstantInviteActionCreators.js
|
30
509bba0_unpacked/discord_app/actions/IntegrationActionCreators.js
Executable file
30
509bba0_unpacked/discord_app/actions/IntegrationActionCreators.js
Executable file
|
@ -0,0 +1,30 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
search(integration: string, query: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.INTEGRATION_QUERY, integration, query});
|
||||
HTTPUtils.get({
|
||||
url: `${Endpoints.INTEGRATIONS}/${integration}/search`,
|
||||
query: {q: query},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INTEGRATION_QUERY_SUCCESS,
|
||||
integration,
|
||||
query,
|
||||
results: res.body,
|
||||
});
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.INTEGRATION_QUERY_FAILURE, integration, query})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/IntegrationActionCreators.js
|
50
509bba0_unpacked/discord_app/actions/InviteModalActionCreators.js
Executable file
50
509bba0_unpacked/discord_app/actions/InviteModalActionCreators.js
Executable file
|
@ -0,0 +1,50 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import i18n from '../i18n';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import InstantInviteActionCreators from './InstantInviteActionCreators';
|
||||
|
||||
export default {
|
||||
acceptInvite(code: string, userLocation: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.INVITE_ACCEPT,
|
||||
code,
|
||||
});
|
||||
|
||||
HTTPUtils.post({
|
||||
url: `${Endpoints.INVITE}/${code}`,
|
||||
context: {
|
||||
Location: userLocation,
|
||||
},
|
||||
}).then(
|
||||
res => {
|
||||
const invite = res.body;
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_ACCEPT_SUCCESS,
|
||||
invite,
|
||||
code,
|
||||
});
|
||||
InstantInviteActionCreators.transitionToInviteChannel(invite.guild.id, invite.channel.id, invite.channel.type);
|
||||
Dispatcher.dispatch({type: ActionTypes.INVITE_MODAL_CLOSE});
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.INVITE_ACCEPT_FAILURE, code});
|
||||
const message = (res && res.body && res.body.message) || i18n.Messages.INVITE_MODAL_ERROR_DEFAULT;
|
||||
Dispatcher.dispatch({type: ActionTypes.INVITE_MODAL_ERROR, message: message});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.INVITE_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/InviteModalActionCreators.js
|
35
509bba0_unpacked/discord_app/actions/KeybindsActionCreators.js
Executable file
35
509bba0_unpacked/discord_app/actions/KeybindsActionCreators.js
Executable file
|
@ -0,0 +1,35 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import type {KeybindShortcut} from '../flow/Client';
|
||||
|
||||
export type Keybind = {
|
||||
id: string,
|
||||
action: string,
|
||||
shortcut: KeybindShortcut,
|
||||
managed: boolean,
|
||||
};
|
||||
|
||||
export default {
|
||||
addKeybind() {
|
||||
Dispatcher.dispatch({type: ActionTypes.KEYBINDS_ADD_KEYBIND});
|
||||
},
|
||||
|
||||
setKeybind(keybind: Keybind) {
|
||||
Dispatcher.dispatch({type: ActionTypes.KEYBINDS_SET_KEYBIND, keybind});
|
||||
},
|
||||
|
||||
deleteKeybind(id: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.KEYBINDS_DELETE_KEYBIND, id});
|
||||
},
|
||||
|
||||
enableAll(enable: boolean) {
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.KEYBINDS_ENABLE_ALL_KEYBINDS, enable});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/KeybindsActionCreators.js
|
29
509bba0_unpacked/discord_app/actions/KeyboardShortcutModalActionCreators.js
Executable file
29
509bba0_unpacked/discord_app/actions/KeyboardShortcutModalActionCreators.js
Executable file
|
@ -0,0 +1,29 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
show() {
|
||||
// Not sure this is the right way to do this...
|
||||
this.deactivateRagingDemon();
|
||||
Dispatcher.dispatch({type: ActionTypes.SHOW_KEYBOARD_SHORTCUTS});
|
||||
},
|
||||
|
||||
hide() {
|
||||
Dispatcher.dispatch({type: ActionTypes.HIDE_KEYBOARD_SHORTCUTS});
|
||||
},
|
||||
|
||||
activateRagingDemon() {
|
||||
Dispatcher.dispatch({type: ActionTypes.ACTIVATE_RAGING_DEMON});
|
||||
},
|
||||
|
||||
deactivateRagingDemon() {
|
||||
Dispatcher.dispatch({type: ActionTypes.DEACTIVATE_RAGING_DEMON});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/KeyboardShortcutModalActionCreators.js
|
27
509bba0_unpacked/discord_app/actions/LayerActionCreators.js
Executable file
27
509bba0_unpacked/discord_app/actions/LayerActionCreators.js
Executable file
|
@ -0,0 +1,27 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export function pushLayer(component: string) {
|
||||
// DirtyDispatch because pushLayer can be called on connection open for forced verification
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LAYER_PUSH,
|
||||
component,
|
||||
});
|
||||
}
|
||||
|
||||
export function popLayer() {
|
||||
// Must be a dirtyDispatch because popLayer can be called on channel deletion
|
||||
// if someone is viewing channel settings
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.LAYER_POP});
|
||||
}
|
||||
|
||||
export function popAllLayers() {
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.LAYER_POP_ALL});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/LayerActionCreators.js
|
58
509bba0_unpacked/discord_app/actions/MFAActionCreators.js
Executable file
58
509bba0_unpacked/discord_app/actions/MFAActionCreators.js
Executable file
|
@ -0,0 +1,58 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import i18n from '../i18n';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import mfaInterceptor from '../utils/MFAInterceptionUtils';
|
||||
|
||||
export default {
|
||||
enable({code, secret}: {code: string, secret: string}) {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.MFA_TOTP_ENABLE,
|
||||
body: {code, secret},
|
||||
}).then(res =>
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MFA_ENABLE_SUCCESS,
|
||||
token: res.body.token,
|
||||
codes: res.body['backup_codes'],
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
disable() {
|
||||
mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.TWO_FA_DISABLE,
|
||||
actionText: i18n.Messages.TWO_FA_REMOVE,
|
||||
},
|
||||
body =>
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.MFA_TOTP_DISABLE,
|
||||
body,
|
||||
}),
|
||||
true
|
||||
).then(res => Dispatcher.dispatch({type: ActionTypes.MFA_DISABLE_SUCCESS, token: res.body.token}));
|
||||
},
|
||||
|
||||
viewBackupCodes(password: string, regenerate: boolean = false): Promise {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.MFA_CODES,
|
||||
body: {password, regenerate},
|
||||
}).then(res => Dispatcher.dispatch({type: ActionTypes.MFA_VIEW_BACKUP_CODES, codes: res.body['backup_codes']}));
|
||||
},
|
||||
|
||||
clearBackupCodes() {
|
||||
// With the new settings screen, this can be called on a logout
|
||||
// unmount action, therefore we need to make it dirty to avoid
|
||||
// a dispatch firing from within a dispatch
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.MFA_CLEAR_BACKUP_CODES,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/MFAActionCreators.js
|
18
509bba0_unpacked/discord_app/actions/MaskedLinkActionCreators.js
Executable file
18
509bba0_unpacked/discord_app/actions/MaskedLinkActionCreators.js
Executable file
|
@ -0,0 +1,18 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
function trustDomain(url: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MASKED_LINK_ADD_TRUSTED_DOMAIN,
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
export {trustDomain};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/MaskedLinkActionCreators.js
|
90
509bba0_unpacked/discord_app/actions/MentionActionCreators.js
Executable file
90
509bba0_unpacked/discord_app/actions/MentionActionCreators.js
Executable file
|
@ -0,0 +1,90 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {Endpoints, ActionTypes, MAX_MENTIONS_PER_FETCH} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
setGuildFilter({
|
||||
guildFilter,
|
||||
roleFilter,
|
||||
everyoneFilter,
|
||||
}: {
|
||||
guildFilter: string,
|
||||
roleFilter: boolean,
|
||||
everyoneFilter: boolean,
|
||||
}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.SET_RECENT_MENTIONS_FILTER,
|
||||
guildFilter,
|
||||
roleFilter,
|
||||
everyoneFilter,
|
||||
});
|
||||
},
|
||||
|
||||
truncateMentions(size: number) {
|
||||
// This can be triggered while unloading the popout, which can be triggered by another action.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.TRUNCATE_MENTIONS,
|
||||
size,
|
||||
});
|
||||
},
|
||||
|
||||
fetchRecentMentions(
|
||||
before: ?string,
|
||||
limit: ?number = MAX_MENTIONS_PER_FETCH,
|
||||
guildId: ?string = null,
|
||||
roles: ?boolean = true,
|
||||
everyone: ?boolean = true
|
||||
) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LOAD_RECENT_MENTIONS,
|
||||
guildId,
|
||||
});
|
||||
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.MENTIONS,
|
||||
query: {
|
||||
before,
|
||||
limit,
|
||||
guild_id: guildId, // eslint-disable-line camelcase
|
||||
roles,
|
||||
everyone,
|
||||
},
|
||||
retries: 2,
|
||||
}).then(
|
||||
({body: messages}) => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_RECENT_MENTIONS_SUCCESS,
|
||||
messages: messages,
|
||||
isAfter: before != null,
|
||||
hasMoreAfter: messages.length >= MAX_MENTIONS_PER_FETCH,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_RECENT_MENTIONS_FAILURE,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
deleteRecentMention(messageId: string) {
|
||||
HTTPUtils.delete({
|
||||
url: Endpoints.MENTIONS_MESSAGE_ID(messageId),
|
||||
retries: 2,
|
||||
});
|
||||
|
||||
// This is an optimistic delete. The server will also dispatch this so that
|
||||
// all other connected clients also delete the recent mention.
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.RECENT_MENTION_DELETE,
|
||||
id: messageId,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/MentionActionCreators.js
|
353
509bba0_unpacked/discord_app/actions/MessageActionCreators.js
Executable file
353
509bba0_unpacked/discord_app/actions/MessageActionCreators.js
Executable file
|
@ -0,0 +1,353 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import lodash from 'lodash';
|
||||
import MessageUtils from '../utils/MessageUtils';
|
||||
import type {ParsedMessage} from '../utils/MessageUtils';
|
||||
import ReadStateStore from '../stores/ReadStateStore';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import MessageQueue from '../lib/MessageQueue';
|
||||
import i18n from '../i18n';
|
||||
import ChannelRecord from '../records/ChannelRecord';
|
||||
import AppAnalyticsUtils from '../utils/AppAnalyticsUtils';
|
||||
import {
|
||||
ActionTypes,
|
||||
Endpoints,
|
||||
ME,
|
||||
MAX_MESSAGES_PER_CHANNEL,
|
||||
CLYDE_ERROR_MESSAGES,
|
||||
Permissions,
|
||||
AbortCodes,
|
||||
} from '../Constants';
|
||||
import MessageStore from '../stores/MessageStore';
|
||||
import UserStore from '../stores/UserStore';
|
||||
import GuildStore from '../stores/GuildStore';
|
||||
import ChannelStore from '../stores/ChannelStore';
|
||||
import PermissionUtils from '../utils/PermissionUtils';
|
||||
import type {Message} from '../flow/Server';
|
||||
import type {JumpDescriptor} from '../flow/Client';
|
||||
|
||||
let seenEmojiWarning = false;
|
||||
|
||||
export default {
|
||||
receiveMessage(channelId: string, message: Message, optimistic: boolean = false) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.MESSAGE_CREATE,
|
||||
channelId,
|
||||
message,
|
||||
optimistic,
|
||||
});
|
||||
},
|
||||
|
||||
sendBotMessage(channelId: string, content: string) {
|
||||
this.receiveMessage(channelId, MessageUtils.createBotMessage(channelId, content));
|
||||
},
|
||||
|
||||
sendClydeError(channelId: string, code: number = 0) {
|
||||
let message;
|
||||
if (code === AbortCodes.EXPLICIT_CONTENT) {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
if (channel.isDM()) {
|
||||
message = i18n.Messages.BOT_DM_EXPLICIT_CONTENT.format({name: channel.toString()});
|
||||
} else if (channel.isGroupDM()) {
|
||||
message = i18n.Messages.BOT_GDM_EXPLICIT_CONTENT.format({name: channel.toString()});
|
||||
} else {
|
||||
const guild = GuildStore.getGuild(channel.getGuildId());
|
||||
if (guild == null) {
|
||||
return;
|
||||
}
|
||||
message = i18n.Messages.BOT_GUILD_EXPLICIT_CONTENT.format({name: guild.toString()});
|
||||
}
|
||||
} else {
|
||||
message = i18n.Messages[CLYDE_ERROR_MESSAGES[code] || CLYDE_ERROR_MESSAGES.DEFAULT];
|
||||
}
|
||||
this.sendBotMessage(channelId, message);
|
||||
},
|
||||
|
||||
truncateMessages(channelId: string, truncateBottom: boolean, truncateTop: boolean) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.TRUNCATE_MESSAGES,
|
||||
channelId,
|
||||
truncateBottom,
|
||||
truncateTop,
|
||||
});
|
||||
},
|
||||
|
||||
jumpToPresent(channelId: string, limit: number) {
|
||||
this.trackJump(channelId, null, 'Present');
|
||||
|
||||
const jump = {
|
||||
present: true,
|
||||
};
|
||||
|
||||
if (MessageStore.hasPresent(channelId)) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES_SUCCESS_CACHED,
|
||||
jump,
|
||||
channelId,
|
||||
limit,
|
||||
});
|
||||
} else {
|
||||
this.fetchMessages(channelId, null, null, limit, jump);
|
||||
}
|
||||
},
|
||||
|
||||
trackJump(channelId: string, messageId: ?string, context: string, extraProperties: ?Object) {
|
||||
AppAnalyticsUtils.trackWithMetadata('jump', {
|
||||
context,
|
||||
channel_id: channelId, // eslint-disable-line camelcase
|
||||
message_id: messageId, // eslint-disable-line camelcase
|
||||
...extraProperties,
|
||||
});
|
||||
},
|
||||
|
||||
jumpToMessage(
|
||||
channelId: string,
|
||||
messageId: string,
|
||||
flash?: boolean = true,
|
||||
context?: string,
|
||||
extraProperties: ?Object = null
|
||||
) {
|
||||
if (typeof context === 'string') {
|
||||
this.trackJump(channelId, messageId, context, extraProperties);
|
||||
}
|
||||
|
||||
this.fetchMessages(channelId, null, null, MAX_MESSAGES_PER_CHANNEL, {messageId, flash});
|
||||
},
|
||||
|
||||
// Tell the stores that the channel is probably going to be loaded, and do any kind of loading
|
||||
// ahead of time. I.e. fetching messages for a channel we know might be selected soon.
|
||||
prefetchMessages(guildId: string, channelId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PREFETCH_MESSAGES,
|
||||
guildId: guildId === ME ? null : guildId,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
fetchMessages(channelId: string, before: ?string, after: ?string, limit: number, jump?: JumpDescriptor) {
|
||||
if (this._tryFetchMessagesCached(channelId, before, after, limit, jump)) {
|
||||
return;
|
||||
}
|
||||
// The only time this happens during a dispatch is when the channel is loaded for the first
|
||||
// time, but there is no need to dispatch this because channels are loading by default.
|
||||
Dispatcher.maybeDispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES,
|
||||
channelId,
|
||||
jump,
|
||||
});
|
||||
|
||||
const around = jump && jump.messageId;
|
||||
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.MESSAGES(channelId),
|
||||
query: {before, after, limit, around},
|
||||
retries: 2,
|
||||
}).then(
|
||||
res => {
|
||||
const messages = res.body;
|
||||
const isBefore = before != null;
|
||||
const isAfter = after != null;
|
||||
const isReplacement = before == null && after == null;
|
||||
|
||||
let hasMoreBefore = around != null || (messages.length === limit && (isBefore || isReplacement));
|
||||
let hasMoreAfter = around != null || (isAfter && messages.length === limit);
|
||||
if (around) {
|
||||
const halfLength = limit / 2;
|
||||
|
||||
// the messages are in reverse order, so the index needs to be inverted
|
||||
const targetIndex = messages.length - 1 - lodash.findIndex(messages, ({id}) => id === around);
|
||||
|
||||
// If the target message has less than halfLength messages before it, then we are at
|
||||
// the beginning of the message history
|
||||
if (targetIndex < halfLength) {
|
||||
hasMoreBefore = false;
|
||||
}
|
||||
|
||||
// if fewer than limit + 1 messages are returned, and the target has halfLength messages before it,
|
||||
// then we're at the end of the message history
|
||||
if (targetIndex >= halfLength && messages.length < limit + 1) {
|
||||
hasMoreAfter = false;
|
||||
}
|
||||
// If we still have more after, let's do a quick sanity check to see if the last message id
|
||||
// loaded is the last message ID according to the read state store. If it is, we're not missing
|
||||
// any messages.
|
||||
if (hasMoreAfter && messages.length) {
|
||||
const lastMessageId = ReadStateStore.lastMessageId(channelId);
|
||||
if (messages[0].id == lastMessageId) {
|
||||
hasMoreAfter = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES_SUCCESS,
|
||||
channelId,
|
||||
messages,
|
||||
isBefore,
|
||||
isAfter,
|
||||
hasMoreBefore,
|
||||
hasMoreAfter,
|
||||
jump,
|
||||
});
|
||||
},
|
||||
() => Dispatcher.dispatch({type: ActionTypes.LOAD_MESSAGES_FAILURE, channelId})
|
||||
);
|
||||
},
|
||||
|
||||
_tryFetchMessagesCached(channelId: string, before: ?string, after: ?string, limit: number, jump?: JumpDescriptor) {
|
||||
// citron note: this can be invoked during a channel switch, so all dispatches need to be dirty
|
||||
const messages = MessageStore.getMessages(channelId);
|
||||
|
||||
// if we're jumping, check if we already have the target message loaded
|
||||
if (jump && jump.messageId && messages.has(jump.messageId, false)) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES_SUCCESS_CACHED,
|
||||
channelId,
|
||||
jump,
|
||||
limit,
|
||||
});
|
||||
|
||||
return true;
|
||||
} else if (before && messages.hasBeforeCached(before)) {
|
||||
// we're not jumping, but check if we already have the previous block cached
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES_SUCCESS_CACHED,
|
||||
channelId,
|
||||
before,
|
||||
limit,
|
||||
});
|
||||
|
||||
return true;
|
||||
} else if (after && messages.hasAfterCached(after)) {
|
||||
// we're not jumping, but check if we already have the next block cached
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.LOAD_MESSAGES_SUCCESS_CACHED,
|
||||
channelId,
|
||||
after,
|
||||
limit,
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
sendMessage(channelId: string, message: ParsedMessage, whenReady?: boolean = true) {
|
||||
if (whenReady) {
|
||||
MessageStore.whenReady(channelId, () => this._sendMessage(channelId, message));
|
||||
} else {
|
||||
this._sendMessage(channelId, message);
|
||||
}
|
||||
},
|
||||
|
||||
_sendMessage(channelId: string, {content, invalidEmojis, tts = false}: ParsedMessage) {
|
||||
// Don't send empty messages.
|
||||
if (!content) return;
|
||||
|
||||
const message = MessageUtils.createMessage(channelId, content, tts);
|
||||
this.receiveMessage(channelId, message, true);
|
||||
|
||||
if (!seenEmojiWarning && invalidEmojis && invalidEmojis.length > 0) {
|
||||
seenEmojiWarning = true;
|
||||
const user = UserStore.getCurrentUser();
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (!__IOS__ && PermissionUtils.can(Permissions.USE_EXTERNAL_EMOJIS, user, channel)) {
|
||||
this.sendBotMessage(channelId, i18n.Messages.INVALID_EMOJI_BODY_UPGRADE);
|
||||
} else {
|
||||
this.sendBotMessage(channelId, i18n.Messages.INVALID_EMOJI_BODY);
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueue.enqueue(
|
||||
{
|
||||
type: 'send',
|
||||
message: {
|
||||
channelId,
|
||||
content,
|
||||
nonce: message.id,
|
||||
tts,
|
||||
},
|
||||
},
|
||||
res => {
|
||||
if (res.ok) {
|
||||
this.receiveMessage(channelId, res.body);
|
||||
} else {
|
||||
if (res.status >= 400 && res.status < 500 && res.body) {
|
||||
this.sendClydeError(channelId, res.body.code);
|
||||
}
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_SEND_FAILED,
|
||||
messageId: message.id,
|
||||
channelId,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
retrySendMessage(channel: ChannelRecord, messageId: string, content: string, tts: boolean, parse: boolean = false) {
|
||||
this.deleteMessage(channel.id, messageId, true);
|
||||
if (parse) {
|
||||
this.sendMessage(channel.id, MessageUtils.parse(channel, content));
|
||||
} else {
|
||||
this.sendMessage(channel.id, {content, tts});
|
||||
}
|
||||
},
|
||||
|
||||
startEditMessage(channelId: string, messageId: string, parsedContent: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_START_EDIT,
|
||||
channelId,
|
||||
messageId,
|
||||
content: parsedContent,
|
||||
});
|
||||
},
|
||||
|
||||
endEditMessage() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_END_EDIT,
|
||||
});
|
||||
},
|
||||
|
||||
editMessage(channelId: string, messageId: string, {content}: {content: string}) {
|
||||
const message = {channelId, messageId, content};
|
||||
MessageQueue.enqueue({type: 'edit', message}, this.endEditMessage);
|
||||
},
|
||||
|
||||
deleteMessage(channelId: string, messageId: string, local: boolean = false) {
|
||||
if (local) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_DELETE,
|
||||
id: messageId,
|
||||
channelId,
|
||||
});
|
||||
} else {
|
||||
HTTPUtils.delete(`${Endpoints.MESSAGES(channelId)}/${messageId}`).then(() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_DELETE,
|
||||
id: messageId,
|
||||
channelId,
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
revealMessage(channelId: string, messageId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_REVEAL,
|
||||
channelId,
|
||||
messageId,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/MessageActionCreators.js
|
32
509bba0_unpacked/discord_app/actions/ModalActionCreators.js
Executable file
32
509bba0_unpacked/discord_app/actions/ModalActionCreators.js
Executable file
|
@ -0,0 +1,32 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import lodash from 'lodash';
|
||||
|
||||
export type ModalRender = ReactClass | ((props: Object) => ReactElement);
|
||||
|
||||
export default {
|
||||
push(modal: ModalRender, props?: Object) {
|
||||
const key = lodash.uniqueId('modal');
|
||||
Dispatcher.dispatch({type: ActionTypes.MODAL_PUSH, modal, props, key});
|
||||
return key;
|
||||
},
|
||||
|
||||
update(key: string, props: Object, partial: boolean = true) {
|
||||
Dispatcher.dispatch({type: ActionTypes.MODAL_UPDATE, key, props, partial});
|
||||
},
|
||||
|
||||
pop() {
|
||||
Dispatcher.dispatch({type: ActionTypes.MODAL_POP});
|
||||
},
|
||||
|
||||
popWithKey(key: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.MODAL_POP, key});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ModalActionCreators.js
|
115
509bba0_unpacked/discord_app/actions/NewUserActionCreators.js
Executable file
115
509bba0_unpacked/discord_app/actions/NewUserActionCreators.js
Executable file
|
@ -0,0 +1,115 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import type UserRecord from '../records/UserRecord';
|
||||
|
||||
function saveAccountChanges(body) {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.ME,
|
||||
body,
|
||||
}).then(
|
||||
res => {
|
||||
const user = res.body;
|
||||
if (user.token) {
|
||||
const token = user.token;
|
||||
delete user.token;
|
||||
Dispatcher.dispatch({type: ActionTypes.UPDATE_TOKEN, token});
|
||||
}
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_UPDATE, user});
|
||||
Dispatcher.dispatch({type: ActionTypes.NEW_USER_FLOW_ACCOUNT_SUCCESS});
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_ACCOUNT_FAILURE,
|
||||
errors: res.body,
|
||||
});
|
||||
return Promise.reject(res);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
setStep(step: number = -1) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_SET_STEP,
|
||||
step,
|
||||
});
|
||||
},
|
||||
|
||||
updateTemporaryGuild(update: {name?: string, icon?: string, region?: string}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_GUILD_UPDATE,
|
||||
guild: update,
|
||||
});
|
||||
},
|
||||
|
||||
createGuild(name: string, region: string, icon: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_GUILD_SUBMITTED,
|
||||
});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILDS,
|
||||
body: {name, region, icon},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.NEW_USER_FLOW_GUILD_CREATED}),
|
||||
res => Dispatcher.dispatch({type: ActionTypes.NEW_USER_FLOW_GUILD_FAILURE, errors: res.body})
|
||||
);
|
||||
},
|
||||
|
||||
updateAccount(settings: {email: string, password: string}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_ACCOUNT_UPDATE,
|
||||
settings,
|
||||
});
|
||||
},
|
||||
|
||||
claimAccount(user: UserRecord) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_ACCOUNT_SUBMITTED,
|
||||
});
|
||||
return saveAccountChanges(user);
|
||||
},
|
||||
|
||||
updateAvatar(avatar: string) {
|
||||
return saveAccountChanges({avatar});
|
||||
},
|
||||
|
||||
// New User Onboarding Actions
|
||||
advanceStep() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_ADVANCE_STEP,
|
||||
});
|
||||
},
|
||||
|
||||
skipOnboarding() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_SKIP,
|
||||
});
|
||||
},
|
||||
|
||||
micTestStart() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_MIC_TEST_START,
|
||||
});
|
||||
},
|
||||
|
||||
micTestStop() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_MIC_TEST_STOP,
|
||||
});
|
||||
},
|
||||
|
||||
selectMicInput(id: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NEW_USER_FLOW_SELECT_MIC_INPUT,
|
||||
id,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/NewUserActionCreators.js
|
15
509bba0_unpacked/discord_app/actions/NoteActionCreators.js
Executable file
15
509bba0_unpacked/discord_app/actions/NoteActionCreators.js
Executable file
|
@ -0,0 +1,15 @@
|
|||
/* @flow */
|
||||
|
||||
import {Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
updateNote(userId: string, note: string) {
|
||||
HTTPUtils.put({url: `${Endpoints.NOTES}/${userId}`, body: {note}});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/NoteActionCreators.js
|
31
509bba0_unpacked/discord_app/actions/NoticeActionCreators.js
Executable file
31
509bba0_unpacked/discord_app/actions/NoticeActionCreators.js
Executable file
|
@ -0,0 +1,31 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
show(noticeType: string, message?: string, buttonText?: string, callback?: Function, id?: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTICE_SHOW,
|
||||
notice: {
|
||||
id,
|
||||
type: noticeType,
|
||||
message,
|
||||
buttonText,
|
||||
callback,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
dismiss(id?: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTICE_DISMISS,
|
||||
id,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/NoticeActionCreators.js
|
72
509bba0_unpacked/discord_app/actions/NotificationActionCreators.js
Executable file
72
509bba0_unpacked/discord_app/actions/NotificationActionCreators.js
Executable file
|
@ -0,0 +1,72 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, NotificationPermissionTypes} from '../Constants';
|
||||
import NotificationUtils from '../utils/NotificationUtils';
|
||||
import type {NotificationOptions} from '../utils/NotificationUtils';
|
||||
|
||||
export default {
|
||||
setDesktopType(desktopType: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATIONS_SET_DESKTOP_TYPE,
|
||||
desktopType,
|
||||
});
|
||||
},
|
||||
|
||||
setTTSType(ttsType: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATIONS_SET_TTS_TYPE,
|
||||
ttsType,
|
||||
});
|
||||
},
|
||||
|
||||
setDisabledSounds(sounds: Array<string>) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATIONS_SET_DISABLED_SOUNDS,
|
||||
sounds,
|
||||
});
|
||||
},
|
||||
|
||||
setDisableUnreadBadge(disableUnreadBadge: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATIONS_SET_DISABLE_UNREAD_BADGE,
|
||||
disableUnreadBadge,
|
||||
});
|
||||
},
|
||||
|
||||
requestPermission(source: string) {
|
||||
NotificationUtils.requestPermission(enabled => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATIONS_SET_PERMISSION_STATE,
|
||||
enabled: enabled ? NotificationPermissionTypes.ENABLED : NotificationPermissionTypes.BLOCKED,
|
||||
source,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
showNotification(icon: ?string, title: string, body: string, options: NotificationOptions) {
|
||||
// Sometimes notifications are dispatched in stores.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.NOTIFICATION_CREATE,
|
||||
icon,
|
||||
title,
|
||||
body,
|
||||
options: {
|
||||
...options,
|
||||
onClick() {
|
||||
options.onClick && options.onClick();
|
||||
this.clickedNotification();
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
clickedNotification() {
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.NOTIFICATION_CLICK});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/NotificationActionCreators.js
|
|
@ -0,0 +1,44 @@
|
|||
/* @flow */
|
||||
|
||||
import {ActionTypes, Endpoints, ME} from '../Constants';
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import type {NotificationSettings} from '../flow/Server';
|
||||
|
||||
export default {
|
||||
open(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATION_SETTINGS_MODAL_OPEN,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.NOTIFICATION_SETTINGS_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
updateNotificationSettings(guildId: string, settings: NotificationSettings, partial: boolean = false) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.USER_GUILD_SETTINGS(guildId || ME),
|
||||
body: settings,
|
||||
});
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_GUILD_SETTINGS_UPDATE,
|
||||
// eslint-disable-next-line camelcase
|
||||
userGuildSettings: [{guild_id: guildId, ...settings}],
|
||||
partial,
|
||||
});
|
||||
},
|
||||
|
||||
updateChannelOverrideSettings(guildId: string, channelId: string, settings: NotificationSettings) {
|
||||
// eslint-disable-next-line camelcase
|
||||
this.updateNotificationSettings(guildId, {channel_overrides: {[channelId]: settings}}, true);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/NotificationSettingsModalActionCreators.js
|
84
509bba0_unpacked/discord_app/actions/OverlayActionCreators.js
Executable file
84
509bba0_unpacked/discord_app/actions/OverlayActionCreators.js
Executable file
|
@ -0,0 +1,84 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
setLocked(locked: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_LOCKED,
|
||||
locked,
|
||||
});
|
||||
},
|
||||
|
||||
setEnabled(enabled: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_ENABLED,
|
||||
enabled,
|
||||
});
|
||||
},
|
||||
|
||||
selectGuild(guildId: ?string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SELECT_GUILD,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
selectCall(callId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SELECT_CALL,
|
||||
callId,
|
||||
});
|
||||
},
|
||||
|
||||
openUserPopout(userId: string, guildId: string, channelId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_OPEN_USER_POPOUT,
|
||||
userId,
|
||||
guildId,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
setDisplayNameMode(mode: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_DISPLAY_NAME_MODE,
|
||||
mode,
|
||||
});
|
||||
},
|
||||
|
||||
setDisplayUserMode(mode: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_DISPLAY_USER_MODE,
|
||||
mode,
|
||||
});
|
||||
},
|
||||
|
||||
setAvatarSizeMode(mode: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_AVATAR_SIZE_MODE,
|
||||
mode,
|
||||
});
|
||||
},
|
||||
|
||||
setPosition(x: number, y: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_SET_POSITION,
|
||||
x,
|
||||
y,
|
||||
});
|
||||
},
|
||||
|
||||
setInstallProgress(progress: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.OVERLAY_INSTALL_PROGRESS,
|
||||
progress,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/OverlayActionCreators.js
|
34
509bba0_unpacked/discord_app/actions/PaymentModalActionCreators.js
Executable file
34
509bba0_unpacked/discord_app/actions/PaymentModalActionCreators.js
Executable file
|
@ -0,0 +1,34 @@
|
|||
/* @flow */
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, PaymentModelModes} from '../Constants';
|
||||
|
||||
import type {CardInfo} from './BillingActionCreators';
|
||||
type PaymentModelModeValues = 'NEW' | 'CHANGE' | 'RESUBSCRIBE';
|
||||
|
||||
export default {
|
||||
show(mode: PaymentModelModeValues = PaymentModelModes.NEW, plan: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_MODAL_OPEN,
|
||||
mode,
|
||||
plan,
|
||||
});
|
||||
},
|
||||
|
||||
submit(cardInfo: CardInfo) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_MODAL_SUBMIT,
|
||||
cardInfo,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PAYMENT_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PaymentModalActionCreators.js
|
30
509bba0_unpacked/discord_app/actions/PermissionActionCreators.js
Executable file
30
509bba0_unpacked/discord_app/actions/PermissionActionCreators.js
Executable file
|
@ -0,0 +1,30 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
clearVADWarning() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PERMISSION_CLEAR_VAD_WARNING,
|
||||
});
|
||||
},
|
||||
|
||||
clearSuppressWarning(forever: boolean = false) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PERMISSION_CLEAR_SUPPRESS_WARNING,
|
||||
forever,
|
||||
});
|
||||
},
|
||||
|
||||
clearPTTAdminWarning() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PERMISSION_CLEAR_PTT_ADMIN_WARNING,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PermissionActionCreators.js
|
48
509bba0_unpacked/discord_app/actions/PhoneVerificationActionCreators.js
Executable file
48
509bba0_unpacked/discord_app/actions/PhoneVerificationActionCreators.js
Executable file
|
@ -0,0 +1,48 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
let PhoneVerificationActionCreators = {};
|
||||
if (__IOS__) {
|
||||
PhoneVerificationActionCreators = require('./ios/PhoneVerificationActionCreators');
|
||||
}
|
||||
|
||||
export default {
|
||||
...PhoneVerificationActionCreators,
|
||||
|
||||
addPhone(phone: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.VERIFICATION_ADDING_PHONE});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.PHONE,
|
||||
body: {
|
||||
phone,
|
||||
},
|
||||
}).then(
|
||||
() => Dispatcher.dispatch({type: ActionTypes.VERIFICATION_ADD_PHONE_SUCCESS}),
|
||||
({body}) => Dispatcher.dispatch({type: ActionTypes.VERIFICATION_ADD_PHONE_FAILURE, error: body.message})
|
||||
);
|
||||
},
|
||||
|
||||
verifyPhone(code: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.VERIFICATION_VERIFYING_PHONE});
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.VERIFY_PHONE,
|
||||
body: {
|
||||
code,
|
||||
},
|
||||
}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.VERIFICATION_VERIFY_PHONE_SUCCESS});
|
||||
Dispatcher.dispatch({type: ActionTypes.MODAL_POP});
|
||||
},
|
||||
({body}) => Dispatcher.dispatch({type: ActionTypes.VERIFICATION_VERIFY_PHONE_FAILURE, error: body.message})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PhoneVerificationActionCreators.js
|
44
509bba0_unpacked/discord_app/actions/PictureInPictureActionCreators.js
Executable file
44
509bba0_unpacked/discord_app/actions/PictureInPictureActionCreators.js
Executable file
|
@ -0,0 +1,44 @@
|
|||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import type {PictureInPictureOffsets} from '../flow/Client';
|
||||
|
||||
type Identifier = string | number;
|
||||
|
||||
export function open(
|
||||
id: Identifier,
|
||||
component: string | Function,
|
||||
position: string,
|
||||
props: any = {},
|
||||
offsets: PictureInPictureOffsets
|
||||
) {
|
||||
// This can be called during channel/guild changes
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.PICTURE_IN_PICTURE_OPEN,
|
||||
id,
|
||||
component,
|
||||
position,
|
||||
props,
|
||||
offsets,
|
||||
});
|
||||
}
|
||||
|
||||
export function close(id: Identifier) {
|
||||
// This can be called during channel/guild changes
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.PICTURE_IN_PICTURE_CLOSE,
|
||||
id,
|
||||
});
|
||||
}
|
||||
|
||||
export function moveTo(id: Identifier, position: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PICTURE_IN_PICTURE_MOVE,
|
||||
id,
|
||||
position,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PictureInPictureActionCreators.js
|
38
509bba0_unpacked/discord_app/actions/PlatformAccountsActionCreators.js
Executable file
38
509bba0_unpacked/discord_app/actions/PlatformAccountsActionCreators.js
Executable file
|
@ -0,0 +1,38 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import {fetchAccounts} from '../lib/ContactImporter';
|
||||
|
||||
export default {
|
||||
detectAccounts(platformTypes: Array<string>, location?: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PLATFORM_ACCOUNTS_DETECTING,
|
||||
platformTypes,
|
||||
location,
|
||||
});
|
||||
|
||||
return fetchAccounts(platformTypes).then(accounts => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PLATFORM_ACCOUNTS_DETECTED,
|
||||
platformTypes,
|
||||
accounts,
|
||||
location,
|
||||
});
|
||||
return accounts;
|
||||
});
|
||||
},
|
||||
|
||||
ignore(platformTypes?: Array<string>) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PLATFORM_ACCOUNTS_IGNORE, platformTypes});
|
||||
},
|
||||
|
||||
changeDisplayType(displayType: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.DETECTED_PLATFORM_ACCOUNTS_DISPLAY_TYPE_CHANGE, displayType});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PlatformAccountsActionCreators.js
|
52
509bba0_unpacked/discord_app/actions/PopoutActionCreators.js
Executable file
52
509bba0_unpacked/discord_app/actions/PopoutActionCreators.js
Executable file
|
@ -0,0 +1,52 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import type {PopoutProps} from '../flow/Client';
|
||||
|
||||
export default {
|
||||
open(popout: PopoutProps) {
|
||||
// This is a Flux anti-pattern. Since popout trigger can be updated due to change
|
||||
// in text or position it will trigger and upodate and that update might be
|
||||
// happening during a dispatch that caused a re-render.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.POPOUT_OPEN,
|
||||
popout,
|
||||
});
|
||||
},
|
||||
|
||||
close(key?: number | string) {
|
||||
// This is a Flux anti-pattern. Since popout unmount can be triggered by
|
||||
// other Dispatcher actions we must force the hide to occur on the next tick
|
||||
// outside of the current dispatch.
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.POPOUT_CLOSE,
|
||||
key,
|
||||
});
|
||||
},
|
||||
|
||||
closeAll() {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.POPOUT_CLOSE_ALL,
|
||||
});
|
||||
},
|
||||
|
||||
rerender(key: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.POPOUT_NEEDS_RERENDER,
|
||||
key,
|
||||
});
|
||||
},
|
||||
|
||||
didRerender(key: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.POPOUT_DID_RERENDER,
|
||||
key,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PopoutActionCreators.js
|
14
509bba0_unpacked/discord_app/actions/PostConnectionCallbackActionCreators.js
Executable file
14
509bba0_unpacked/discord_app/actions/PostConnectionCallbackActionCreators.js
Executable file
|
@ -0,0 +1,14 @@
|
|||
/* @flow */
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
call(callback: Function): void {
|
||||
Dispatcher.dispatch({type: ActionTypes.POST_CONNECTION_PENDING_CALLBACK, callback});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PostConnectionCallbackActionCreators.js
|
24
509bba0_unpacked/discord_app/actions/PrivacySettingsModalActionCreators.js
Executable file
24
509bba0_unpacked/discord_app/actions/PrivacySettingsModalActionCreators.js
Executable file
|
@ -0,0 +1,24 @@
|
|||
/* @flow */
|
||||
|
||||
import {ActionTypes} from '../Constants';
|
||||
import Dispatcher from '../Dispatcher';
|
||||
|
||||
export default {
|
||||
open(guildId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRIVACY_SETTINGS_MODAL_OPEN,
|
||||
guildId,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRIVACY_SETTINGS_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PrivacySettingsModalActionCreators.js
|
19
509bba0_unpacked/discord_app/actions/PrivateChannelCallActionCreators.js
Executable file
19
509bba0_unpacked/discord_app/actions/PrivateChannelCallActionCreators.js
Executable file
|
@ -0,0 +1,19 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
selectParticipant(participantId: ?string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_CALL_SELECT_PARTICIPANT, participantId});
|
||||
},
|
||||
|
||||
updateLayout(channelId: string, layout: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_CALL_UPDATE_LAYOUT, channelId, layout});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PrivateChannelCallActionCreators.js
|
|
@ -0,0 +1,32 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import UserRecord from '../records/UserRecord';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
search(query: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_RECIPIENTS_INVITE_QUERY, query});
|
||||
},
|
||||
|
||||
clear() {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_RECIPIENTS_INVITE_QUERY, query: ''});
|
||||
},
|
||||
|
||||
select(row: number) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_RECIPIENTS_INVITE_SELECT, row});
|
||||
},
|
||||
|
||||
addUser(user: UserRecord) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_RECIPIENTS_ADD_USER, user});
|
||||
},
|
||||
|
||||
removeUser(user: UserRecord) {
|
||||
Dispatcher.dispatch({type: ActionTypes.PRIVATE_CHANNEL_RECIPIENTS_REMOVE_USER, user});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PrivateChannelRecipientsInviteActionCreators.js
|
56
509bba0_unpacked/discord_app/actions/PruneGuildModalActionCreators.js
Executable file
56
509bba0_unpacked/discord_app/actions/PruneGuildModalActionCreators.js
Executable file
|
@ -0,0 +1,56 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
open(guildId: string, days: number = 7) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRUNE_GUILD_MODAL_OPEN,
|
||||
guildId,
|
||||
days,
|
||||
estimate: 0,
|
||||
});
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.GUILD_PRUNE(guildId),
|
||||
query: {days},
|
||||
}).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRUNE_GUILD_MODAL_OPEN,
|
||||
guildId,
|
||||
days,
|
||||
estimate: res.body['pruned'],
|
||||
});
|
||||
},
|
||||
() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRUNE_GUILD_MODAL_OPEN,
|
||||
guildId,
|
||||
days,
|
||||
estimate: 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.PRUNE_GUILD_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
prune(guildId: string, days: number) {
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.GUILD_PRUNE(guildId),
|
||||
query: {days},
|
||||
});
|
||||
this.close();
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/PruneGuildModalActionCreators.js
|
195
509bba0_unpacked/discord_app/actions/QuickSwitcherActionCreators.js
Executable file
195
509bba0_unpacked/discord_app/actions/QuickSwitcherActionCreators.js
Executable file
|
@ -0,0 +1,195 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import ChannelStore from '../stores/ChannelStore';
|
||||
import DelayedSelectionActionCreators from '../actions/DelayedSelectionActionCreators';
|
||||
import SelectedChannelActionCreators from '../actions/SelectedChannelActionCreators';
|
||||
import DimensionActionCreators from '../actions/DimensionActionCreators';
|
||||
import ChannelActionCreators from '../actions/ChannelActionCreators';
|
||||
import SelectedChannelStore from '../stores/SelectedChannelStore';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
import QuickSwitcherStore from '../stores/QuickSwitcherStore';
|
||||
import SelectedGuildStore from '../stores/SelectedGuildStore';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
import {findNextSelected} from '../utils/QuickSwitcherUtils';
|
||||
import {ActionTypes, QuickSwitcherResultTypes, ME, AnalyticEvents} from '../Constants';
|
||||
import type {QuickSwitcherResult} from '../flow/Client';
|
||||
|
||||
function trackOpen(source) {
|
||||
if (QuickSwitcherStore.isOpen()) {
|
||||
return;
|
||||
}
|
||||
const guildId = SelectedGuildStore.getGuildId();
|
||||
const channelId = SelectedChannelStore.getChannelId(guildId);
|
||||
let channelType;
|
||||
if (channelId != null) {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
channelType = channel != null ? channel.type : null;
|
||||
}
|
||||
AnalyticsUtils.track(AnalyticEvents.QUICKSWITCHER_OPENED, {
|
||||
source,
|
||||
/* eslint-disable camelcase */
|
||||
current_guild_id: guildId,
|
||||
current_channel_id: channelId,
|
||||
current_channel_type: channelType,
|
||||
/* eslint-enable camelcase */
|
||||
});
|
||||
}
|
||||
|
||||
type QuickSwitcherCloseParams = {
|
||||
current_channel_id: ?string,
|
||||
current_channel_type?: ?number,
|
||||
current_guild_id: ?string,
|
||||
query_mode: string,
|
||||
query_length: number,
|
||||
top_result_type: ?string,
|
||||
top_result_score: ?number,
|
||||
num_results_total: number,
|
||||
num_results_users: number,
|
||||
num_results_text_channels: number,
|
||||
num_results_voice_channels: number,
|
||||
num_results_guilds: number,
|
||||
num_results_group_dms: number,
|
||||
selected_type?: string,
|
||||
selected_score?: number,
|
||||
selected_index?: number,
|
||||
selected_channel_id?: ?string,
|
||||
selected_guild_id?: ?string,
|
||||
selected_user_id?: string,
|
||||
};
|
||||
|
||||
function trackClose(event, result) {
|
||||
const {results, queryMode, query} = QuickSwitcherStore.getState();
|
||||
const guildId = SelectedGuildStore.getGuildId();
|
||||
const channelId = SelectedChannelStore.getChannelId(guildId);
|
||||
const initialResult = results[findNextSelected('down', -1, results)];
|
||||
const params: QuickSwitcherCloseParams = {
|
||||
/* eslint-disable camelcase */
|
||||
current_channel_id: channelId,
|
||||
current_guild_id: guildId,
|
||||
query_mode: queryMode ? queryMode : 'GENERAL',
|
||||
query_length: query.length,
|
||||
top_result_type: initialResult ? initialResult.type : null,
|
||||
top_result_score: initialResult ? initialResult.score : null,
|
||||
num_results_total: QuickSwitcherStore.getResultTotals(),
|
||||
num_results_users: QuickSwitcherStore.getResultTotals(QuickSwitcherResultTypes.USER),
|
||||
num_results_text_channels: QuickSwitcherStore.getResultTotals(QuickSwitcherResultTypes.TEXT_CHANNEL),
|
||||
num_results_voice_channels: QuickSwitcherStore.getResultTotals(QuickSwitcherResultTypes.VOICE_CHANNEL),
|
||||
num_results_guilds: QuickSwitcherStore.getResultTotals(QuickSwitcherResultTypes.GUILD),
|
||||
num_results_group_dms: QuickSwitcherStore.getResultTotals(QuickSwitcherResultTypes.GROUP_DM),
|
||||
/* eslint-enable camelcase */
|
||||
};
|
||||
if (channelId != null) {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
params['current_channel_type'] = channel != null ? channel.type : null;
|
||||
}
|
||||
if (result != null) {
|
||||
const {type, score, record} = result;
|
||||
params['selected_type'] = type;
|
||||
params['selected_score'] = score;
|
||||
params['selected_index'] = results.indexOf(result);
|
||||
switch (type) {
|
||||
case QuickSwitcherResultTypes.GUILD:
|
||||
params['selected_guild_id'] = record.id;
|
||||
break;
|
||||
case QuickSwitcherResultTypes.TEXT_CHANNEL:
|
||||
case QuickSwitcherResultTypes.VOICE_CHANNEL:
|
||||
params['selected_guild_id'] = record.guild_id;
|
||||
params['selected_channel_id'] = record.id;
|
||||
break;
|
||||
case QuickSwitcherResultTypes.GROUP_DM:
|
||||
params['selected_channel_id'] = record.id;
|
||||
break;
|
||||
case QuickSwitcherResultTypes.USER:
|
||||
params['selected_user_id'] = record.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AnalyticsUtils.track(event, params);
|
||||
}
|
||||
|
||||
function hideQuickSwitcher() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.QUICKSWITCHER_HIDE,
|
||||
});
|
||||
}
|
||||
|
||||
export function show(source: string = 'KEYBIND') {
|
||||
trackOpen(source);
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.QUICKSWITCHER_SHOW,
|
||||
});
|
||||
}
|
||||
|
||||
export function hide() {
|
||||
trackClose(AnalyticEvents.QUICKSWITCHER_CLOSED);
|
||||
hideQuickSwitcher();
|
||||
}
|
||||
|
||||
export function toggle(source: string = 'KEYBIND') {
|
||||
if (QuickSwitcherStore.isOpen()) {
|
||||
hide();
|
||||
} else {
|
||||
show(source);
|
||||
}
|
||||
}
|
||||
|
||||
export function search(query: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.QUICKSWITCHER_SEARCH,
|
||||
query,
|
||||
});
|
||||
}
|
||||
|
||||
export function selectResult(selectedIndex: number) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.QUICKSWITCHER_SELECT,
|
||||
selectedIndex,
|
||||
});
|
||||
}
|
||||
|
||||
export function switchToResult(result: QuickSwitcherResult) {
|
||||
trackClose(AnalyticEvents.QUICKSWITCHER_RESULT_SELECTED, result);
|
||||
const {type, record} = result;
|
||||
let channel;
|
||||
switch (type) {
|
||||
case QuickSwitcherResultTypes.GUILD:
|
||||
channel = SelectedChannelStore.getChannelId(record.id);
|
||||
if (channel) {
|
||||
DelayedSelectionActionCreators.selectChannel(record.id, channel);
|
||||
} else {
|
||||
DelayedSelectionActionCreators.selectGuild(record.id);
|
||||
}
|
||||
DelayedSelectionActionCreators.flushSelection(true);
|
||||
break;
|
||||
case QuickSwitcherResultTypes.TEXT_CHANNEL:
|
||||
channel = ChannelStore.getChannel(record.id);
|
||||
if (channel != null) {
|
||||
DelayedSelectionActionCreators.selectChannel(channel.guild_id, record.id);
|
||||
DelayedSelectionActionCreators.flushSelection(true);
|
||||
}
|
||||
break;
|
||||
case QuickSwitcherResultTypes.VOICE_CHANNEL:
|
||||
channel = ChannelStore.getChannel(record.id);
|
||||
if (channel != null) {
|
||||
SelectedChannelActionCreators.selectVoiceChannel(channel.guild_id, record.id);
|
||||
}
|
||||
break;
|
||||
case QuickSwitcherResultTypes.USER:
|
||||
ChannelActionCreators.openPrivateChannel(AuthenticationStore.getId(), [record.id]);
|
||||
DimensionActionCreators.channelListScrollTo(ME, record.id);
|
||||
break;
|
||||
case QuickSwitcherResultTypes.GROUP_DM:
|
||||
DelayedSelectionActionCreators.selectChannel(ME, record.id);
|
||||
DelayedSelectionActionCreators.flushSelection(true);
|
||||
DimensionActionCreators.channelListScrollTo(ME, record.id);
|
||||
break;
|
||||
}
|
||||
Dispatcher.dispatch({type: ActionTypes.QUICKSWITCHER_SWITCH_TO, result});
|
||||
hideQuickSwitcher();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/QuickSwitcherActionCreators.js
|
107
509bba0_unpacked/discord_app/actions/ReactionActionCreators.js
Executable file
107
509bba0_unpacked/discord_app/actions/ReactionActionCreators.js
Executable file
|
@ -0,0 +1,107 @@
|
|||
/* @flow */
|
||||
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import i18n from '../i18n';
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import AuthenticationStore from '../stores/AuthenticationStore';
|
||||
import AlertActionCreators from './AlertActionCreators';
|
||||
import {ComponentDispatch} from '../utils/ComponentDispatchUtils';
|
||||
import {Endpoints, ActionTypes, AbortCodes, ComponentActions} from '../Constants';
|
||||
|
||||
type ReactionEmoji = {id: ?string, name: string};
|
||||
|
||||
function checkReactionResponse(res, retry) {
|
||||
const {status, body} = res;
|
||||
if (status === 429) {
|
||||
// Rate limit on this endpoint is really low so just retry.
|
||||
setTimeout(retry, res.body['retry_after']);
|
||||
return false;
|
||||
} else if (status === 403) {
|
||||
switch (body && body.code) {
|
||||
case AbortCodes.TOO_MANY_REACTIONS:
|
||||
AlertActionCreators.show({
|
||||
title: i18n.Messages.TOO_MANY_REACTIONS_ALERT_HEADER,
|
||||
body: i18n.Messages.TOO_MANY_REACTIONS_ALERT_BODY,
|
||||
confirmText: i18n.Messages.OKAY,
|
||||
});
|
||||
break;
|
||||
case AbortCodes.REACTION_BLOCKED:
|
||||
ComponentDispatch.dispatch(ComponentActions.SHAKE_APP, {duration: 200, intensity: 2});
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function optimisticDispatch(
|
||||
type: 'MESSAGE_REACTION_ADD' | 'MESSAGE_REACTION_REMOVE',
|
||||
channelId: string,
|
||||
messageId: string,
|
||||
emoji: ReactionEmoji,
|
||||
userId?: string
|
||||
) {
|
||||
Dispatcher.dispatch({
|
||||
type,
|
||||
channelId,
|
||||
messageId,
|
||||
userId: userId || AuthenticationStore.getId(),
|
||||
emoji,
|
||||
optimistic: true,
|
||||
});
|
||||
}
|
||||
|
||||
function makeURL(channelId: string, messageId: string, emoji: ReactionEmoji, userId?: string): string {
|
||||
const emojiCode = encodeURIComponent(emoji.id != null ? `${emoji.name}:${emoji.id}` : emoji.name);
|
||||
return userId != null
|
||||
? Endpoints.REACTION(channelId, messageId, emojiCode, userId)
|
||||
: Endpoints.REACTIONS(channelId, messageId, emojiCode, userId);
|
||||
}
|
||||
|
||||
export function getReactions(channelId: string, messageId: string, emoji: ReactionEmoji, after?: string): Promise {
|
||||
return HTTPUtils.get({
|
||||
url: makeURL(channelId, messageId, emoji),
|
||||
query: {
|
||||
limit: 100,
|
||||
after: after,
|
||||
},
|
||||
}).then(res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.MESSAGE_REACTION_ADD_USERS,
|
||||
channelId,
|
||||
messageId,
|
||||
users: res.body,
|
||||
emoji,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
});
|
||||
}
|
||||
|
||||
export function addReaction(channelId: string, messageId: string, emoji: ReactionEmoji) {
|
||||
optimisticDispatch(ActionTypes.MESSAGE_REACTION_ADD, channelId, messageId, emoji);
|
||||
HTTPUtils.put(makeURL(channelId, messageId, emoji, '@me')).catch(res => {
|
||||
if (checkReactionResponse(res, () => addReaction(channelId, messageId, emoji))) {
|
||||
optimisticDispatch(ActionTypes.MESSAGE_REACTION_REMOVE, channelId, messageId, emoji);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function removeAllReactions(channelId: string, messageId: string) {
|
||||
HTTPUtils.delete(Endpoints.REMOVE_REACTIONS(channelId, messageId)).catch(res => {
|
||||
checkReactionResponse(res, () => removeAllReactions(channelId, messageId));
|
||||
});
|
||||
}
|
||||
|
||||
export function removeReaction(channelId: string, messageId: string, emoji: ReactionEmoji, userId?: string) {
|
||||
optimisticDispatch(ActionTypes.MESSAGE_REACTION_REMOVE, channelId, messageId, emoji, userId);
|
||||
HTTPUtils.delete(makeURL(channelId, messageId, emoji, userId || '@me')).catch(res => {
|
||||
if (checkReactionResponse(res, () => removeReaction(channelId, messageId, emoji, userId))) {
|
||||
optimisticDispatch(ActionTypes.MESSAGE_REACTION_ADD, channelId, messageId, emoji, userId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ReactionActionCreators.js
|
37
509bba0_unpacked/discord_app/actions/ReadStateActionCreators.js
Executable file
37
509bba0_unpacked/discord_app/actions/ReadStateActionCreators.js
Executable file
|
@ -0,0 +1,37 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
|
||||
export default {
|
||||
ack(channelId: string, immediate: boolean = false, force: boolean = false) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_ACK,
|
||||
channelId,
|
||||
immediate,
|
||||
force,
|
||||
});
|
||||
},
|
||||
|
||||
localAck(channelId: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.CHANNEL_LOCAL_ACK,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
manualAck(channelId: string, messageId: string) {
|
||||
HTTPUtils.post({
|
||||
url: `${Endpoints.MESSAGES(channelId)}/${messageId}/ack`,
|
||||
body: {
|
||||
manual: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ReadStateActionCreators.js
|
33
509bba0_unpacked/discord_app/actions/RegionActionCreators.js
Executable file
33
509bba0_unpacked/discord_app/actions/RegionActionCreators.js
Executable file
|
@ -0,0 +1,33 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
fetchDefaultRegions() {
|
||||
return this.fetchRegions(null);
|
||||
},
|
||||
|
||||
fetchRegions(guildId: ?string) {
|
||||
HTTPUtils.get({
|
||||
url: Endpoints.REGIONS(guildId),
|
||||
retries: 1,
|
||||
}).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOAD_REGIONS, regions: res.body, guildId}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.LOAD_REGIONS, regions: [], guildId})
|
||||
);
|
||||
},
|
||||
|
||||
changeCallRegion(channelId: string, region: string) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.CALL(channelId),
|
||||
body: {region},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/RegionActionCreators.js
|
88
509bba0_unpacked/discord_app/actions/RelationshipActionCreators.js
Executable file
88
509bba0_unpacked/discord_app/actions/RelationshipActionCreators.js
Executable file
|
@ -0,0 +1,88 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints, AbortCodes, UserSettingsSections} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import i18n from '../i18n';
|
||||
import AlertActionCreators from './AlertActionCreators';
|
||||
import UserSettingsModalActionCreators from './UserSettingsModalActionCreators';
|
||||
import UserProfileModalActionCreators from './UserProfileModalActionCreators';
|
||||
import ContextMenuActionCreators from './ContextMenuActionCreators';
|
||||
|
||||
function showAlert(options) {
|
||||
ContextMenuActionCreators.close();
|
||||
UserProfileModalActionCreators.close();
|
||||
AlertActionCreators.show(options);
|
||||
}
|
||||
|
||||
function checkRelationshipAddResponse(res) {
|
||||
const {status, body} = res;
|
||||
if (status === 429) {
|
||||
showAlert({
|
||||
title: i18n.Messages.FRIEND_REQUEST_RATE_LIMITED_HEADER,
|
||||
body: i18n.Messages.FRIEND_REQUEST_RATE_LIMITED_BODY,
|
||||
confirmText: i18n.Messages.FRIEND_REQUEST_RATE_LIMITED_BUTTON,
|
||||
});
|
||||
} else if (status === 403) {
|
||||
const code = body && body.code;
|
||||
if (code === AbortCodes.EMAIL_VERIFICATION_REQUIRED) {
|
||||
showAlert({
|
||||
title: i18n.Messages.FRIEND_REQUEST_REQUIRES_EMAIL_VALIDATION_HEADER,
|
||||
body: i18n.Messages.FRIEND_REQUEST_REQUIRES_EMAIL_VALIDATION_BODY,
|
||||
confirmText: i18n.Messages.FRIEND_REQUEST_REQUIRES_EMAIL_VALIDATION_BUTTON,
|
||||
onConfirm: () => {
|
||||
UserSettingsModalActionCreators.open(UserSettingsSections.ACCOUNT);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
throw res;
|
||||
}
|
||||
|
||||
type Context = {
|
||||
location: string,
|
||||
};
|
||||
|
||||
export default {
|
||||
sendRequest(discordTag: string, context?: Context): Promise<*> {
|
||||
let [username, discriminator] = discordTag.split('#');
|
||||
discriminator = parseInt(discriminator);
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.USER_RELATIONSHIPS(),
|
||||
body: {
|
||||
username,
|
||||
discriminator,
|
||||
},
|
||||
context,
|
||||
}).catch(checkRelationshipAddResponse);
|
||||
},
|
||||
|
||||
addRelationship(userId: string, context?: Context, type?: number) {
|
||||
HTTPUtils.put({
|
||||
url: `${Endpoints.USER_RELATIONSHIPS()}/${userId}`,
|
||||
body: {
|
||||
type,
|
||||
},
|
||||
context,
|
||||
}).catch(checkRelationshipAddResponse);
|
||||
},
|
||||
|
||||
removeRelationship(userId: string, context?: Context) {
|
||||
HTTPUtils.delete({
|
||||
url: `${Endpoints.USER_RELATIONSHIPS()}/${userId}`,
|
||||
context,
|
||||
});
|
||||
},
|
||||
|
||||
fetchRelationships() {
|
||||
HTTPUtils.get(Endpoints.USER_RELATIONSHIPS()).then(
|
||||
res => Dispatcher.dispatch({type: ActionTypes.LOAD_RELATIONSHIPS_SUCCESS, relationships: res.body}),
|
||||
() => Dispatcher.dispatch({type: ActionTypes.LOAD_RELATIONSHIPS_FAILURE})
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/RelationshipActionCreators.js
|
32
509bba0_unpacked/discord_app/actions/ReportModalActionCreators.js
Executable file
32
509bba0_unpacked/discord_app/actions/ReportModalActionCreators.js
Executable file
|
@ -0,0 +1,32 @@
|
|||
/* @flow */
|
||||
|
||||
import {Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
type ReportData = {
|
||||
guild_id?: ?string,
|
||||
message_id?: ?string,
|
||||
user_id?: ?string,
|
||||
reason?: ?number,
|
||||
};
|
||||
|
||||
export default {
|
||||
report(body: ReportData) {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.REPORT,
|
||||
body,
|
||||
});
|
||||
},
|
||||
|
||||
getReasons(query: ReportData) {
|
||||
return HTTPUtils.get({
|
||||
url: Endpoints.REPORT,
|
||||
query,
|
||||
}).then(res => res.body);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/ReportModalActionCreators.js
|
121
509bba0_unpacked/discord_app/actions/SearchActionCreators.js
Executable file
121
509bba0_unpacked/discord_app/actions/SearchActionCreators.js
Executable file
|
@ -0,0 +1,121 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import SearchStore from '../stores/SearchStore';
|
||||
import AppAnalyticsUtils from '../utils/AppAnalyticsUtils';
|
||||
import GuildNSFWAgreeStore from '../stores/GuildNSFWAgreeStore';
|
||||
import {ActionTypes, SEARCH_PAGE_SIZE} from '../Constants';
|
||||
import type {SearchQuery} from '../flow/Server';
|
||||
import type {EditorState} from 'draft-js';
|
||||
import type {Token} from '../lib/QueryTokenizer';
|
||||
import type {CursorScope} from '../flow/Client';
|
||||
|
||||
export function search(searchId: string, query: SearchQuery, queryString: ?string) {
|
||||
if (GuildNSFWAgreeStore.didAgree(searchId)) {
|
||||
// eslint-disable-next-line camelcase
|
||||
query.include_nsfw = true;
|
||||
}
|
||||
const modifierKeys = Object.keys(query);
|
||||
AppAnalyticsUtils.trackWithMetadata('search_started', {
|
||||
/* eslint-disable camelcase */
|
||||
prev_search_id: SearchStore.getAnalyticsId(searchId),
|
||||
num_modifiers: modifierKeys.length,
|
||||
/* eslint-enable camelcase */
|
||||
modifiers: modifierKeys.reduce((acc, k) => {
|
||||
const modifierValue = query[k];
|
||||
acc[k] = Array.isArray(modifierValue) ? modifierValue.length : 1;
|
||||
return acc;
|
||||
}, {}),
|
||||
});
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.SEARCH_START,
|
||||
query,
|
||||
searchId,
|
||||
queryString,
|
||||
});
|
||||
}
|
||||
|
||||
export function searchByMode(searchId: string, sortBy: string) {
|
||||
const query = SearchStore.getQuery(searchId);
|
||||
return search(searchId, {
|
||||
...query,
|
||||
offset: 0,
|
||||
// eslint-disable-next-line camelcase
|
||||
sort_by: sortBy,
|
||||
});
|
||||
}
|
||||
|
||||
export function searchNextPage(searchId: string, numResults: number = SEARCH_PAGE_SIZE) {
|
||||
return searchPage(searchId, numResults);
|
||||
}
|
||||
|
||||
export function searchPreviousPage(searchId: string, numResults: number = SEARCH_PAGE_SIZE) {
|
||||
return searchPage(searchId, -numResults);
|
||||
}
|
||||
|
||||
function searchPage(searchId: string, numResults: number) {
|
||||
const currentOffset = SearchStore.getOffset(searchId);
|
||||
const query = SearchStore.getQuery(searchId);
|
||||
const offset = currentOffset + numResults;
|
||||
const totalResults = SearchStore.getTotalResults(searchId);
|
||||
|
||||
if (offset < 0 || offset > totalResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
return search(searchId, {
|
||||
...query,
|
||||
offset,
|
||||
});
|
||||
}
|
||||
|
||||
export function clearHistory(searchId: ?string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.SEARCH_CLEAR_HISTORY, searchId});
|
||||
}
|
||||
|
||||
export function ensureSearchState(searchId: ?string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.SEARCH_ENSURE_SEARCH_STATE, searchId});
|
||||
}
|
||||
|
||||
export function setSearchState(searchId: ?string, editorState: EditorState) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.SEARCH_EDITOR_STATE_CHANGE,
|
||||
searchId,
|
||||
editorState,
|
||||
});
|
||||
}
|
||||
|
||||
export function clearSearchState(searchId: string) {
|
||||
AppAnalyticsUtils.trackWithMetadata('search_closed', {
|
||||
// eslint-disable-next-line camelcase
|
||||
search_id: SearchStore.getAnalyticsId(searchId),
|
||||
});
|
||||
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.SEARCH_EDITOR_STATE_CLEAR,
|
||||
searchId,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAutocompleteQuery(searchId: ?string, tokens: Array<Token>, cursorScope: ?CursorScope) {
|
||||
// This can be fired under various circumstances we cannot control
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.SEARCH_AUTOCOMPLETE_QUERY_UPDATE,
|
||||
searchId,
|
||||
tokens,
|
||||
cursorScope,
|
||||
});
|
||||
}
|
||||
|
||||
export function setShowBlockedResults(searchId: string, showBlocked: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.SEARCH_SET_SHOW_BLOCKED_RESULTS,
|
||||
searchId,
|
||||
showBlocked,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/SearchActionCreators.js
|
46
509bba0_unpacked/discord_app/actions/SelectedChannelActionCreators.js
Executable file
46
509bba0_unpacked/discord_app/actions/SelectedChannelActionCreators.js
Executable file
|
@ -0,0 +1,46 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import MediaEngineStore from '../stores/MediaEngineStore';
|
||||
import {ActionTypes, ME, Routes} from '../Constants';
|
||||
import RouterUtils from '../utils/RouterUtils';
|
||||
|
||||
export default {
|
||||
selectChannel(guildId: ?string, channelId: ?string, messageId?: string) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.CHANNEL_SELECT,
|
||||
guildId: guildId === ME ? null : guildId,
|
||||
channelId,
|
||||
messageId,
|
||||
});
|
||||
},
|
||||
|
||||
selectPrivateChannel(channelId: string) {
|
||||
// TODO: remove this once RouterUtils is resolved iOS and Web
|
||||
if (__WEB__) {
|
||||
RouterUtils.transitionTo(Routes.CHANNEL(ME, channelId));
|
||||
} else {
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.GUILD_SELECT, guildId: null});
|
||||
this.selectChannel(ME, channelId);
|
||||
}
|
||||
},
|
||||
|
||||
selectVoiceChannel(guildId: ?string, channelId: ?string) {
|
||||
if (MediaEngineStore.isSupported()) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.VOICE_CHANNEL_SELECT,
|
||||
guildId,
|
||||
channelId,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
clearVoiceChannel() {
|
||||
Dispatcher.dispatch({type: ActionTypes.VOICE_CHANNEL_CLEAR});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/SelectedChannelActionCreators.js
|
45
509bba0_unpacked/discord_app/actions/StatusPageActionCreators.js
Executable file
45
509bba0_unpacked/discord_app/actions/StatusPageActionCreators.js
Executable file
|
@ -0,0 +1,45 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
const BASE_MAINTENANCES_URL = 'https://status.discordapp.com/api/v2/scheduled-maintenances';
|
||||
const INCIDENTS_URL = 'https://status.discordapp.com/api/v2/incidents/unresolved.json';
|
||||
|
||||
export default {
|
||||
checkIncidents() {
|
||||
Promise.all([
|
||||
HTTPUtils.get(`${BASE_MAINTENANCES_URL}/active.json`),
|
||||
HTTPUtils.get(INCIDENTS_URL),
|
||||
]).then(([res1, res2]) => {
|
||||
const [maintenance] = res1.body['scheduled_maintenances'];
|
||||
const [incident] = res2.body['incidents'];
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.STATUS_PAGE_INCIDENT,
|
||||
incident: incident || maintenance,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
checkScheduledMaintenances() {
|
||||
HTTPUtils.get(`${BASE_MAINTENANCES_URL}/upcoming.json`).then(res => {
|
||||
const [maintenance] = res.body['scheduled_maintenances'];
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.STATUS_PAGE_SCHEDULED_MAINTENANCE,
|
||||
maintenance,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
ackScheduledMaintenance() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.STATUS_PAGE_SCHEDULED_MAINTENANCE_ACK,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/StatusPageActionCreators.js
|
34
509bba0_unpacked/discord_app/actions/StreamerModeActionCreators.js
Executable file
34
509bba0_unpacked/discord_app/actions/StreamerModeActionCreators.js
Executable file
|
@ -0,0 +1,34 @@
|
|||
/* @flow */
|
||||
|
||||
import {ActionTypes} from '../Constants';
|
||||
import Dispatcher from '../Dispatcher';
|
||||
|
||||
export type StreamerModeOptions = {
|
||||
enabled?: boolean,
|
||||
autoToggle?: boolean,
|
||||
hidePersonalInformation?: boolean,
|
||||
hideInstantInvites?: boolean,
|
||||
disableSounds?: boolean,
|
||||
disableNotifications?: boolean,
|
||||
};
|
||||
|
||||
export default {
|
||||
setEnabled(enabled: boolean) {
|
||||
this.update({enabled});
|
||||
},
|
||||
|
||||
update(settings: StreamerModeOptions) {
|
||||
for (const key of Object.keys(settings)) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.STREAMER_MODE_UPDATE,
|
||||
key,
|
||||
value: ((settings[key]: any): boolean),
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/StreamerModeActionCreators.js
|
44
509bba0_unpacked/discord_app/actions/TextMessageFormActionCreators.js
Executable file
44
509bba0_unpacked/discord_app/actions/TextMessageFormActionCreators.js
Executable file
|
@ -0,0 +1,44 @@
|
|||
/* @flow */
|
||||
|
||||
import lodash from 'lodash';
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
const delayedReset = lodash.debounce(() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.TEXT_MESSAGE_DOWNLOAD_LINK_RESET});
|
||||
}, 3000);
|
||||
|
||||
export default {
|
||||
sendTextLink(phoneNumber: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.TEXT_MESSAGE_DOWNLOAD_LINK_SUBMITTING,
|
||||
});
|
||||
|
||||
HTTPUtils.post({
|
||||
url: Endpoints.MOBILE_TEXT_LINK,
|
||||
body: {
|
||||
phone_number: phoneNumber, // eslint-disable-line camelcase
|
||||
},
|
||||
}).then(
|
||||
() => {
|
||||
Dispatcher.dispatch({type: ActionTypes.TEXT_MESSAGE_DOWNLOAD_LINK_SUCCESS});
|
||||
delayedReset.cancel();
|
||||
delayedReset();
|
||||
},
|
||||
response => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.TEXT_MESSAGE_DOWNLOAD_LINK_FAILURE,
|
||||
errors: response ? response.body.message : [['Something went wrong']],
|
||||
});
|
||||
delayedReset.cancel();
|
||||
delayedReset();
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/TextMessageFormActionCreators.js
|
35
509bba0_unpacked/discord_app/actions/TooltipActionCreators.js
Executable file
35
509bba0_unpacked/discord_app/actions/TooltipActionCreators.js
Executable file
|
@ -0,0 +1,35 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export type TooltipProps = {
|
||||
position: string,
|
||||
text: string,
|
||||
type: string,
|
||||
targetWidth: number,
|
||||
targetHeight: number,
|
||||
x: number,
|
||||
y: number,
|
||||
};
|
||||
|
||||
export default {
|
||||
show(id: number, tooltip: TooltipProps) {
|
||||
// This is a Flux anti-pattern. Since tooltip trigger can be updated due to change
|
||||
// in text or position it will trigger and upodate and that update might be
|
||||
// happening during a dispatch that caused a re-render.
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.TOOLTIP_SHOW, id, tooltip});
|
||||
},
|
||||
|
||||
hide(id: number) {
|
||||
// This is a Flux anti-pattern. Since tooltip unmount can be triggered by
|
||||
// other Dispatcher actions we must force the hide to occur on the next tick
|
||||
// outside of the current dispatch.
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.TOOLTIP_HIDE, id});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/TooltipActionCreators.js
|
34
509bba0_unpacked/discord_app/actions/TutorialActionCreators.js
Executable file
34
509bba0_unpacked/discord_app/actions/TutorialActionCreators.js
Executable file
|
@ -0,0 +1,34 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
show(tutorialId: string, renderData: any) {
|
||||
// This is a Flux anti-pattern. We need to be able to dispatch while we're mounting in response
|
||||
// to a dispatch.
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.TUTORIAL_INDICATOR_SHOW, tutorialId, renderData});
|
||||
},
|
||||
|
||||
hide(tutorialId: string) {
|
||||
// This is a Flux anti-pattern. We need to be able to dispatch while we're unmounting in response
|
||||
// to a dispatch.
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.TUTORIAL_INDICATOR_HIDE, tutorialId});
|
||||
},
|
||||
|
||||
dismiss(tutorialId: string) {
|
||||
Dispatcher.dispatch({type: ActionTypes.TUTORIAL_INDICATOR_DISMISS, tutorialId});
|
||||
HTTPUtils.put(`${Endpoints.TUTORIAL_INDICATORS}/${tutorialId}`);
|
||||
},
|
||||
|
||||
suppressAll() {
|
||||
Dispatcher.dispatch({type: ActionTypes.TUTORIAL_INDICATOR_SUPPRESS_ALL});
|
||||
HTTPUtils.post(`${Endpoints.TUTORIAL_INDICATORS}/suppress`);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/TutorialActionCreators.js
|
15
509bba0_unpacked/discord_app/actions/TypingActionCreators.js
Executable file
15
509bba0_unpacked/discord_app/actions/TypingActionCreators.js
Executable file
|
@ -0,0 +1,15 @@
|
|||
/* @flow */
|
||||
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import {Endpoints} from '../Constants';
|
||||
|
||||
export default {
|
||||
sendTyping(channelId: string) {
|
||||
HTTPUtils.post(Endpoints.TYPING(channelId));
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/TypingActionCreators.js
|
15
509bba0_unpacked/discord_app/actions/UploadActionCreators.js
Executable file
15
509bba0_unpacked/discord_app/actions/UploadActionCreators.js
Executable file
|
@ -0,0 +1,15 @@
|
|||
/* @flow */
|
||||
|
||||
let UploadActionCreators = {};
|
||||
if (__IOS__) {
|
||||
UploadActionCreators = require('./ios/UploadActionCreators');
|
||||
} else {
|
||||
UploadActionCreators = require('./web/UploadActionCreators');
|
||||
}
|
||||
|
||||
export default UploadActionCreators;
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UploadActionCreators.js
|
29
509bba0_unpacked/discord_app/actions/UploadModalActionCreators.js
Executable file
29
509bba0_unpacked/discord_app/actions/UploadModalActionCreators.js
Executable file
|
@ -0,0 +1,29 @@
|
|||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
popFirstFile() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.UPLOAD_MODAL_POP_FILE,
|
||||
});
|
||||
},
|
||||
|
||||
pushFiles({files, channelId}: {files: Array<File>, channelId: string}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.UPLOAD_MODAL_PUSH_FILES,
|
||||
files,
|
||||
channelId,
|
||||
});
|
||||
},
|
||||
|
||||
clearAll() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.UPLOAD_MODAL_CLEAR_ALL_FILES,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UploadModalActionCreators.js
|
19
509bba0_unpacked/discord_app/actions/UserActionCreators.js
Executable file
19
509bba0_unpacked/discord_app/actions/UserActionCreators.js
Executable file
|
@ -0,0 +1,19 @@
|
|||
/* @flow */
|
||||
|
||||
import {Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export function acceptAgreements(terms: boolean = true, privacy: boolean = true): Promise<boolean> {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.USER_AGREEMENTS,
|
||||
body: {
|
||||
terms,
|
||||
privacy,
|
||||
},
|
||||
}).then(() => true, () => false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UserActionCreators.js
|
72
509bba0_unpacked/discord_app/actions/UserProfileModalActionCreators.js
Executable file
72
509bba0_unpacked/discord_app/actions/UserProfileModalActionCreators.js
Executable file
|
@ -0,0 +1,72 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import UserStore from '../stores/UserStore';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
|
||||
function fetchProfile(userId) {
|
||||
HTTPUtils.get(Endpoints.USER_PROFILE(userId)).then(
|
||||
res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_FETCH_SUCCESS,
|
||||
...res.body,
|
||||
});
|
||||
},
|
||||
({body}) => console.warn(`fetchProfile error: ${body.code} - ${body.message}`)
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
open(userId: string) {
|
||||
if (!UserStore.getUser(userId).bot) {
|
||||
fetchProfile(userId);
|
||||
}
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_OPEN,
|
||||
userId,
|
||||
});
|
||||
},
|
||||
|
||||
push(userId: string) {
|
||||
fetchProfile(userId);
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_PUSH,
|
||||
userId,
|
||||
});
|
||||
},
|
||||
|
||||
pop() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_POP,
|
||||
});
|
||||
},
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
setSection(section: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_PROFILE_MODAL_SET_SECTION,
|
||||
section,
|
||||
});
|
||||
},
|
||||
|
||||
fetchMutualFriends(userId: string) {
|
||||
HTTPUtils.get(Endpoints.USER_RELATIONSHIPS(userId)).then(res => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.LOAD_MUTUAL_FRIENDS,
|
||||
userId,
|
||||
mutualFriends: res.body,
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UserProfileModalActionCreators.js
|
105
509bba0_unpacked/discord_app/actions/UserSettingsAccountActionCreators.js
Executable file
105
509bba0_unpacked/discord_app/actions/UserSettingsAccountActionCreators.js
Executable file
|
@ -0,0 +1,105 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import i18n from '../i18n';
|
||||
import {ActionTypes, Endpoints, DEVICE_TOKEN, DEVICE_PUSH_PROVIDER} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import mfaInterceptor from '../utils/MFAInterceptionUtils';
|
||||
import Storage from '../lib/Storage';
|
||||
import {hasAnimatedAvatar} from '../utils/AvatarUtils';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
|
||||
export function accountDetailsInit() {
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_ACCOUNT_INIT});
|
||||
}
|
||||
|
||||
export function accountDetailsClose() {
|
||||
// This has to be dirty, since it could be firing at the same time as logout
|
||||
Dispatcher.dirtyDispatch({type: ActionTypes.USER_SETTINGS_ACCOUNT_CLOSE});
|
||||
}
|
||||
|
||||
export function toggleEditingProfile(isEditingProfile: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_ACCOUNT_TOGGLE_EDITING_PROFILE,
|
||||
isEditingProfile,
|
||||
});
|
||||
}
|
||||
|
||||
export function toggleEditingPassword(isEditingPassword: boolean) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_ACCOUNT_TOGGLE_EDITING_PASSWORD,
|
||||
isEditingPassword,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAccountInfo(update: {[key: string]: ?string}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_ACCOUNT_UPDATE_INFO,
|
||||
update,
|
||||
});
|
||||
}
|
||||
|
||||
export function saveAccountChanges(
|
||||
username: string,
|
||||
email: string,
|
||||
password: string,
|
||||
avatar: ?string,
|
||||
newPassword: ?string
|
||||
) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_ACCOUNT_SUBMIT,
|
||||
});
|
||||
|
||||
mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.TWO_FA_CHANGE_ACCOUNT,
|
||||
},
|
||||
extraBody => {
|
||||
const body = {
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
avatar,
|
||||
// eslint-disable-next-line camelcase
|
||||
new_password: newPassword,
|
||||
...extraBody,
|
||||
};
|
||||
// Only send these values if we have them.
|
||||
const pushToken = Storage.get(DEVICE_TOKEN);
|
||||
if (DEVICE_PUSH_PROVIDER != null && pushToken != null) {
|
||||
body['push_provider'] = DEVICE_PUSH_PROVIDER;
|
||||
body['push_token'] = pushToken;
|
||||
}
|
||||
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.ME,
|
||||
body,
|
||||
});
|
||||
},
|
||||
{
|
||||
// Only open mfa modal if the server wants the code. In this case, we do not want to optimistically open it.
|
||||
checkEnabled: false,
|
||||
hooks: {
|
||||
onEarlyClose: () => Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_ACCOUNT_SUBMIT_FAILURE, errors: {}}),
|
||||
},
|
||||
}
|
||||
).then(
|
||||
res => {
|
||||
const user = res.body;
|
||||
const token = user.token;
|
||||
AnalyticsUtils.track('user_avatar_updated', {animated: hasAnimatedAvatar(user)});
|
||||
delete user.token;
|
||||
Dispatcher.dispatch({type: ActionTypes.UPDATE_TOKEN, token});
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_UPDATE, user});
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_ACCOUNT_SUBMIT_SUCCESS});
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_ACCOUNT_SUBMIT_FAILURE, errors: res.body});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UserSettingsAccountActionCreators.js
|
68
509bba0_unpacked/discord_app/actions/UserSettingsActionCreators.js
Executable file
68
509bba0_unpacked/discord_app/actions/UserSettingsActionCreators.js
Executable file
|
@ -0,0 +1,68 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import type {UserSettings} from '../flow/Server';
|
||||
|
||||
const KEY_MAPPING = {
|
||||
showCurrentGame: 'show_current_game',
|
||||
inlineAttachmentMedia: 'inline_attachment_media',
|
||||
inlineEmbedMedia: 'inline_embed_media',
|
||||
renderEmbeds: 'render_embeds',
|
||||
renderReactions: 'render_reactions',
|
||||
sync: 'sync',
|
||||
theme: 'theme',
|
||||
enableTTSCommand: 'enable_tts_command',
|
||||
messageDisplayCompact: 'message_display_compact',
|
||||
locale: 'locale',
|
||||
convertEmoticons: 'convert_emoticons',
|
||||
restrictedGuilds: 'restricted_guilds',
|
||||
friendSourceFlags: 'friend_source_flags',
|
||||
developerMode: 'developer_mode',
|
||||
guildPositions: 'guild_positions',
|
||||
detectPlatformAccounts: 'detect_platform_accounts',
|
||||
status: 'status',
|
||||
explicitContentFilter: 'explicit_content_filter',
|
||||
defaultGuildsRestricted: 'default_guilds_restricted',
|
||||
afkTimeout: 'afk_timeout',
|
||||
};
|
||||
|
||||
type OpaqueSettings = {[key: string]: any};
|
||||
|
||||
function convertKeys(settings: OpaqueSettings, reverse: boolean): OpaqueSettings {
|
||||
const convertedSettings = {};
|
||||
for (const camelKey of Object.keys(KEY_MAPPING)) {
|
||||
const snakeKey = KEY_MAPPING[camelKey];
|
||||
const value = settings[reverse ? snakeKey : camelKey];
|
||||
if (value != null) {
|
||||
convertedSettings[reverse ? camelKey : snakeKey] = value;
|
||||
}
|
||||
}
|
||||
return convertedSettings;
|
||||
}
|
||||
|
||||
export default {
|
||||
updateLocalSettings(settings: OpaqueSettings, convert: boolean = false) {
|
||||
if (convert) {
|
||||
settings = convertKeys(settings, true);
|
||||
}
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_UPDATE,
|
||||
settings,
|
||||
});
|
||||
},
|
||||
|
||||
updateRemoteSettings(settings: UserSettings) {
|
||||
HTTPUtils.patch({
|
||||
url: Endpoints.SETTINGS,
|
||||
body: convertKeys(settings, false),
|
||||
});
|
||||
this.updateLocalSettings(settings);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UserSettingsActionCreators.js
|
122
509bba0_unpacked/discord_app/actions/UserSettingsModalActionCreators.js
Executable file
122
509bba0_unpacked/discord_app/actions/UserSettingsModalActionCreators.js
Executable file
|
@ -0,0 +1,122 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import i18n from '../i18n';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
import mfaInterceptor from '../utils/MFAInterceptionUtils';
|
||||
import Storage from '../lib/Storage';
|
||||
import {hasAnimatedAvatar} from '../utils/AvatarUtils';
|
||||
import AnalyticsUtils from '../utils/AnalyticsUtils';
|
||||
import {pushLayer} from './LayerActionCreators';
|
||||
import {ActionTypes, Endpoints, DEVICE_TOKEN, DEVICE_PUSH_PROVIDER, Layers} from '../Constants';
|
||||
|
||||
function init(section: ?string = null, subsection: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_INIT,
|
||||
section,
|
||||
subsection,
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
open(section: ?string = null, subsection: ?string = null) {
|
||||
if (__IOS__) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_OPEN,
|
||||
section,
|
||||
subsection,
|
||||
});
|
||||
} else {
|
||||
init(section, subsection);
|
||||
pushLayer(Layers.USER_SETTINGS);
|
||||
}
|
||||
},
|
||||
|
||||
init,
|
||||
|
||||
close() {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_CLOSE,
|
||||
});
|
||||
},
|
||||
|
||||
setSection(section: string, subsection: ?string = null) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_SET_SECTION,
|
||||
section,
|
||||
subsection,
|
||||
});
|
||||
},
|
||||
|
||||
updateAccount(settings: {
|
||||
username?: string,
|
||||
email?: string,
|
||||
password?: string,
|
||||
newPassword?: ?string,
|
||||
avatar?: ?string,
|
||||
}) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_UPDATE_ACCOUNT,
|
||||
settings,
|
||||
});
|
||||
},
|
||||
|
||||
saveAccountChanges(username: string, email: string, password: string, avatar: string, newPassword: string) {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.USER_SETTINGS_MODAL_SUBMIT,
|
||||
});
|
||||
|
||||
mfaInterceptor(
|
||||
{
|
||||
title: i18n.Messages.TWO_FA_CHANGE_ACCOUNT,
|
||||
},
|
||||
extraBody => {
|
||||
const body = {
|
||||
username,
|
||||
email,
|
||||
password,
|
||||
avatar,
|
||||
// eslint-disable-next-line camelcase
|
||||
new_password: newPassword,
|
||||
...extraBody,
|
||||
};
|
||||
// Only send these values if we have them.
|
||||
const pushToken = Storage.get(DEVICE_TOKEN);
|
||||
if (DEVICE_PUSH_PROVIDER != null && pushToken != null) {
|
||||
body['push_provider'] = DEVICE_PUSH_PROVIDER;
|
||||
body['push_token'] = pushToken;
|
||||
}
|
||||
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.ME,
|
||||
body,
|
||||
});
|
||||
},
|
||||
{
|
||||
// Only open mfa modal if the server wants the code. In this case, we do not want to optimistically open it.
|
||||
checkEnabled: false,
|
||||
hooks: {
|
||||
onEarlyClose: () => Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_MODAL_SUBMIT_FAILURE, errors: {}}),
|
||||
},
|
||||
}
|
||||
).then(
|
||||
res => {
|
||||
const user = res.body;
|
||||
const token = user.token;
|
||||
AnalyticsUtils.track('user_avatar_updated', {animated: hasAnimatedAvatar(user)});
|
||||
delete user.token;
|
||||
Dispatcher.dispatch({type: ActionTypes.UPDATE_TOKEN, token});
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_UPDATE, user});
|
||||
this.close(true);
|
||||
},
|
||||
res => {
|
||||
Dispatcher.dispatch({type: ActionTypes.USER_SETTINGS_MODAL_SUBMIT_FAILURE, errors: res.body});
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/UserSettingsModalActionCreators.js
|
88
509bba0_unpacked/discord_app/actions/WebhooksActionCreators.js
Executable file
88
509bba0_unpacked/discord_app/actions/WebhooksActionCreators.js
Executable file
|
@ -0,0 +1,88 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes, Endpoints} from '../Constants';
|
||||
import HTTPUtils from '../utils/HTTPUtils';
|
||||
|
||||
export default {
|
||||
fetchForGuild(guildId: string): void {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.WEBHOOKS_FETCHING,
|
||||
guildId,
|
||||
});
|
||||
HTTPUtils.get(Endpoints.GUILD_WEBHOOKS(guildId))
|
||||
.then(({body}) =>
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOKS_UPDATE,
|
||||
guildId,
|
||||
webhooks: body,
|
||||
})
|
||||
)
|
||||
.catch(({body}) => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOKS_UPDATE,
|
||||
guildId,
|
||||
error: body.message,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
fetchForChannel(guildId: string, channelId: string): void {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.WEBHOOKS_FETCHING,
|
||||
guildId,
|
||||
channelId,
|
||||
});
|
||||
HTTPUtils.get(Endpoints.CHANNEL_WEBHOOKS(channelId)).then(({body}) =>
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOKS_UPDATE,
|
||||
guildId,
|
||||
channelId,
|
||||
webhooks: body,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
create(guildId: string, channelId: string, body: Object): Promise {
|
||||
return HTTPUtils.post({
|
||||
url: Endpoints.CHANNEL_WEBHOOKS(channelId),
|
||||
body,
|
||||
}).then(({body}) => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOK_CREATE,
|
||||
guildId,
|
||||
webhook: body,
|
||||
});
|
||||
return body;
|
||||
});
|
||||
},
|
||||
|
||||
delete(guildId: string, webhookId: string): Promise {
|
||||
return HTTPUtils.delete(Endpoints.WEBHOOK(webhookId)).then(() => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOK_DELETE,
|
||||
guildId,
|
||||
webhookId,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
update(guildId: string, webhookId: string, body: Object): Promise {
|
||||
return HTTPUtils.patch({
|
||||
url: Endpoints.WEBHOOK(webhookId),
|
||||
body,
|
||||
}).then(({body}) => {
|
||||
Dispatcher.dispatch({
|
||||
type: ActionTypes.WEBHOOK_UPDATE,
|
||||
guildId,
|
||||
webhook: body,
|
||||
});
|
||||
return body;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/WebhooksActionCreators.js
|
24
509bba0_unpacked/discord_app/actions/WindowActionCreators.js
Executable file
24
509bba0_unpacked/discord_app/actions/WindowActionCreators.js
Executable file
|
@ -0,0 +1,24 @@
|
|||
/* @flow */
|
||||
|
||||
import Dispatcher from '../Dispatcher';
|
||||
import {ActionTypes} from '../Constants';
|
||||
|
||||
export default {
|
||||
focus(focused: boolean) {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.WINDOW_FOCUS,
|
||||
focused,
|
||||
});
|
||||
},
|
||||
|
||||
resized() {
|
||||
Dispatcher.dirtyDispatch({
|
||||
type: ActionTypes.WINDOW_RESIZED,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/WindowActionCreators.js
|
54
509bba0_unpacked/discord_app/actions/web/AlertActionCreators.js
Executable file
54
509bba0_unpacked/discord_app/actions/web/AlertActionCreators.js
Executable file
|
@ -0,0 +1,54 @@
|
|||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import ModalActionCreators from '../ModalActionCreators';
|
||||
import Alert from '../../components/Alert';
|
||||
|
||||
export default {
|
||||
show({
|
||||
title,
|
||||
body,
|
||||
confirmText,
|
||||
cancelText,
|
||||
onConfirm,
|
||||
onCancel,
|
||||
iconUrl,
|
||||
minorText,
|
||||
onConfirmSecondary,
|
||||
className,
|
||||
}: {
|
||||
title: string,
|
||||
body: string,
|
||||
confirmText: string,
|
||||
cancelText: string,
|
||||
onConfirm: Function,
|
||||
onCancel: Function,
|
||||
iconUrl: string,
|
||||
minorText: string,
|
||||
onConfirmSecondary: Function,
|
||||
className: string,
|
||||
}) {
|
||||
ModalActionCreators.push(props => {
|
||||
return (
|
||||
<Alert
|
||||
{...props}
|
||||
title={title}
|
||||
body={body}
|
||||
confirmText={confirmText}
|
||||
cancelText={cancelText}
|
||||
onConfirm={onConfirm}
|
||||
onCancel={onCancel}
|
||||
iconUrl={iconUrl}
|
||||
minorText={minorText}
|
||||
onConfirmSecondary={onConfirmSecondary}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_app/actions/web/AlertActionCreators.js
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue