Add files
This commit is contained in:
commit
bb80829159
18195 changed files with 2122994 additions and 0 deletions
94
509bba0_unpacked/discord_common/js/Constants.js
Executable file
94
509bba0_unpacked/discord_common/js/Constants.js
Executable file
|
@ -0,0 +1,94 @@
|
|||
/* @flow */
|
||||
import ColorGenerator from './config/colors';
|
||||
|
||||
export const Colors = {
|
||||
// Brand
|
||||
BRAND_PURPLE: '#7289DA',
|
||||
BRAND_PURPLE_TRANSPARENT: '#7289DA00',
|
||||
HINT_PURPLE: '#c9d2f0',
|
||||
DARK_PURPLE: '#697ec4',
|
||||
|
||||
// Status
|
||||
STATUS_RED: '#f04747',
|
||||
STATUS_GREEN: '#43b581',
|
||||
STATUS_YELLOW: '#faa61a',
|
||||
STATUS_GREY: '#747f8d',
|
||||
|
||||
// Lights
|
||||
WHITE: '#ffffff',
|
||||
WHITE1: '#f9f9f9',
|
||||
WHITE2: '#f3f3f3',
|
||||
WHITE3: '#f0f0f0',
|
||||
WHITE4: '#eceeef',
|
||||
WHITE5: '#ebebeb',
|
||||
WHITE6: '#e9e7e7',
|
||||
WHITE7: '#dbdde1',
|
||||
WHITE8: '#cdcdcd',
|
||||
WHITE9: '#737F8D',
|
||||
PLACEHOLDER: '#dadddf',
|
||||
PLACEHOLDER2: '#74787d',
|
||||
MODAL_GREY: '#EFEFF4',
|
||||
|
||||
// Darks
|
||||
BLACK: '#000000',
|
||||
ORANGE: '#f57731',
|
||||
GUILDS_GREY: '#1e2124',
|
||||
CHANNELS_GREY: '#2e3136',
|
||||
ACCOUNT_GREY: '#282b30',
|
||||
CHAT_GREY: '#36393e',
|
||||
UNREAD_GREY: '#8a8e94',
|
||||
HIGHLIGHT_GREY: '#25282c',
|
||||
AVATAR_GREY: '#747F8C',
|
||||
DARK_GREY: '#677179',
|
||||
GREY1: '#99aab5',
|
||||
GREY2: '#87909c',
|
||||
GREY3: '#737f8d',
|
||||
GREY4: '#949494',
|
||||
GREY5: '#535559',
|
||||
GREY6: '#4f545c',
|
||||
GREY7: '#1c242b',
|
||||
GREY8: '#575d66',
|
||||
GREY9: '#202226',
|
||||
|
||||
DARK1: '#030303',
|
||||
LINK: '#00b0f4',
|
||||
|
||||
...ColorGenerator()
|
||||
};
|
||||
|
||||
export const Fonts = {
|
||||
PRIMARY_LIGHT: 'Whitney-Light',
|
||||
PRIMARY_BOLD: 'Whitney-Bold',
|
||||
PRIMARY_SEMIBOLD: 'Whitney-Semibold',
|
||||
PRIMARY_REGULAR: 'Whitney-Book',
|
||||
PRIMARY: 'Whitney-Medium'
|
||||
};
|
||||
|
||||
export const RECAPTCHA_SITE_KEY = '6Lef5iQTAAAAAKeIvIY-DeexoO3gj7ryl9rLMEnn';
|
||||
|
||||
export const OAuth2Scopes = {
|
||||
IDENTIFY: 'identify',
|
||||
EMAIL: 'email',
|
||||
CONNECTIONS: 'connections',
|
||||
GUILDS: 'guilds',
|
||||
GUILDS_JOIN: 'guilds.join',
|
||||
GDM_JOIN: 'gdm.join',
|
||||
RPC: 'rpc',
|
||||
RPC_API: 'rpc.api',
|
||||
RPC_NOTIFICATIONS_READ: 'rpc.notifications.read',
|
||||
BOT: 'bot',
|
||||
WEBHOOK_INCOMING: 'webhook.incoming',
|
||||
MESSAGES_READ: 'messages.read'
|
||||
};
|
||||
|
||||
export default {
|
||||
Colors,
|
||||
Fonts,
|
||||
RECAPTCHA_SITE_KEY,
|
||||
OAuth2Scopes
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/Constants.js
|
83
509bba0_unpacked/discord_common/js/components/FileInput.js
Executable file
83
509bba0_unpacked/discord_common/js/components/FileInput.js
Executable file
|
@ -0,0 +1,83 @@
|
|||
import React from 'react';
|
||||
|
||||
const CLASSNAME = 'file-input';
|
||||
const STYLE = disabled => ({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
opacity: 0,
|
||||
cursor: disabled ? 'not-allowed' : 'pointer'
|
||||
});
|
||||
|
||||
const FileInput = React.createClass({
|
||||
propTypes: {
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
multiple: React.PropTypes.bool,
|
||||
filters: React.PropTypes.arrayOf(React.PropTypes.shape({
|
||||
name: React.PropTypes.string.isRequired,
|
||||
extensions: React.PropTypes.arrayOf(React.PropTypes.string)
|
||||
})),
|
||||
embedded: React.PropTypes.bool,
|
||||
handleNativeClick: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
multiple: false,
|
||||
disabled: false
|
||||
};
|
||||
},
|
||||
|
||||
activateUploadDialogue() {
|
||||
if (this.props.embedded) {
|
||||
this.handleNativeClick();
|
||||
}
|
||||
// Not sure if better way?
|
||||
else if (this._input) {
|
||||
this._input.click();
|
||||
}
|
||||
},
|
||||
|
||||
handleNativeClick() {
|
||||
this.props.handleNativeClick(this.props);
|
||||
},
|
||||
|
||||
handleBrowserInputMouseDown(e) {
|
||||
e.target.value = null;
|
||||
},
|
||||
|
||||
render() {
|
||||
const {disabled} = this.props;
|
||||
// Electron's input[type="file"] does not open on a separate thread and lock's up the app,
|
||||
// instead use the Electron's custom file dialog.
|
||||
if (this.props.embedded) {
|
||||
return <div style={STYLE(disabled)}
|
||||
className={CLASSNAME}
|
||||
onClick={!disabled && this.handleNativeClick} />;
|
||||
}
|
||||
else {
|
||||
let accept;
|
||||
if (this.props.filters) {
|
||||
accept = this.props.filters.map(filter => filter.extensions.map(ext => `.${ext}`).join(',')).join(',');
|
||||
}
|
||||
return <input style={STYLE(disabled)}
|
||||
className={CLASSNAME}
|
||||
disabled={disabled}
|
||||
type="file"
|
||||
onMouseDown={this.handleBrowserInputMouseDown}
|
||||
onChange={this.props.onChange}
|
||||
multiple={this.props.multiple}
|
||||
accept={accept}
|
||||
ref={node => this._input = node} />;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default FileInput;
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/components/FileInput.js
|
28
509bba0_unpacked/discord_common/js/config/colors/BaseColors.js
Executable file
28
509bba0_unpacked/discord_common/js/config/colors/BaseColors.js
Executable file
|
@ -0,0 +1,28 @@
|
|||
module.exports = {
|
||||
PRIMARY: '#4f545c',
|
||||
BRAND: '#7289DA',
|
||||
|
||||
STATUS_RED: '#f04747',
|
||||
STATUS_YELLOW: '#faa61a',
|
||||
STATUS_GREEN: '#43b581',
|
||||
STATUS_GREY: '#747f8d',
|
||||
|
||||
LINK: '#00b0f4',
|
||||
WHITE: '#ffffff',
|
||||
BLACK: '#000000',
|
||||
|
||||
// Other brands
|
||||
SKYPE: '#009DD7',
|
||||
BATTLENET: '#009AE5',
|
||||
STEAM: '#182332',
|
||||
LOL: '#021F25',
|
||||
TWITCH: '#593695',
|
||||
YOUTUBE: '#CB2120',
|
||||
TWITTER: '#1DA1F2',
|
||||
REDDIT: '#5F99CF'
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/config/colors/BaseColors.js
|
17
509bba0_unpacked/discord_common/js/config/colors/ColorScales.js
Executable file
17
509bba0_unpacked/discord_common/js/config/colors/ColorScales.js
Executable file
|
@ -0,0 +1,17 @@
|
|||
module.exports = {
|
||||
'100': 0.95,
|
||||
'200': 0.80,
|
||||
'300': 0.60,
|
||||
'400': 0.20,
|
||||
'500': 0,
|
||||
'600': -0.32,
|
||||
'630': -0.411,
|
||||
'700': -0.60,
|
||||
'800': -0.70,
|
||||
'900': -0.95
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/config/colors/ColorScales.js
|
36
509bba0_unpacked/discord_common/js/config/colors/index.js
Executable file
36
509bba0_unpacked/discord_common/js/config/colors/index.js
Executable file
|
@ -0,0 +1,36 @@
|
|||
const BaseColors = require('./BaseColors');
|
||||
const ColorScales = require('./ColorScales');
|
||||
const ColorFunctions = require('../../utils/ColorFunctions');
|
||||
|
||||
const ColorGenerator = (forCSS=false) => {
|
||||
const Colors = {};
|
||||
|
||||
for (const color in BaseColors) {
|
||||
for (const scale in ColorScales) {
|
||||
const computedColor = ColorFunctions.lightness(ColorScales[scale], BaseColors[color]);
|
||||
|
||||
let colorName;
|
||||
if (forCSS) {
|
||||
colorName = color.replace(/_/g, '-').toLowerCase();
|
||||
Colors[`${colorName}-${scale}`] = computedColor;
|
||||
}
|
||||
else {
|
||||
colorName = color;
|
||||
Colors[`${colorName}_${scale}`] = computedColor;
|
||||
}
|
||||
|
||||
if (scale === '500') {
|
||||
Colors[colorName] = computedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Colors;
|
||||
};
|
||||
|
||||
module.exports = ColorGenerator;
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/config/colors/index.js
|
62
509bba0_unpacked/discord_common/js/containers/connectStores.js
Executable file
62
509bba0_unpacked/discord_common/js/containers/connectStores.js
Executable file
|
@ -0,0 +1,62 @@
|
|||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import shallowEqual from '../lib/shallowEqual';
|
||||
|
||||
type ReactClass<DefaultProps, Props> = Class<React.Component<DefaultProps, Props, *>>;
|
||||
|
||||
interface Store {
|
||||
addChangeListener(callback: Function): void;
|
||||
removeChangeListener(callback: Function): void;
|
||||
}
|
||||
|
||||
function getDisplayName(Component: ReactClass): string {
|
||||
return Component.displayName || Component.name || 'Component';
|
||||
}
|
||||
|
||||
export default function connectStores<DefaultProps, Props, State: Object>(
|
||||
stores: Array<Store>,
|
||||
getStateFromStores: (props: Props) => State
|
||||
): (Component: ReactClass<DefaultProps, Props>) => ReactClass<DefaultProps, $Diff<Props, State>> {
|
||||
return Component => {
|
||||
return class extends React.Component<*, *, *> {
|
||||
static displayName = `FluxContainer(${getDisplayName(Component)})`;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = getStateFromStores(props);
|
||||
|
||||
// $FlowFixMe: Flow does not like rebinding of instance methods.
|
||||
this._handleStoreChange = this._handleStoreChange.bind(this);
|
||||
}
|
||||
|
||||
_handleStoreChange() {
|
||||
this.setState(getStateFromStores(this.props));
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
stores.forEach(store => store.addChangeListener(this._handleStoreChange));
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Props) {
|
||||
if (!shallowEqual(this.props, nextProps)) {
|
||||
this.setState(getStateFromStores(nextProps));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
stores.forEach(store => store.removeChangeListener(this._handleStoreChange));
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Component {...this.props} {...this.state} />;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/containers/connectStores.js
|
199
509bba0_unpacked/discord_common/js/containers/makeDraggable.js
Executable file
199
509bba0_unpacked/discord_common/js/containers/makeDraggable.js
Executable file
|
@ -0,0 +1,199 @@
|
|||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {DragSource, DropTarget} from 'react-dnd';
|
||||
import Styles from './makeDraggable.mod.css';
|
||||
|
||||
type Props = {
|
||||
onHover?: Function,
|
||||
onDragStart?: Function,
|
||||
onDragLeave?: Function,
|
||||
onCancel?: Function,
|
||||
onDrop?: Function,
|
||||
children: any,
|
||||
isOver: boolean,
|
||||
didDrop: boolean,
|
||||
connectDropTarget: Function
|
||||
};
|
||||
|
||||
const dragSource = {
|
||||
beginDrag({dragId}, monitor, component) {
|
||||
const {onDragStart, onHover, onDrop} = component.context;
|
||||
onDragStart(dragId);
|
||||
return {dragId, onDragStart, onHover, onDrop};
|
||||
},
|
||||
|
||||
endDrag(props, monitor) {
|
||||
const {onDrop} = monitor.getItem();
|
||||
onDrop(monitor.getDropResult());
|
||||
}
|
||||
};
|
||||
|
||||
const dropTarget = {
|
||||
drop({dragId}) {
|
||||
return {dragId};
|
||||
},
|
||||
|
||||
hover({dragId}, monitor) {
|
||||
const {onHover} = monitor.getItem();
|
||||
onHover(dragId);
|
||||
}
|
||||
};
|
||||
|
||||
function dragCollect(connect, monitor) {
|
||||
return {
|
||||
connectDragPreview: connect.dragPreview(),
|
||||
connectDragSource: connect.dragSource(),
|
||||
isDragging: monitor.isDragging()
|
||||
};
|
||||
}
|
||||
|
||||
function dropCollect(connect, _monitor) {
|
||||
return {
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
};
|
||||
}
|
||||
|
||||
export function makeDragItem(TYPE: string) {
|
||||
// $FlowFixMe - I will need to properly annotate this later
|
||||
return Component => {
|
||||
return DropTarget(
|
||||
TYPE,
|
||||
dropTarget,
|
||||
dropCollect
|
||||
)(DragSource(
|
||||
TYPE,
|
||||
dragSource,
|
||||
dragCollect
|
||||
)(class extends React.Component {
|
||||
static draggable = true;
|
||||
static defaultProps = {
|
||||
dragClass: ''
|
||||
};
|
||||
static contextTypes = {
|
||||
onHover: React.PropTypes.func,
|
||||
onDragStart: React.PropTypes.func,
|
||||
onDrop: React.PropTypes.func,
|
||||
};
|
||||
|
||||
// This is required to not get babel transformed
|
||||
componentDidMount() {}
|
||||
|
||||
render() {
|
||||
const {
|
||||
connectDropTarget,
|
||||
connectDragPreview,
|
||||
connectDragSource,
|
||||
isDragging,
|
||||
dragClass,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
connectDropTarget(
|
||||
connectDragSource(
|
||||
<div className={classNames(Styles.draggable, {[dragClass]: isDragging})}>
|
||||
<Component
|
||||
isDragging={isDragging}
|
||||
connectDragPreview={connectDragPreview}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
export function makeDragList(TYPE: string) {
|
||||
// $FlowFixMe - I will need to properly annotate this later
|
||||
return Component => {
|
||||
return DropTarget(TYPE, {}, (connect, monitor) => {
|
||||
return {
|
||||
connectDropTarget: connect.dropTarget(),
|
||||
isOver: monitor.isOver(),
|
||||
didDrop: monitor.didDrop()
|
||||
};
|
||||
})(class extends React.PureComponent {
|
||||
props: Props;
|
||||
_dragging: ?string;
|
||||
|
||||
static childContextTypes = {
|
||||
onHover: React.PropTypes.func,
|
||||
onDragStart: React.PropTypes.func,
|
||||
onDrop: React.PropTypes.func,
|
||||
};
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
onHover: this.handleHover,
|
||||
onDragStart: this.handleDragStart,
|
||||
onDrop: this.handleDrop
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {onDragLeave, isOver, didDrop} = this.props;
|
||||
if (
|
||||
prevProps.isOver !== isOver &&
|
||||
isOver === false &&
|
||||
didDrop === false
|
||||
) {
|
||||
onDragLeave && onDragLeave();
|
||||
}
|
||||
}
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
(this: any).handleHover = this.handleHover.bind(this);
|
||||
(this: any).handleDragStart = this.handleDragStart.bind(this);
|
||||
(this: any).handleDrop = this.handleDrop.bind(this);
|
||||
}
|
||||
|
||||
handleHover(dragId: string) {
|
||||
if (dragId === this._dragging) {
|
||||
return;
|
||||
}
|
||||
const {onHover} = this.props;
|
||||
onHover && onHover(dragId, this._dragging);
|
||||
}
|
||||
|
||||
handleDragStart(dragging: string) {
|
||||
if (dragging === this._dragging) {
|
||||
return;
|
||||
}
|
||||
this._dragging = dragging;
|
||||
const {onDragStart} = this.props;
|
||||
onDragStart && onDragStart(dragging);
|
||||
}
|
||||
|
||||
handleDrop(dropTarget: {dragId: string}) {
|
||||
this._dragging = null;
|
||||
const {onCancel, onDrop} = this.props;
|
||||
if (dropTarget) {
|
||||
onDrop && onDrop(dropTarget);
|
||||
}
|
||||
else {
|
||||
onCancel && onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {connectDropTarget, ...props} = this.props;
|
||||
return connectDropTarget(
|
||||
<div>
|
||||
<Component {...props} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/containers/makeDraggable.js
|
9
509bba0_unpacked/discord_common/js/containers/makeDraggable.mod.css
Executable file
9
509bba0_unpacked/discord_common/js/containers/makeDraggable.mod.css
Executable file
|
@ -0,0 +1,9 @@
|
|||
// removed by extract-text-webpack-plugin
|
||||
module.exports = {"draggable":"draggable-2aWBFf"};
|
||||
|
||||
|
||||
//////////////////
|
||||
// WEBPACK FOOTER
|
||||
// ./discord_common/js/containers/makeDraggable.mod.css
|
||||
// module id = 2121
|
||||
// module chunks = 2
|
213
509bba0_unpacked/discord_common/js/i18n/index.js
Executable file
213
509bba0_unpacked/discord_common/js/i18n/index.js
Executable file
|
@ -0,0 +1,213 @@
|
|||
/* @flow */
|
||||
|
||||
import lodash from 'lodash';
|
||||
import moment from 'moment';
|
||||
import {getMessage} from './parse';
|
||||
|
||||
const DEFAULT_LOCALE = 'en-US';
|
||||
|
||||
let chosenLocale: string;
|
||||
let Languages = [];
|
||||
const Messages = {};
|
||||
let _getMessages;
|
||||
let _didSetLocale;
|
||||
|
||||
if (__IOS__) {
|
||||
// $FlowFixMe
|
||||
require('intl');
|
||||
}
|
||||
|
||||
function findMessages(locale) {
|
||||
try {
|
||||
return _getMessages(locale);
|
||||
}
|
||||
catch (e) {
|
||||
console.warn('unsupported locale', locale);
|
||||
if (locale.indexOf('-') === -1) {
|
||||
return findMessages(DEFAULT_LOCALE);
|
||||
}
|
||||
else {
|
||||
return findMessages(locale.split('-')[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadMessagesForLocale(locale, messagesRecur, prefix) {
|
||||
const messages = messagesRecur || findMessages(locale);
|
||||
for (const key in messages) {
|
||||
const message = messages[key];
|
||||
if (typeof message == 'object') {
|
||||
loadMessagesForLocale(locale, message, key);
|
||||
continue;
|
||||
}
|
||||
else if (message.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
addToMessages(prefix, key, getMessage(message, locale));
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(`Failed parsing intl key '${key}' in locale '${locale}' defaulting to English`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addToMessages(prefix, key, message) {
|
||||
if (prefix) {
|
||||
if (Messages[prefix]) {
|
||||
Messages[prefix][key] = message;
|
||||
}
|
||||
else {
|
||||
Messages[prefix] = {[key]: message};
|
||||
}
|
||||
}
|
||||
else {
|
||||
Messages[key] = message;
|
||||
}
|
||||
}
|
||||
|
||||
function setLocale(locale: string) {
|
||||
if (chosenLocale === locale) return;
|
||||
const oldLocale = chosenLocale;
|
||||
chosenLocale = locale;
|
||||
|
||||
for (const key of Object.keys(Messages)) {
|
||||
delete Messages[key];
|
||||
}
|
||||
|
||||
loadMessagesForLocale(DEFAULT_LOCALE);
|
||||
|
||||
if (locale !== DEFAULT_LOCALE) {
|
||||
loadMessagesForLocale(locale);
|
||||
}
|
||||
|
||||
moment.locale([chosenLocale, DEFAULT_LOCALE]);
|
||||
if (_didSetLocale) {
|
||||
_didSetLocale(chosenLocale, oldLocale);
|
||||
}
|
||||
}
|
||||
|
||||
function getSystemLocale(): ?string {
|
||||
let locale;
|
||||
if (__IOS__) {
|
||||
// $FlowFixMe
|
||||
const localizationManager = require('react-native').NativeModules.LocalizationManager;
|
||||
if (localizationManager != null) {
|
||||
locale = localizationManager.Language;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// $FlowFixMe
|
||||
const browserChosenLanguage = navigator.languages ? navigator.languages[0] : null;
|
||||
// $FlowFixMe
|
||||
locale = browserChosenLanguage || navigator.language || navigator.browserLanguage || navigator.userLanguage;
|
||||
}
|
||||
// $FlowFixMe
|
||||
return locale;
|
||||
}
|
||||
|
||||
function getDefaultLocale() {
|
||||
let locale = getSystemLocale();
|
||||
|
||||
locale = locale || DEFAULT_LOCALE;
|
||||
|
||||
const locales = Languages.filter(({enabled}) => enabled).map(({code}) => code);
|
||||
|
||||
if (locales.indexOf(locale) !== -1) {
|
||||
return locale;
|
||||
}
|
||||
|
||||
const [language] = locale.split('-');
|
||||
if (locales.indexOf(language) !== -1) {
|
||||
return language;
|
||||
}
|
||||
|
||||
locale = lodash.find(locales, l => {
|
||||
return l.indexOf('-') && l.split('-')[0] == locale;
|
||||
});
|
||||
|
||||
if (locale) {
|
||||
return locale;
|
||||
}
|
||||
|
||||
return DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
function getAvailableLocales() {
|
||||
const availableLocales = Languages.filter(({enabled}) => enabled).map(({code, name}) => {
|
||||
return {
|
||||
value: code,
|
||||
name,
|
||||
localizedName: Messages[code] || name
|
||||
};
|
||||
});
|
||||
availableLocales.sort(({name: a}, {name: b}) => {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
});
|
||||
return availableLocales;
|
||||
}
|
||||
|
||||
function getLocaleInfo() {
|
||||
return lodash.find(Languages, lan => lan.code == chosenLocale);
|
||||
}
|
||||
|
||||
type Language = {
|
||||
name: string,
|
||||
englishName: string,
|
||||
code: string,
|
||||
enabled: boolean
|
||||
};
|
||||
|
||||
type InitOptions = {
|
||||
initalLocale?: string,
|
||||
getMessages: (locale: string) => {[key: string]: any},
|
||||
getLanguages: () => Array<Language>,
|
||||
didSetLocale: (locale: string) => void
|
||||
};
|
||||
|
||||
function init({initalLocale, getMessages, getLanguages, didSetLocale}: InitOptions) {
|
||||
// $FlowFixMe
|
||||
if (Intl.__addLocaleData) {
|
||||
// $FlowFixMe
|
||||
Intl.__addLocaleData(require('intl/locale-data/json/en'));
|
||||
}
|
||||
|
||||
_getMessages = getMessages;
|
||||
Languages = getLanguages();
|
||||
_didSetLocale = didSetLocale;
|
||||
setLocale(initalLocale || getDefaultLocale());
|
||||
}
|
||||
|
||||
export type i18nType<Messages: Object> = {
|
||||
init(options: InitOptions): void,
|
||||
Messages: {[key: $Keys<Messages>]: any},
|
||||
getAvailableLocales(): Array<{value: string, name: string, localizedName: string}>,
|
||||
getLocale(): string,
|
||||
getLocaleInfo(locale: string): ?Language,
|
||||
getDefaultLocale(): string,
|
||||
setLocale(locale: string): void,
|
||||
getSystemLocale(): ?string,
|
||||
getLanguages(): Array<Language>,
|
||||
translationSiteURL: string
|
||||
};
|
||||
|
||||
export default {
|
||||
init,
|
||||
Messages: (Messages: any),
|
||||
getAvailableLocales,
|
||||
getLocale: () => chosenLocale,
|
||||
getLocaleInfo,
|
||||
getDefaultLocale,
|
||||
setLocale,
|
||||
getSystemLocale,
|
||||
getLanguages: () => Languages,
|
||||
translationSiteURL: 'https://i18n.discordapp.com'
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/i18n/index.js
|
142
509bba0_unpacked/discord_common/js/i18n/parse.js
Executable file
142
509bba0_unpacked/discord_common/js/i18n/parse.js
Executable file
|
@ -0,0 +1,142 @@
|
|||
import IntlMessageFormat from 'intl-messageformat';
|
||||
import SimpleMarkdown from 'simple-markdown';
|
||||
|
||||
const FORMAT_RE = /\{.+?}/;
|
||||
const MARKDOWN_RE = /[~*_]{2}.+?[~*_]{2}|\[.+?]\(.+?\)|\n\n/;
|
||||
const UNSAFE_RE = /!!/;
|
||||
const UNSAFE_RE_ALL = /!!/g;
|
||||
|
||||
let updateRules = rules => rules;
|
||||
if (__IOS__) {
|
||||
updateRules = require('./updateRules.ios');
|
||||
}
|
||||
else if (__WEB__ && !__SDK__) {
|
||||
updateRules = require('./updateRules.web');
|
||||
}
|
||||
|
||||
function parserFor(rules) {
|
||||
const parser = SimpleMarkdown.parserFor(updateRules(rules));
|
||||
const output = SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules, 'react'));
|
||||
return function(str, context, unsafeContext) {
|
||||
const inline = str.indexOf('\n\n') === -1;
|
||||
if (!inline) {
|
||||
str += '\n\n';
|
||||
}
|
||||
return output(parser(str, {inline, context, unsafeContext}));
|
||||
};
|
||||
}
|
||||
|
||||
function parserForNonReact(rules) {
|
||||
const parser = SimpleMarkdown.parserFor(rules);
|
||||
return function(str, context, unsafeContext) {
|
||||
return parser(str + '\n\n', {inline: false, context, unsafeContext});
|
||||
};
|
||||
}
|
||||
|
||||
const linkRule = SimpleMarkdown.defaultRules.link;
|
||||
const rules = {
|
||||
newline: SimpleMarkdown.defaultRules.newline,
|
||||
paragraph: SimpleMarkdown.defaultRules.paragraph,
|
||||
url: SimpleMarkdown.defaultRules.url,
|
||||
link: {
|
||||
...linkRule,
|
||||
|
||||
parse(capture, parse, state) {
|
||||
const node = linkRule.parse(capture, parse, state);
|
||||
node.context = state.context;
|
||||
return node;
|
||||
}
|
||||
},
|
||||
strong: SimpleMarkdown.defaultRules.strong,
|
||||
u: SimpleMarkdown.defaultRules.u,
|
||||
br: SimpleMarkdown.defaultRules.br,
|
||||
em: SimpleMarkdown.defaultRules.em,
|
||||
|
||||
hook: {
|
||||
order: SimpleMarkdown.defaultRules.text.order,
|
||||
match: SimpleMarkdown.inlineRegex(/^\$\[(.*?)\]\((\w+)\)/),
|
||||
|
||||
parse(capture, parse, state) {
|
||||
const {context} = state;
|
||||
return {
|
||||
render: context[capture[2]],
|
||||
content: parse(capture[1], state)
|
||||
};
|
||||
},
|
||||
|
||||
react(node, output, state) {
|
||||
return node.render(output(node.content, state), state.key);
|
||||
}
|
||||
},
|
||||
|
||||
noparse: {
|
||||
order: SimpleMarkdown.defaultRules.text.order,
|
||||
|
||||
match: SimpleMarkdown.inlineRegex(/^!!(\d+?)!!/),
|
||||
|
||||
parse(capture, parse, {unsafeContext}) {
|
||||
return {
|
||||
type: 'text',
|
||||
content: unsafeContext[capture[1]]
|
||||
};
|
||||
},
|
||||
|
||||
react(node) {
|
||||
return node.content;
|
||||
}
|
||||
},
|
||||
text: SimpleMarkdown.defaultRules.text
|
||||
};
|
||||
|
||||
const parse = parserFor(rules);
|
||||
const parseForNonReact = parserForNonReact(rules);
|
||||
|
||||
function getMessage(str, locale) {
|
||||
if (str == null) {
|
||||
return str;
|
||||
}
|
||||
|
||||
str = str.replace(/^\n+|\n+$/g, '');
|
||||
|
||||
const hasMarkdown = MARKDOWN_RE.test(str);
|
||||
|
||||
if (FORMAT_RE.test(str) || hasMarkdown) {
|
||||
if (!hasMarkdown) {
|
||||
str = str.replace(UNSAFE_RE_ALL, '');
|
||||
}
|
||||
const intlMessage = new IntlMessageFormat(str, locale);
|
||||
if (hasMarkdown) {
|
||||
const originalFormat = intlMessage.format;
|
||||
const unsafe = UNSAFE_RE.test(str);
|
||||
intlMessage.format = (context={}, react=true) => {
|
||||
const unsafeContext = {};
|
||||
if (unsafe) {
|
||||
let i = 0;
|
||||
for (const key of Object.keys(context)) {
|
||||
const value = context[key];
|
||||
if (typeof value === 'string') {
|
||||
unsafeContext[++i] = value;
|
||||
context[key] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!react) {
|
||||
return parseForNonReact(originalFormat(context), context, unsafeContext);
|
||||
}
|
||||
return parse(originalFormat(context), context, unsafeContext);
|
||||
};
|
||||
intlMessage.plainFormat = originalFormat;
|
||||
}
|
||||
return intlMessage;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
export default {
|
||||
getMessage
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/i18n/parse.js
|
36
509bba0_unpacked/discord_common/js/i18n/updateRules.web.js
Executable file
36
509bba0_unpacked/discord_common/js/i18n/updateRules.web.js
Executable file
|
@ -0,0 +1,36 @@
|
|||
import React from 'react';
|
||||
import SimpleMarkdown from 'simple-markdown';
|
||||
|
||||
export default function updateRules(rules) {
|
||||
rules.paragraph.react = (node, output, state) => {
|
||||
return <p key={state.key}>{output(node.content, state)}</p>;
|
||||
};
|
||||
rules.link.react = (node, output, state) => {
|
||||
const props = {};
|
||||
|
||||
if (node.context != null) {
|
||||
const handlers = node.context[node.target];
|
||||
|
||||
if (handlers && handlers.onClick) {
|
||||
props.onClick = handlers.onClick;
|
||||
props.onContextMenu = handlers.onContextMenu;
|
||||
}
|
||||
else {
|
||||
props.onClick = handlers;
|
||||
}
|
||||
}
|
||||
|
||||
if (props.onClick == null) {
|
||||
props.href = SimpleMarkdown.sanitizeUrl(node.target);
|
||||
props.target = '_blank';
|
||||
}
|
||||
|
||||
return <a key={state.key} title={node.title} {...props}>{output(node.content, state)}</a>;
|
||||
};
|
||||
return rules;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/i18n/updateRules.web.js
|
91
509bba0_unpacked/discord_common/js/lib/DevToolsListener.js
Executable file
91
509bba0_unpacked/discord_common/js/lib/DevToolsListener.js
Executable file
|
@ -0,0 +1,91 @@
|
|||
import {EventEmitter} from 'events';
|
||||
|
||||
const THRESHOLD = 160;
|
||||
const INTERVAL = 500;
|
||||
|
||||
const ORIENTATIONS = {
|
||||
VERTICAL: 'vertical',
|
||||
HORIZONTAL: 'horizontal'
|
||||
};
|
||||
|
||||
let devTools = {
|
||||
open: false,
|
||||
orientation: null
|
||||
};
|
||||
|
||||
function hasFirebug() {
|
||||
try {
|
||||
return window.Firebug.chrome.isInitialized;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function widthDifference() {
|
||||
try {
|
||||
return window.outerWidth - window.innerWidth;
|
||||
}
|
||||
catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function heightDifference() {
|
||||
try {
|
||||
return window.outerHeight - window.innerHeight;
|
||||
}
|
||||
catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class DevToolsListener extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
setInterval(() => this.check(), INTERVAL);
|
||||
}
|
||||
|
||||
get orientations() {
|
||||
return Object.values(ORIENTATIONS);
|
||||
}
|
||||
|
||||
get state() {
|
||||
return devTools;
|
||||
}
|
||||
|
||||
check() {
|
||||
const widthThreshold = widthDifference() > THRESHOLD;
|
||||
const heightThreshold = heightDifference() > THRESHOLD;
|
||||
const orientation = widthThreshold ? ORIENTATIONS.VERTICAL : ORIENTATIONS.HORIZONTAL;
|
||||
|
||||
if (
|
||||
!(heightThreshold && widthThreshold) &&
|
||||
(hasFirebug() || widthThreshold || heightThreshold)
|
||||
) {
|
||||
const open = devTools.open;
|
||||
|
||||
devTools = {
|
||||
open: true,
|
||||
orientation
|
||||
};
|
||||
|
||||
if (!open || devTools.orientation !== orientation) {
|
||||
this.emit('changed', devTools);
|
||||
}
|
||||
}
|
||||
else if (devTools.open) {
|
||||
devTools.open = false;
|
||||
|
||||
this.emit('changed', devTools);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DevToolsListener;
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/lib/DevToolsListener.js
|
23
509bba0_unpacked/discord_common/js/lib/XSSDefenses.js
Executable file
23
509bba0_unpacked/discord_common/js/lib/XSSDefenses.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
export function consoleWarning(messages) {
|
||||
console.log(
|
||||
`%c${messages.SELF_XSS_HEADER}`,
|
||||
'color: #7289DA; -webkit-text-stroke: 2px black; font-size: 72px; font-weight: bold;'
|
||||
);
|
||||
console.log(
|
||||
`%c${messages.SELF_XSS_LINE_1}`,
|
||||
'font-size: 16px;'
|
||||
);
|
||||
console.log(
|
||||
`%c${messages.SELF_XSS_LINE_2}`,
|
||||
'font-size: 18px; font-weight: bold; color: red;'
|
||||
);
|
||||
console.log(
|
||||
`%c${messages.SELF_XSS_LINE_3}`,
|
||||
'font-size: 16px;'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/lib/XSSDefenses.js
|
29
509bba0_unpacked/discord_common/js/lib/shallowEqual.js
Executable file
29
509bba0_unpacked/discord_common/js/lib/shallowEqual.js
Executable file
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Shallow compare to objects with the option to ignore certain keys.
|
||||
*/
|
||||
export default function shallowEqual(a: Object, b: Object, ignore: Array<string>): boolean {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const keysA = Object.keys(a);
|
||||
const keysB = Object.keys(b);
|
||||
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < keysA.length; i++) {
|
||||
const key = keysA[i];
|
||||
if (a[key] !== b[key] && (ignore == null || ignore.indexOf(key) === -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/lib/shallowEqual.js
|
75
509bba0_unpacked/discord_common/js/utils/ColorFunctions.js
Executable file
75
509bba0_unpacked/discord_common/js/utils/ColorFunctions.js
Executable file
|
@ -0,0 +1,75 @@
|
|||
/* eslint-disable */
|
||||
|
||||
function percentToFraction(amount) {
|
||||
if (typeof amount === 'string' && amount.indexOf('%') !== -1) {
|
||||
amount = parseInt(amount, 10) / 100;
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
const sbcRip = d => {
|
||||
const l = d.length;
|
||||
const RGB = new Object();
|
||||
const i = parseInt;
|
||||
|
||||
if (l > 9) {
|
||||
d = d.split(',');
|
||||
if (d.length < 3 || d.length > 4) return null; //ErrorCheck
|
||||
RGB[0] = i(d[0].slice(4)), RGB[1] = i(d[1]), RGB[2] = i(d[2]), RGB[3] = d[3] ? parseFloat(d[3]) : -1;
|
||||
}
|
||||
else {
|
||||
if (l == 8 || l == 6 || l < 4) return null; //ErrorCheck
|
||||
if (l < 6) d = '#' + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (l > 4 ? d[4] + '' + d[4] : ''); //3 digit
|
||||
d = i(d.slice(1), 16), RGB[0] = d >> 16 & 255, RGB[1] = d >> 8 & 255, RGB[2] = d & 255, RGB[3] = l == 9 || l == 5 ? r(((d >> 24 & 255) / 255) * 10000) / 10000 : -1;
|
||||
}
|
||||
return RGB;
|
||||
};
|
||||
|
||||
function lightness(p, from, to) {
|
||||
if (
|
||||
typeof(p) != 'number' ||
|
||||
p < -1 ||
|
||||
p > 1 ||
|
||||
typeof(from) != 'string' ||
|
||||
(from[0] != 'r' && from[0] != '#') ||
|
||||
(typeof(to) != 'string' &&
|
||||
typeof(to) != 'undefined')
|
||||
) {
|
||||
return null; //ErrorCheck
|
||||
}
|
||||
|
||||
let i = parseInt;
|
||||
let r = Math.round;
|
||||
let hh = from.length > 9;
|
||||
let h = typeof(to) == 'string' ? to.length > 9 ? true : to == 'c' ? !hh : false : hh;
|
||||
let b = p < 0;
|
||||
p = b ? p * -1 : p;
|
||||
to = to && to != 'c' ? to : b ? '#000000' : '#FFFFFF';
|
||||
|
||||
let f = sbcRip(from);
|
||||
let t = sbcRip(to);
|
||||
|
||||
if (!f || !t) {
|
||||
return null; //ErrorCheck
|
||||
}
|
||||
|
||||
if (h) {
|
||||
return 'rgb(' + r((t[0] - f[0]) * p + f[0]) + ',' + r((t[1] - f[1]) * p + f[1]) + ',' + r((t[2] - f[2]) * p + f[2]) + (f[3] < 0 && t[3] < 0 ? ')' : ',' + (f[3] > -1 && t[3] > -1 ? r(((t[3] - f[3]) * p + f[3]) * 10000) / 10000 : t[3] < 0 ? f[3] : t[3]) + ')');
|
||||
}
|
||||
return '#' + (0x100000000 + (f[3] > -1 && t[3] > -1 ? r(((t[3] - f[3]) * p + f[3]) * 255) : t[3] > -1 ? r(t[3] * 255) : f[3] > -1 ? r(f[3] * 255) : 255) * 0x1000000 + r((t[0] - f[0]) * p + f[0]) * 0x10000 + r((t[1] - f[1]) * p + f[1]) * 0x100 + r((t[2] - f[2]) * p + f[2])).toString(16).slice(f[3] > -1 || t[3] > -1 ? 1 : 3);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
darken: function(color, amount) {
|
||||
return lightness(-(percentToFraction(amount)), color);
|
||||
},
|
||||
lighten: function(color, amount) {
|
||||
return lightness(percentToFraction(amount), color);
|
||||
},
|
||||
lightness
|
||||
};
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/utils/ColorFunctions.js
|
90
509bba0_unpacked/discord_common/js/utils/ColorUtils.js
Executable file
90
509bba0_unpacked/discord_common/js/utils/ColorUtils.js
Executable file
|
@ -0,0 +1,90 @@
|
|||
/* @flow */
|
||||
|
||||
const HEX_REGEX = /^#?([a-f,A-F,0-9]{1,2})([a-f,A-F,0-9]{1,2})([a-f,A-F,0-9]{1,2})$/;
|
||||
|
||||
function pad2(s: string): string {
|
||||
return s.length == 1 ? `0${s}` : s;
|
||||
}
|
||||
|
||||
export function hex2int(hex: string): ?number {
|
||||
if (!hex) return;
|
||||
|
||||
// #FFF style
|
||||
if (hex.length === 4) {
|
||||
hex = `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`;
|
||||
}
|
||||
|
||||
return parseInt(hex.slice(1), 16);
|
||||
}
|
||||
|
||||
export function int2hex(colorInt: number): string {
|
||||
const r = (colorInt >> 16) & 0xff;
|
||||
const g = (colorInt >> 8) & 0xff;
|
||||
const b = colorInt & 0xff;
|
||||
return `#${pad2(r.toString(16))}${pad2(g.toString(16))}${pad2(b.toString(16))}`;
|
||||
}
|
||||
|
||||
export function hex2rgb(hex: string, alpha?: number=1): ?string {
|
||||
let match = hex.match(HEX_REGEX);
|
||||
if (match) {
|
||||
match = match.slice(1);
|
||||
|
||||
if (match.length !== 3) {
|
||||
return null;
|
||||
}
|
||||
const rgb = match.map(value => {
|
||||
if (value.length === 1) {
|
||||
value += value;
|
||||
}
|
||||
return parseInt(value, 16);
|
||||
});
|
||||
|
||||
return `rgba(${rgb.join(', ')}, ${alpha})`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function rgb2hex(rgb: string): ?string {
|
||||
const match = rgb.match(/\d{1,3}/g);
|
||||
if (match && match.length >= 3) {
|
||||
const [r, g, b, a] = match.slice(1);
|
||||
|
||||
if (a == null || a == '0') {
|
||||
return 'transparent';
|
||||
}
|
||||
return `#${pad2(r.toString(16))}${pad2(g.toString(16))}${pad2(b.toString(16))}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function int2rgba(colorInt: number, alpha: ?number): string {
|
||||
if (alpha == null) {
|
||||
alpha = ((colorInt >> 24) & 0xff) / 255;
|
||||
}
|
||||
|
||||
const r = (colorInt >> 16) & 0xff;
|
||||
const g = (colorInt >> 8) & 0xff;
|
||||
const b = colorInt & 0xff;
|
||||
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
|
||||
export function getDarkness(color: number) {
|
||||
const r = color >> 16 & 0xFF;
|
||||
const g = color >> 8 & 0xFF;
|
||||
const b = color & 0xFF;
|
||||
return 1 - (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||
}
|
||||
|
||||
export function isValidHex(hex: string): boolean {
|
||||
if (hex.length !== 4 && hex.length != 7 || hex[0] != '#') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hex.match(HEX_REGEX) != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WEBPACK FOOTER //
|
||||
// ./discord_common/js/utils/ColorUtils.js
|
Loading…
Add table
Add a link
Reference in a new issue