312 lines
9.7 KiB
JavaScript
Executable file
312 lines
9.7 KiB
JavaScript
Executable file
import React from 'react';
|
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
|
import Flux from '../../lib/flux';
|
|
import classNames from 'classnames';
|
|
import i18n from '../../i18n';
|
|
import NativeUtils from '../../utils/NativeUtils';
|
|
import ConfirmModal from '../ConfirmModal';
|
|
import {SUPPORTS_COPY} from '../../utils/ClipboardUtils';
|
|
import {FormSection, FormTitle, FormText, FormTitleTags, FormItem} from '../../uikit/form';
|
|
import Card from '../../uikit/Card';
|
|
import RadioGroup from '../../uikit/RadioGroup';
|
|
import SwitchItem from '../../uikit/SwitchItem';
|
|
import Slider from '../../uikit/Slider';
|
|
import Flex from '../../uikit/Flex';
|
|
import MessageUtils from '../../utils/MessageUtils';
|
|
import {modKey} from '../../lib/Keybinds';
|
|
import MessageGroup from '../MessageGroup';
|
|
import MessageRecord from '../../records/MessageRecord';
|
|
import UserSettingsActionCreators from '../../actions/UserSettingsActionCreators';
|
|
import {fontScaleTo, zoomTo} from '../../actions/AccessibilityActionCreators';
|
|
import ModalActionCreators from '../../actions/ModalActionCreators';
|
|
import UserSettingsStore from '../../stores/UserSettingsStore';
|
|
import AccessibilityStore from '../../stores/AccessibilityStore';
|
|
import {ThemeTypes, MARKETING_URLS, MessageStates, Accessibility, NativeFeatures} from '../../Constants';
|
|
import '../../styles/user_settings_appearance.styl';
|
|
|
|
const UserSettingsAppearance = React.createClass({
|
|
mixins: [Flux.StoreListenerMixin(AccessibilityStore, UserSettingsStore), PureRenderMixin],
|
|
|
|
getInitialState() {
|
|
return {
|
|
hardwareAccelerationEnabled: NativeUtils.getEnableHardwareAcceleration(),
|
|
};
|
|
},
|
|
|
|
getStateFromStores() {
|
|
const theme = UserSettingsStore.theme;
|
|
const previewMessage = theme === ThemeTypes.DARK
|
|
? i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_2_DARK
|
|
: i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_2_LIGHT;
|
|
|
|
return {
|
|
theme,
|
|
previewMessage,
|
|
messageDisplayCompact: UserSettingsStore.messageDisplayCompact,
|
|
developerMode: UserSettingsStore.developerMode,
|
|
fontScale: AccessibilityStore.fontScale,
|
|
zoom: AccessibilityStore.zoom,
|
|
};
|
|
},
|
|
|
|
componentWillMount() {
|
|
this.channel = {
|
|
isPrivate: () => false,
|
|
id: '1337',
|
|
};
|
|
|
|
let id = 0;
|
|
this.messages = [
|
|
MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_1),
|
|
state: MessageStates.SENT,
|
|
id: id++,
|
|
}),
|
|
MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, this.state.previewMessage),
|
|
state: MessageStates.SENT,
|
|
id: id++,
|
|
}),
|
|
MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_3),
|
|
state: MessageStates.SENT,
|
|
id: id++,
|
|
}),
|
|
MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_4),
|
|
state: MessageStates.SENT,
|
|
id: id++,
|
|
}),
|
|
MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, i18n.Messages.USER_SETTINGS_APPEARANCE_PREVIEW_MESSAGE_5),
|
|
state: MessageStates.SENT,
|
|
id,
|
|
}),
|
|
];
|
|
},
|
|
|
|
componentWillUnmount() {
|
|
this.channel = null;
|
|
this.messages = null;
|
|
},
|
|
|
|
componentWillUpdate(nextProps, nextState) {
|
|
// Update the preview message when theme changes
|
|
if (this.state.theme !== nextState.theme) {
|
|
this.messages[1] = MessageRecord.create({
|
|
...MessageUtils.createMessage(this.channel.id, nextState.previewMessage),
|
|
state: 'SENT',
|
|
});
|
|
}
|
|
},
|
|
|
|
renderZoomSlider() {
|
|
if (!NativeUtils.embedded) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<FormItem title={i18n.Messages.ACCESSIBILITY_ZOOM_LEVEL_LABEL} className="margin-top-20">
|
|
<Slider
|
|
className="margin-top-20 margin-bottom-4"
|
|
defaultValue={this.state.zoom}
|
|
markers={Accessibility.ZOOM_SCALES}
|
|
stickToMarkers
|
|
onValueChange={this.handleZoomChange}
|
|
onValueRender={this.handleSliderRender}
|
|
/>
|
|
<FormText type={FormText.Types.DESCRIPTION}>
|
|
{i18n.Messages.USER_SETTINGS_APPEARANCE_ZOOM_TIP.format({modKey})}
|
|
</FormText>
|
|
</FormItem>
|
|
);
|
|
},
|
|
|
|
renderFontScaleSlider() {
|
|
return (
|
|
<FormItem title={i18n.Messages.ACCESSIBILITY_FONT_SCALING_LABEL} className="margin-top-40">
|
|
<Flex align={Flex.Align.CENTER}>
|
|
<Flex.Child className="font-scale-sample-small">Aa</Flex.Child>
|
|
<Flex.Child>
|
|
<Slider
|
|
className="margin-top-4"
|
|
defaultValue={this.state.fontScale}
|
|
markers={Accessibility.FONT_SCALES}
|
|
stickToMarkers
|
|
equidistant
|
|
onValueChange={this.handleFontScaleChange}
|
|
onValueRender={this.handleSliderRender}
|
|
onMarkerRender={this.handleRenderFontScale}
|
|
/>
|
|
</Flex.Child>
|
|
<Flex.Child className="font-scale-sample-large">Aa</Flex.Child>
|
|
</Flex>
|
|
</FormItem>
|
|
);
|
|
},
|
|
|
|
renderPreview() {
|
|
const {messageDisplayCompact} = this.state;
|
|
|
|
return (
|
|
<Card className="preview" outline>
|
|
<div className={classNames('preview-inner', {'preview-compact': messageDisplayCompact})}>
|
|
{this.messages.map(message =>
|
|
<MessageGroup
|
|
key={message.id}
|
|
channel={this.channel}
|
|
messages={[message]}
|
|
enableInteraction={false}
|
|
compact={messageDisplayCompact}
|
|
/>
|
|
)}
|
|
</div>
|
|
</Card>
|
|
);
|
|
},
|
|
|
|
renderThemePicker() {
|
|
return (
|
|
<FormItem title={i18n.Messages.THEME} className="margin-top-40">
|
|
<RadioGroup
|
|
options={[
|
|
{
|
|
name: i18n.Messages.THEME_LIGHT,
|
|
value: ThemeTypes.LIGHT,
|
|
},
|
|
{
|
|
name: i18n.Messages.THEME_DARK,
|
|
value: ThemeTypes.DARK,
|
|
},
|
|
]}
|
|
onChange={this.handleThemeChange}
|
|
value={this.state.theme}
|
|
/>
|
|
</FormItem>
|
|
);
|
|
},
|
|
|
|
renderDisplayMode() {
|
|
return (
|
|
<FormItem title={i18n.Messages.MESSAGE_DISPLAY_MODE_LABEL} className="margin-top-40">
|
|
<RadioGroup
|
|
options={[
|
|
{
|
|
name: i18n.Messages.COZY_MODE,
|
|
value: false,
|
|
},
|
|
{
|
|
name: i18n.Messages.COMPACT_MODE,
|
|
value: true,
|
|
},
|
|
]}
|
|
onChange={this.handleMessageDisplayModeChange}
|
|
value={this.state.messageDisplayCompact}
|
|
/>
|
|
</FormItem>
|
|
);
|
|
},
|
|
|
|
renderDeveloperMode() {
|
|
if (SUPPORTS_COPY) {
|
|
return (
|
|
<SwitchItem
|
|
value={this.state.developerMode}
|
|
onChange={this.handleDeveloperModeChecked}
|
|
note={i18n.Messages.DEVELOPER_MODE_HELP_TEXT.format({apiDocsUrl: MARKETING_URLS.API_DOCS})}>
|
|
{i18n.Messages.DEVELOPER_MODE}
|
|
</SwitchItem>
|
|
);
|
|
}
|
|
},
|
|
|
|
renderHardwareAcceleration() {
|
|
if (NativeUtils.supportsFeature(NativeFeatures.ELECTRON_CONFIGURE_HARDWARE_ACCELERATION)) {
|
|
return (
|
|
<SwitchItem
|
|
className="margin-top-4"
|
|
value={this.state.hardwareAccelerationEnabled}
|
|
onChange={this.handleHardwareAccelerationChecked}
|
|
note={i18n.Messages.HARDWARE_ACCELERATION_HELP_TEXT}>
|
|
{i18n.Messages.HARDWARE_ACCELERATION}
|
|
</SwitchItem>
|
|
);
|
|
}
|
|
},
|
|
|
|
render() {
|
|
return (
|
|
<FormSection className="user-settings-appearance" tag={FormTitleTags.H2} title={i18n.Messages.APPEARANCE}>
|
|
{this.renderPreview(this.state.theme, this.state.messageDisplayCompact)}
|
|
{this.renderThemePicker()}
|
|
{this.renderDisplayMode()}
|
|
{this.renderFontScaleSlider()}
|
|
{this.renderZoomSlider()}
|
|
<FormTitle tag={FormTitleTags.H2} className="margin-top-60 margin-bottom-20">
|
|
{i18n.Messages.SETTINGS_ADVANCED}
|
|
</FormTitle>
|
|
{this.renderDeveloperMode()}
|
|
{this.renderHardwareAcceleration()}
|
|
</FormSection>
|
|
);
|
|
},
|
|
|
|
handleThemeChange(option) {
|
|
UserSettingsActionCreators.updateRemoteSettings({theme: option.value});
|
|
},
|
|
|
|
handleMessageDisplayModeChange(option) {
|
|
UserSettingsActionCreators.updateRemoteSettings({messageDisplayCompact: option.value});
|
|
},
|
|
|
|
handleDeveloperModeChecked(e) {
|
|
UserSettingsActionCreators.updateRemoteSettings({developerMode: e.currentTarget.checked});
|
|
},
|
|
|
|
handleHardwareAccelerationChecked(e) {
|
|
const shouldEnable = e.currentTarget.checked;
|
|
ModalActionCreators.push(props => {
|
|
return (
|
|
<ConfirmModal
|
|
header={i18n.Messages.SWITCH_HARDWARE_ACCELERATION}
|
|
confirmText={i18n.Messages.OKAY}
|
|
cancelText={i18n.Messages.CANCEL}
|
|
onConfirm={() => NativeUtils.setEnableHardwareAcceleration(shouldEnable)}
|
|
red={true}
|
|
{...props}>
|
|
<p>{i18n.Messages.SWITCH_HARDWARE_ACCELERATION_BODY}</p>
|
|
</ConfirmModal>
|
|
);
|
|
});
|
|
},
|
|
|
|
handleRenderFontScale(value) {
|
|
// 82 and 92 render better for our font, however 80 and 90 are nice round numbers.
|
|
// So we use 82/92 to render, but display 80/90 for information to the users
|
|
if (value === 82) {
|
|
value = 80;
|
|
} else if (value === 92) {
|
|
value = 90;
|
|
}
|
|
return `${value.toFixed(0)}`;
|
|
},
|
|
|
|
handleSliderRender(value) {
|
|
return `${value.toFixed(0)}%`;
|
|
},
|
|
|
|
handleFontScaleChange(fontScale) {
|
|
fontScaleTo(Math.round(fontScale));
|
|
},
|
|
|
|
handleZoomChange(zoom) {
|
|
zoomTo(zoom);
|
|
},
|
|
});
|
|
|
|
export default UserSettingsAppearance;
|
|
|
|
|
|
|
|
// WEBPACK FOOTER //
|
|
// ./discord_app/components/user_settings/UserSettingsAppearance.js
|