import React from 'react'; import { MonacoEditor } from './Monaco'; import { DefaultSettings, EditingModes, HtmlElementId, SaveSettingsInterface, } from './AppendEditor'; import { CloseIcon, RefreshIcon } from './Icons'; import { ChevronToggleButton, UndoButton } from './Buttons'; const customStylesID = 'customStyles'; const editingModeID = 'editingMode'; const fontEditID = 'fontEdit'; const fontSizeID = 'fontSize'; const fontViewID = 'fontView'; const monacoEditorLanguageID = 'monacoEditorLanguage'; const resetAllSettingsID = 'resetAllSettings'; const saveAsDefaultID = 'saveAsDefault'; interface SettingsProps { defaultSettings: DefaultSettings; customStyles: string; editingMode?: string; fontEdit: string; fontSize: string; fontView: string; monacoEditorLanguage: string; cancelText: string; confirmText: string; debugMode: boolean; keyMap: Map; onCancel: () => void; onConfirm: (object: SaveSettingsInterface) => void; title: string; helpLink: string; } interface SettingsState { customStyles: string; editingMode: string; fontEdit: string; fontSize: string; fontView: string; monacoEditorLanguage: string; saveAsDefault: boolean; showCustomStyles: boolean; [x: string]: string | boolean; } const startRegExp = new RegExp(/```css\n/gm); const cssRegExp = new RegExp(/```css/gm); const endRegExp = new RegExp(/\n```/gm); const codeRegExp = new RegExp(/```/gm); export default class Settings extends React.Component< SettingsProps, SettingsState > { constructor(props: SettingsProps) { super(props); let monacoEditorLanguage = 'markdown'; if (this.props.monacoEditorLanguage) { monacoEditorLanguage = this.props.monacoEditorLanguage; } let editingMode = 'usePlainText'; if (this.props.editingMode) { editingMode = this.props.editingMode; } this.state = { customStyles: this.props.customStyles, editingMode, fontEdit: this.props.fontEdit, fontSize: this.props.fontSize, fontView: this.props.fontView, monacoEditorLanguage, saveAsDefault: false, showCustomStyles: false, // false by default for a mobile-first experience }; } handleInputChange = (event: React.ChangeEvent) => { const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; this.setState({ [name]: value, }); if (this.props.debugMode) { console.log( 'Settings event name: ' + event.target.name + ' Value: ' + event.target.value ); } }; handleSelectChange = (event: React.ChangeEvent) => { const target = event.target; const value = target.value; const name = target.name; this.setState( { [name]: value, }, () => { if (this.props.debugMode) { console.log( 'Saved select. Name: ' + event.target.name + ' Value: ' + event.target.value ); } } ); }; toggleShowCustomStyles = () => { this.setState({ showCustomStyles: !this.state.showCustomStyles, }); }; cleanCustomStyles = (text: string) => { if (text) { return text .replace(startRegExp, '') .replace(cssRegExp, '') .replace(endRegExp, '') .replace(codeRegExp, ''); } else { return text; } }; saveText = (text: string) => { this.setState({ customStyles: text, }); }; handleSubmit = () => { if (this.props.debugMode) { let fontEditMessage = ''; let fontViewMessage = ''; if (this.state.fontEdit === '' || this.state.fontEdit === undefined) { fontEditMessage = 'Default'; } else if (this.state.fontEdit) { fontEditMessage = this.state.fontEdit; } if (this.state.fontView === '' || this.state.fontView === undefined) { fontViewMessage = 'Default'; } else if (this.state.fontView) { fontViewMessage = this.state.fontView; } console.log( 'Settings.tsx handleSubmit() triggered: ' + '\n - Settings editingMode: ' + this.state.editingMode + '\n - Settings fontEdit: ' + this.state.fontEdit + '\n - Settings fontView: ' + this.state.fontView + '\n - Your chosen font for Edit/Append is: ' + fontEditMessage + '\n - Your chosen font for View/Print is: ' + fontViewMessage + '\n' ); } this.setState( { // clean the custom styles prior to saving them customStyles: this.cleanCustomStyles(this.state.customStyles), }, () => { if (this.props.debugMode) { console.log('Your custom styles: ' + this.state.customStyles); } const { customStyles, editingMode, fontEdit, fontSize, fontView, monacoEditorLanguage, saveAsDefault, } = this.state; this.props.onConfirm({ customStyles, editingMode, fontEdit, fontSize, fontView, monacoEditorLanguage, saveAsDefault, }); } ); }; loadDefaultSettings = () => { const defaultSettings = this.props.defaultSettings; this.setState( { ...defaultSettings, }, () => { this.refreshCustomStyles(); } ); }; refreshCustomStyles = () => { this.setState( { showCustomStyles: !this.state.showCustomStyles, }, () => { this.setState({ showCustomStyles: !this.state.showCustomStyles, }); } ); }; clearCustomStyles = () => { this.setState( { customStyles: '', }, () => { this.refreshCustomStyles(); if (this.props.debugMode) { console.log('customStyles reset: ' + this.state.customStyles); } } ); const customStyles = document.getElementById( customStylesID ) as HTMLTextAreaElement; if (customStyles) { customStyles.value = ''; customStyles.focus(); } }; clearFontEdit = () => { this.setState({ fontEdit: '', }); const fontEdit = document.getElementById(fontEditID) as HTMLTextAreaElement; if (fontEdit) { fontEdit.value = ''; fontEdit.focus(); } }; clearFontSize = () => { this.setState({ fontSize: '', }); const fontSize = document.getElementById(fontSizeID) as HTMLSelectElement; if (fontSize) { fontSize.value = ''; fontSize.focus(); } }; clearFontView = () => { this.setState({ fontView: '', }); const fontView = document.getElementById(fontViewID) as HTMLTextAreaElement; if (fontView) { fontView.value = ''; fontView.focus(); } }; clearEditingMode = () => { this.setState({ editingMode: EditingModes.usePlainText, }); }; clearMonacoEditorLanguage = () => { this.setState({ monacoEditorLanguage: 'markdown', }); const monacoEditorLanguage = document.getElementById( monacoEditorLanguageID ) as HTMLSelectElement; if (monacoEditorLanguage) { monacoEditorLanguage.value = 'markdown'; monacoEditorLanguage.focus(); } }; clearSaveAsDefault = () => { this.setState({ saveAsDefault: false, }); const saveAsDefault = document.getElementById( saveAsDefaultID ) as HTMLInputElement; saveAsDefault.checked = false; saveAsDefault.focus(); }; clearAllSettings = () => { // We clear from bottom settings to top settings so the focus afterwards is on top this.clearSaveAsDefault(); this.clearCustomStyles(); this.clearFontView(); this.clearFontEdit(); this.clearFontSize(); this.clearMonacoEditorLanguage(); this.clearEditingMode(); const resetAllSettings = document.getElementById(resetAllSettingsID); if (resetAllSettings) { resetAllSettings.focus(); } }; onKeyDown = (e: React.KeyboardEvent) => { this.props.keyMap.set(e.key, true); //console.log("Keys pressed: " + e.key + "KeyMap for key: " + keyMap.get(e.key)) + "KeyMap for Shift: " + keyMap.get('Shift'); // Save settings if Control and 's' are pressed if (this.props.keyMap.get('Control') && this.props.keyMap.get('s')) { e.preventDefault(); this.handleSubmit(); } // Save settings if Control and Enter are pressed else if ( this.props.keyMap.get('Control') && this.props.keyMap.get('Enter') ) { e.preventDefault(); this.handleSubmit(); } }; onKeyUp = (e: React.KeyboardEvent) => { this.props.keyMap.set(e.key, false); }; onBlur = (e: React.FocusEvent) => { this.props.keyMap.clear(); }; componentWillUnmount = () => { this.props.keyMap.clear(); }; render() { //

const { title, onCancel, confirmText, cancelText, helpLink } = this.props; return (

{title}

Need help? Check out the{' '} documentation . To clear all settings, click undo: 

To load your personal default settings, click: 

Editing Mode:

{this.state.editingMode === EditingModes.useMonacoEditor && (
)}
{this.state.editingMode !== EditingModes.useMonacoEditor && (
)} {this.state.editingMode !== EditingModes.useDynamicEditor && (
)}
{this.state.showCustomStyles && ( )}
{this.state.showCustomStyles && (
)}
); } }