From ec42aedb73dd95c03109af542beb1abadecd9dbb Mon Sep 17 00:00:00 2001 From: gabek Date: Thu, 17 Nov 2022 18:32:58 +0000 Subject: [PATCH] Prettified Code! --- webroot/js/components/chat/chat-input.js | 684 +++++++++++------------ 1 file changed, 342 insertions(+), 342 deletions(-) diff --git a/webroot/js/components/chat/chat-input.js b/webroot/js/components/chat/chat-input.js index 264a1c807..dfccad32f 100644 --- a/webroot/js/components/chat/chat-input.js +++ b/webroot/js/components/chat/chat-input.js @@ -6,395 +6,395 @@ import { EmojiButton } from '/js/web_modules/@joeattardi/emoji-button.js'; import ContentEditable, { replaceCaret } from './content-editable.js'; import { - generatePlaceholderText, - getCaretPosition, - convertToText, - convertOnPaste, - createEmojiMarkup, - trimNbsp, - emojify, + generatePlaceholderText, + getCaretPosition, + convertToText, + convertOnPaste, + createEmojiMarkup, + trimNbsp, + emojify, } from '../../utils/chat.js'; import { - getLocalStorage, - setLocalStorage, - classNames, + getLocalStorage, + setLocalStorage, + classNames, } from '../../utils/helpers.js'; import { - URL_CUSTOM_EMOJIS, - KEY_CHAT_FIRST_MESSAGE_SENT, - CHAT_CHAR_COUNT_BUFFER, - CHAT_OK_KEYCODES, - CHAT_KEY_MODIFIERS, + URL_CUSTOM_EMOJIS, + KEY_CHAT_FIRST_MESSAGE_SENT, + CHAT_CHAR_COUNT_BUFFER, + CHAT_OK_KEYCODES, + CHAT_KEY_MODIFIERS, } from '../../utils/constants.js'; export default class ChatInput extends Component { - constructor(props, context) { - super(props, context); - this.formMessageInput = createRef(); - this.emojiPickerButton = createRef(); + constructor(props, context) { + super(props, context); + this.formMessageInput = createRef(); + this.emojiPickerButton = createRef(); - this.messageCharCount = 0; + this.messageCharCount = 0; - this.prepNewLine = false; - this.modifierKeyPressed = false; // control/meta/shift/alt + this.prepNewLine = false; + this.modifierKeyPressed = false; // control/meta/shift/alt - this.state = { - inputHTML: '', - inputCharsLeft: props.inputMaxBytes, - hasSentFirstChatMessage: getLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT), - emojiPicker: null, - emojiList: null, - emojiNames: null, - }; + this.state = { + inputHTML: '', + inputCharsLeft: props.inputMaxBytes, + hasSentFirstChatMessage: getLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT), + emojiPicker: null, + emojiList: null, + emojiNames: null, + }; - this.handleEmojiButtonClick = this.handleEmojiButtonClick.bind(this); - this.handleEmojiSelected = this.handleEmojiSelected.bind(this); - this.getCustomEmojis = this.getCustomEmojis.bind(this); + this.handleEmojiButtonClick = this.handleEmojiButtonClick.bind(this); + this.handleEmojiSelected = this.handleEmojiSelected.bind(this); + this.getCustomEmojis = this.getCustomEmojis.bind(this); - this.handleMessageInputKeydown = this.handleMessageInputKeydown.bind(this); - this.handleMessageInputKeyup = this.handleMessageInputKeyup.bind(this); - this.handleMessageInputBlur = this.handleMessageInputBlur.bind(this); - this.handleSubmitChatButton = this.handleSubmitChatButton.bind(this); - this.handlePaste = this.handlePaste.bind(this); + this.handleMessageInputKeydown = this.handleMessageInputKeydown.bind(this); + this.handleMessageInputKeyup = this.handleMessageInputKeyup.bind(this); + this.handleMessageInputBlur = this.handleMessageInputBlur.bind(this); + this.handleSubmitChatButton = this.handleSubmitChatButton.bind(this); + this.handlePaste = this.handlePaste.bind(this); - this.handleContentEditableChange = - this.handleContentEditableChange.bind(this); - } + this.handleContentEditableChange = + this.handleContentEditableChange.bind(this); + } - componentDidMount() { - this.getCustomEmojis(); - } + componentDidMount() { + this.getCustomEmojis(); + } - getCustomEmojis() { - fetch(URL_CUSTOM_EMOJIS) - .then((response) => { - if (!response.ok) { - throw new Error(`Network response was not ok ${response.ok}`); - } - return response.json(); - }) - .then((json) => { - const emojiList = json; - const emojiNames = emojiList.map((emoji) => emoji.name); - const emojiPicker = new EmojiButton({ - zIndex: 100, - theme: 'owncast', // see chat.css - custom: json, - initialCategory: 'custom', - showPreview: false, - autoHide: false, - autoFocusSearch: false, - showAnimation: false, - emojiSize: '24px', - position: 'right-start', - strategy: 'absolute', - }); - emojiPicker.on('emoji', (emoji) => { - this.handleEmojiSelected(emoji); - }); - emojiPicker.on('hidden', () => { - this.formMessageInput.current.focus(); - replaceCaret(this.formMessageInput.current); - }); - this.setState({ emojiNames, emojiList, emojiPicker }); - }) - .catch((error) => { - // this.handleNetworkingError(`Emoji Fetch: ${error}`); - }); - } + getCustomEmojis() { + fetch(URL_CUSTOM_EMOJIS) + .then((response) => { + if (!response.ok) { + throw new Error(`Network response was not ok ${response.ok}`); + } + return response.json(); + }) + .then((json) => { + const emojiList = json; + const emojiNames = emojiList.map((emoji) => emoji.name); + const emojiPicker = new EmojiButton({ + zIndex: 100, + theme: 'owncast', // see chat.css + custom: json, + initialCategory: 'custom', + showPreview: false, + autoHide: false, + autoFocusSearch: false, + showAnimation: false, + emojiSize: '24px', + position: 'right-start', + strategy: 'absolute', + }); + emojiPicker.on('emoji', (emoji) => { + this.handleEmojiSelected(emoji); + }); + emojiPicker.on('hidden', () => { + this.formMessageInput.current.focus(); + replaceCaret(this.formMessageInput.current); + }); + this.setState({ emojiNames, emojiList, emojiPicker }); + }) + .catch((error) => { + // this.handleNetworkingError(`Emoji Fetch: ${error}`); + }); + } - handleEmojiButtonClick() { - const { emojiPicker } = this.state; - if (emojiPicker) { - emojiPicker.togglePicker(this.emojiPickerButton.current); - } - } + handleEmojiButtonClick() { + const { emojiPicker } = this.state; + if (emojiPicker) { + emojiPicker.togglePicker(this.emojiPickerButton.current); + } + } - handleEmojiSelected(emoji) { - const { inputHTML, inputCharsLeft } = this.state; - // if we're already at char limit, don't do anything - if (inputCharsLeft < 0) { - return; - } - let content = ''; - if (emoji.url) { - content = createEmojiMarkup(emoji, false); - } else { - content = emoji.emoji; - } + handleEmojiSelected(emoji) { + const { inputHTML, inputCharsLeft } = this.state; + // if we're already at char limit, don't do anything + if (inputCharsLeft < 0) { + return; + } + let content = ''; + if (emoji.url) { + content = createEmojiMarkup(emoji, false); + } else { + content = emoji.emoji; + } - const position = getCaretPosition(this.formMessageInput.current); - const newHTML = - inputHTML.substring(0, position) + - content + - inputHTML.substring(position); + const position = getCaretPosition(this.formMessageInput.current); + const newHTML = + inputHTML.substring(0, position) + + content + + inputHTML.substring(position); - const charsLeft = this.calculateCurrentBytesLeft(newHTML); - this.setState({ - inputHTML: newHTML, - inputCharsLeft: charsLeft, - }); - // a hacky way add focus back into input field - setTimeout(() => { - const input = this.formMessageInput.current; - input.focus(); - replaceCaret(input); - }, 100); - } + const charsLeft = this.calculateCurrentBytesLeft(newHTML); + this.setState({ + inputHTML: newHTML, + inputCharsLeft: charsLeft, + }); + // a hacky way add focus back into input field + setTimeout(() => { + const input = this.formMessageInput.current; + input.focus(); + replaceCaret(input); + }, 100); + } - // autocomplete text from the given "list". "token" marks the start of word lookup. - autoComplete(token, list) { - const { inputHTML } = this.state; - const position = getCaretPosition(this.formMessageInput.current); - const at = inputHTML.lastIndexOf(token, position - 1); - if (at === -1) { - return false; - } + // autocomplete text from the given "list". "token" marks the start of word lookup. + autoComplete(token, list) { + const { inputHTML } = this.state; + const position = getCaretPosition(this.formMessageInput.current); + const at = inputHTML.lastIndexOf(token, position - 1); + if (at === -1) { + return false; + } - let partial = inputHTML.substring(at + 1, position).trim(); + let partial = inputHTML.substring(at + 1, position).trim(); - if (this.partial === undefined) { - this.partial = []; - } + if (this.partial === undefined) { + this.partial = []; + } - if (partial === this.suggestion) { - partial = this.partial[token]; - } else { - this.partial[token] = partial; - } + if (partial === this.suggestion) { + partial = this.partial[token]; + } else { + this.partial[token] = partial; + } - const possibilities = list.filter(function (item) { - return item.toLowerCase().startsWith(partial.toLowerCase()); - }); + const possibilities = list.filter(function (item) { + return item.toLowerCase().startsWith(partial.toLowerCase()); + }); - if (this.completionIndex === undefined) { - this.completionIndex = []; - } + if (this.completionIndex === undefined) { + this.completionIndex = []; + } - if ( - this.completionIndex[token] === undefined || - ++this.completionIndex[token] >= possibilities.length - ) { - this.completionIndex[token] = 0; - } + if ( + this.completionIndex[token] === undefined || + ++this.completionIndex[token] >= possibilities.length + ) { + this.completionIndex[token] = 0; + } - if (possibilities.length > 0) { - this.suggestion = possibilities[this.completionIndex[token]]; + if (possibilities.length > 0) { + this.suggestion = possibilities[this.completionIndex[token]]; - const newHTML = - inputHTML.substring(0, at + 1) + - this.suggestion + - ' ' + - inputHTML.substring(position); + const newHTML = + inputHTML.substring(0, at + 1) + + this.suggestion + + ' ' + + inputHTML.substring(position); - this.setState({ - inputHTML: newHTML, - inputCharsLeft: this.calculateCurrentBytesLeft(newHTML), - }); - } + this.setState({ + inputHTML: newHTML, + inputCharsLeft: this.calculateCurrentBytesLeft(newHTML), + }); + } - return true; - } + return true; + } - // replace :emoji: with the emoji - injectEmoji() { - const { inputHTML, emojiList } = this.state; - const textValue = convertToText(inputHTML); - const processedHTML = emojify(inputHTML, emojiList); + // replace :emoji: with the emoji + injectEmoji() { + const { inputHTML, emojiList } = this.state; + const textValue = convertToText(inputHTML); + const processedHTML = emojify(inputHTML, emojiList); - if (textValue != convertToText(processedHTML)) { - this.setState({ - inputHTML: processedHTML, - }); - return true; - } - return false; - } + if (textValue != convertToText(processedHTML)) { + this.setState({ + inputHTML: processedHTML, + }); + return true; + } + return false; + } - handleMessageInputKeydown(event) { - const key = event && event.key; + handleMessageInputKeydown(event) { + const key = event && event.key; - if (key === 'Enter') { - if (!this.prepNewLine) { - this.sendMessage(); - event.preventDefault(); - this.prepNewLine = false; - return; - } - } - // allow key presses such as command/shift/meta, etc even when message length is full later. - if (CHAT_KEY_MODIFIERS.includes(key)) { - this.modifierKeyPressed = true; - } - if (key === 'Control' || key === 'Shift') { - this.prepNewLine = true; - } - if (key === 'Tab') { - const { chatUserNames } = this.props; - const { emojiNames } = this.state; - if (this.autoComplete('@', chatUserNames)) { - event.preventDefault(); - } - if (this.autoComplete(':', emojiNames)) { - event.preventDefault(); - } - } + if (key === 'Enter') { + if (!this.prepNewLine) { + this.sendMessage(); + event.preventDefault(); + this.prepNewLine = false; + return; + } + } + // allow key presses such as command/shift/meta, etc even when message length is full later. + if (CHAT_KEY_MODIFIERS.includes(key)) { + this.modifierKeyPressed = true; + } + if (key === 'Control' || key === 'Shift') { + this.prepNewLine = true; + } + if (key === 'Tab') { + const { chatUserNames } = this.props; + const { emojiNames } = this.state; + if (this.autoComplete('@', chatUserNames)) { + event.preventDefault(); + } + if (this.autoComplete(':', emojiNames)) { + event.preventDefault(); + } + } - // if new input pushes the potential chars over, don't do anything - const formField = this.formMessageInput.current; - const tempCharsLeft = this.calculateCurrentBytesLeft(formField.innerHTML); - if (tempCharsLeft <= 0 && !CHAT_OK_KEYCODES.includes(key)) { - if (!this.modifierKeyPressed) { - event.preventDefault(); // prevent typing more - } - return; - } - } + // if new input pushes the potential chars over, don't do anything + const formField = this.formMessageInput.current; + const tempCharsLeft = this.calculateCurrentBytesLeft(formField.innerHTML); + if (tempCharsLeft <= 0 && !CHAT_OK_KEYCODES.includes(key)) { + if (!this.modifierKeyPressed) { + event.preventDefault(); // prevent typing more + } + return; + } + } - handleMessageInputKeyup(event) { - const { key } = event; - if (key === 'Control' || key === 'Shift') { - this.prepNewLine = false; - } - if (CHAT_KEY_MODIFIERS.includes(key)) { - this.modifierKeyPressed = false; - } + handleMessageInputKeyup(event) { + const { key } = event; + if (key === 'Control' || key === 'Shift') { + this.prepNewLine = false; + } + if (CHAT_KEY_MODIFIERS.includes(key)) { + this.modifierKeyPressed = false; + } - if (key === ':' || key === ';') { - this.injectEmoji(); - } - } + if (key === ':' || key === ';') { + this.injectEmoji(); + } + } - handleMessageInputBlur() { - this.prepNewLine = false; - this.modifierKeyPressed = false; - } + handleMessageInputBlur() { + this.prepNewLine = false; + this.modifierKeyPressed = false; + } - handlePaste(event) { - // don't allow paste if too much text already - if (this.state.inputCharsLeft < 0) { - event.preventDefault(); - return; - } - convertOnPaste(event, this.state.emojiList); - this.handleMessageInputKeydown(event); - } + handlePaste(event) { + // don't allow paste if too much text already + if (this.state.inputCharsLeft < 0) { + event.preventDefault(); + return; + } + convertOnPaste(event, this.state.emojiList); + this.handleMessageInputKeydown(event); + } - handleSubmitChatButton(event) { - event.preventDefault(); - this.sendMessage(); - } + handleSubmitChatButton(event) { + event.preventDefault(); + this.sendMessage(); + } - sendMessage() { - const { handleSendMessage, inputMaxBytes } = this.props; - const { hasSentFirstChatMessage, inputHTML, inputCharsLeft } = this.state; - if (inputCharsLeft < 0) { - return; - } - const message = convertToText(inputHTML); - const newStates = { - inputHTML: '', - inputCharsLeft: inputMaxBytes, - }; + sendMessage() { + const { handleSendMessage, inputMaxBytes } = this.props; + const { hasSentFirstChatMessage, inputHTML, inputCharsLeft } = this.state; + if (inputCharsLeft < 0) { + return; + } + const message = convertToText(inputHTML); + const newStates = { + inputHTML: '', + inputCharsLeft: inputMaxBytes, + }; - handleSendMessage(message); + handleSendMessage(message); - if (!hasSentFirstChatMessage) { - newStates.hasSentFirstChatMessage = true; - setLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT, true); - } + if (!hasSentFirstChatMessage) { + newStates.hasSentFirstChatMessage = true; + setLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT, true); + } - // clear things out. - this.setState(newStates); - } + // clear things out. + this.setState(newStates); + } - handleContentEditableChange(event) { - const value = event.target.value; - this.setState({ - inputHTML: value, - inputCharsLeft: this.calculateCurrentBytesLeft(value), - }); - } + handleContentEditableChange(event) { + const value = event.target.value; + this.setState({ + inputHTML: value, + inputCharsLeft: this.calculateCurrentBytesLeft(value), + }); + } - calculateCurrentBytesLeft(inputContent) { - const { inputMaxBytes } = this.props; - const curBytes = new Blob([trimNbsp(inputContent)]).size; - return inputMaxBytes - curBytes; - } + calculateCurrentBytesLeft(inputContent) { + const { inputMaxBytes } = this.props; + const curBytes = new Blob([trimNbsp(inputContent)]).size; + return inputMaxBytes - curBytes; + } - render(props, state) { - const { hasSentFirstChatMessage, inputCharsLeft, inputHTML, emojiPicker } = - state; - const { inputEnabled, inputMaxBytes } = props; - const emojiButtonStyle = { - display: emojiPicker && inputCharsLeft > 0 ? 'block' : 'none', - }; - const extraClasses = classNames({ - 'display-count': inputCharsLeft <= CHAT_CHAR_COUNT_BUFFER, - }); - const placeholderText = generatePlaceholderText( - inputEnabled, - hasSentFirstChatMessage - ); - return html` -
-
- <${ContentEditable} - id="message-input" - aria-role="textbox" - class="appearance-none block w-full bg-transparent text-sm text-gray-700 h-full focus:outline-none" - aria-placeholder=${placeholderText} - innerRef=${this.formMessageInput} - html=${inputHTML} - disabled=${!inputEnabled} - onChange=${this.handleContentEditableChange} - onKeyDown=${this.handleMessageInputKeydown} - onKeyUp=${this.handleMessageInputKeyup} - onBlur=${this.handleMessageInputBlur} - onPaste=${this.handlePaste} - /> -
-
- - + render(props, state) { + const { hasSentFirstChatMessage, inputCharsLeft, inputHTML, emojiPicker } = + state; + const { inputEnabled, inputMaxBytes } = props; + const emojiButtonStyle = { + display: emojiPicker && inputCharsLeft > 0 ? 'block' : 'none', + }; + const extraClasses = classNames({ + 'display-count': inputCharsLeft <= CHAT_CHAR_COUNT_BUFFER, + }); + const placeholderText = generatePlaceholderText( + inputEnabled, + hasSentFirstChatMessage + ); + return html` +
+
+ <${ContentEditable} + id="message-input" + aria-role="textbox" + class="appearance-none block w-full bg-transparent text-sm text-gray-700 h-full focus:outline-none" + aria-placeholder=${placeholderText} + innerRef=${this.formMessageInput} + html=${inputHTML} + disabled=${!inputEnabled} + onChange=${this.handleContentEditableChange} + onKeyDown=${this.handleMessageInputKeydown} + onKeyUp=${this.handleMessageInputKeyup} + onBlur=${this.handleMessageInputBlur} + onPaste=${this.handlePaste} + /> +
+
+ + - - + + - ${inputCharsLeft} bytes -
-
- `; - } + ${inputCharsLeft} bytes +
+
+ `; + } }