// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import 'bootstrap-colorpicker'; import $ from 'jquery'; import PropTypes from 'prop-types'; import React from 'react'; import {Popover, OverlayTrigger} from 'react-bootstrap'; import {defineMessages, FormattedMessage, intlShape, injectIntl} from 'react-intl'; import Constants from 'utils/constants.jsx'; import * as UserAgent from 'utils/user_agent.jsx'; import * as Utils from 'utils/utils.jsx'; const messages = defineMessages({ sidebarBg: { id: 'user.settings.custom_theme.sidebarBg', defaultMessage: 'Sidebar BG' }, sidebarText: { id: 'user.settings.custom_theme.sidebarText', defaultMessage: 'Sidebar Text' }, sidebarHeaderBg: { id: 'user.settings.custom_theme.sidebarHeaderBg', defaultMessage: 'Sidebar Header BG' }, sidebarHeaderTextColor: { id: 'user.settings.custom_theme.sidebarHeaderTextColor', defaultMessage: 'Sidebar Header Text' }, sidebarUnreadText: { id: 'user.settings.custom_theme.sidebarUnreadText', defaultMessage: 'Sidebar Unread Text' }, sidebarTextHoverBg: { id: 'user.settings.custom_theme.sidebarTextHoverBg', defaultMessage: 'Sidebar Text Hover BG' }, sidebarTextActiveBorder: { id: 'user.settings.custom_theme.sidebarTextActiveBorder', defaultMessage: 'Sidebar Text Active Border' }, sidebarTextActiveColor: { id: 'user.settings.custom_theme.sidebarTextActiveColor', defaultMessage: 'Sidebar Text Active Color' }, onlineIndicator: { id: 'user.settings.custom_theme.onlineIndicator', defaultMessage: 'Online Indicator' }, awayIndicator: { id: 'user.settings.custom_theme.awayIndicator', defaultMessage: 'Away Indicator' }, mentionBj: { id: 'user.settings.custom_theme.mentionBj', defaultMessage: 'Mention Jewel BG' }, mentionColor: { id: 'user.settings.custom_theme.mentionColor', defaultMessage: 'Mention Jewel Text' }, centerChannelBg: { id: 'user.settings.custom_theme.centerChannelBg', defaultMessage: 'Center Channel BG' }, centerChannelColor: { id: 'user.settings.custom_theme.centerChannelColor', defaultMessage: 'Center Channel Text' }, newMessageSeparator: { id: 'user.settings.custom_theme.newMessageSeparator', defaultMessage: 'New Message Separator' }, linkColor: { id: 'user.settings.custom_theme.linkColor', defaultMessage: 'Link Color' }, buttonBg: { id: 'user.settings.custom_theme.buttonBg', defaultMessage: 'Button BG' }, buttonColor: { id: 'user.settings.custom_theme.buttonColor', defaultMessage: 'Button Text' }, errorTextColor: { id: 'user.settings.custom_theme.errorTextColor', defaultMessage: 'Error Text Color' }, mentionHighlightBg: { id: 'user.settings.custom_theme.mentionHighlightBg', defaultMessage: 'Mention Highlight BG' }, mentionHighlightLink: { id: 'user.settings.custom_theme.mentionHighlightLink', defaultMessage: 'Mention Highlight Link' }, codeTheme: { id: 'user.settings.custom_theme.codeTheme', defaultMessage: 'Code Theme' } }); const HEX_CODE_LENGTH = 7; class CustomThemeChooser extends React.Component { constructor(props) { super(props); this.selectTheme = this.selectTheme.bind(this); const copyTheme = Object.assign({}, this.props.theme); delete copyTheme.type; delete copyTheme.image; this.state = { copyTheme: JSON.stringify(copyTheme) }; } componentDidMount() { $('.color-picker').colorpicker({ format: 'hex' }); $('.color-picker').on('changeColor', this.onPickerChange); $('.group--code').on('change', this.onCodeThemeChange); document.addEventListener('click', this.closeColorpicker); } componentWillUnmount() { $('.color-picker').off('changeColor', this.onPickerChange); $('.group--code').off('change', this.onCodeThemeChange); document.removeEventListener('click', this.closeColorpicker); } componentDidUpdate() { const theme = this.props.theme; Constants.THEME_ELEMENTS.forEach((element) => { if (theme.hasOwnProperty(element.id) && element.id !== 'codeTheme') { $('#' + element.id).data('colorpicker').color.setColor(theme[element.id]); $('#' + element.id).colorpicker('update'); } }); } closeColorpicker(e) { if (!$(e.target).closest('.color-picker').length && Utils.isMobile()) { $('.color-picker').colorpicker('hide'); } } onPickerChange = (e) => { const inputBox = e.target.childNodes[0]; if (document.activeElement === inputBox && inputBox.value.length !== HEX_CODE_LENGTH) { return; } const theme = this.props.theme; if (theme[e.target.id] !== e.color.toHex()) { theme[e.target.id] = e.color.toHex(); theme.type = 'custom'; this.props.updateTheme(theme); } } pasteBoxChange = (e) => { let text = ''; if (window.clipboardData && window.clipboardData.getData) { // IE text = window.clipboardData.getData('Text'); } else { text = e.clipboardData.getData('Text');//e.clipboardData.getData('text/plain'); } if (text.length === 0) { return; } let theme; try { theme = JSON.parse(text); } catch (err) { return; } this.setState({ copyTheme: JSON.stringify(theme) }); theme.type = 'custom'; this.props.updateTheme(theme); } onChangeHandle = (e) => { e.stopPropagation(); } selectTheme() { const textarea = this.refs.textarea; textarea.focus(); textarea.setSelectionRange(0, this.state.copyTheme.length); } toggleSidebarStyles = (e) => { e.preventDefault(); $(this.refs.sidebarStylesHeader).toggleClass('open'); this.toggleSection(this.refs.sidebarStyles); } toggleCenterChannelStyles = (e) => { e.preventDefault(); $(this.refs.centerChannelStylesHeader).toggleClass('open'); this.toggleSection(this.refs.centerChannelStyles); } toggleLinkAndButtonStyles = (e) => { e.preventDefault(); $(this.refs.linkAndButtonStylesHeader).toggleClass('open'); this.toggleSection(this.refs.linkAndButtonStyles); } toggleSection(node) { if (UserAgent.isIos()) { // iOS doesn't support jQuery animations $(node).toggleClass('open'); } else { $(node).slideToggle(); } } onCodeThemeChange = (e) => { const theme = this.props.theme; theme.codeTheme = e.target.value; this.props.updateTheme(theme); } render() { const {formatMessage} = this.props.intl; const theme = this.props.theme; const sidebarElements = []; const centerChannelElements = []; const linkAndButtonElements = []; Constants.THEME_ELEMENTS.forEach((element, index) => { if (element.id === 'codeTheme') { const codeThemeOptions = []; let codeThemeURL = ''; element.themes.forEach((codeTheme, codeThemeIndex) => { if (codeTheme.id === theme[element.id]) { codeThemeURL = codeTheme.iconURL; } codeThemeOptions.push( ); }); var popoverContent = ( ); centerChannelElements.push(
); } else if (element.group === 'centerChannelElements') { centerChannelElements.push(
); } else if (element.group === 'sidebarElements') { sidebarElements.push(
); } else { linkAndButtonElements.push(
); } }); const pasteBox = (