diff --git a/webroot/index-standalone-chat.html b/webroot/index-standalone-chat.html index ad2a7e483..463eb3c1c 100644 --- a/webroot/index-standalone-chat.html +++ b/webroot/index-standalone-chat.html @@ -8,22 +8,17 @@ - -
diff --git a/webroot/index-video-only.html b/webroot/index-video-only.html index cecd5583c..748bd4bdc 100644 --- a/webroot/index-video-only.html +++ b/webroot/index-video-only.html @@ -20,15 +20,9 @@
diff --git a/webroot/index.html b/webroot/index.html index 4263caa4c..40a1eb1fd 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -28,54 +28,47 @@ + + - + +
- - -
- - + + - + .noscript a { + display: inline; + color: blue; + text-decoration: underline; + } + +
+ +
+

+ This Owncast stream requires Javascript to play. +

+
+ + diff --git a/webroot/js/app-standalone-chat.js b/webroot/js/app-standalone-chat.js index a5c4f1cb0..d2a2d0d0f 100644 --- a/webroot/js/app-standalone-chat.js +++ b/webroot/js/app-standalone-chat.js @@ -29,10 +29,6 @@ export default class StandaloneChat extends Component { }); } - handleChatToggle() { - return; - } - render(props, state) { const { username, userAvatarImage, websocket } = state; diff --git a/webroot/js/components/chat/chat-input.js b/webroot/js/components/chat/chat-input.js index b2482105a..665195d84 100644 --- a/webroot/js/components/chat/chat-input.js +++ b/webroot/js/components/chat/chat-input.js @@ -16,7 +16,7 @@ export default class ChatInput extends Component { this.emojiPickerButton = createRef(); this.messageCharCount = 0; - this.maxMessageLength = 500; + this.maxMessageLength = 500; this.maxMessageBuffer = 20; this.emojiPicker = null; @@ -98,94 +98,107 @@ export default class ChatInput extends Component { } // autocomplete user names - autoCompleteNames() { + autoCompleteNames() { const { chatUserNames } = this.props; - const { inputHTML } = this.state; - const position = getCaretPosition(this.formMessageInput.current); - const at = inputHTML.lastIndexOf('@', position - 1); - if (at === -1) { - return false; - } + const { inputHTML } = this.state; + const position = getCaretPosition(this.formMessageInput.current); + const at = inputHTML.lastIndexOf('@', position - 1); + if (at === -1) { + return false; + } - let partial = inputHTML.substring(at + 1, position).trim(); + let partial = inputHTML.substring(at + 1, position).trim(); - if (partial === this.suggestion) { - partial = this.partial; - } else { - this.partial = partial; - } + if (partial === this.suggestion) { + partial = this.partial; + } else { + this.partial = partial; + } - const possibilities = chatUserNames.filter(function (username) { - return username.toLowerCase().startsWith(partial.toLowerCase()); - }); + const possibilities = chatUserNames.filter(function (username) { + return username.toLowerCase().startsWith(partial.toLowerCase()); + }); - if (this.completionIndex === undefined || ++this.completionIndex >= possibilities.length) { - this.completionIndex = 0; - } + if (this.completionIndex === undefined || ++this.completionIndex >= possibilities.length) { + this.completionIndex = 0; + } - if (possibilities.length > 0) { - this.suggestion = possibilities[this.completionIndex]; + if (possibilities.length > 0) { + this.suggestion = possibilities[this.completionIndex]; this.setState({ inputHTML: inputHTML.substring(0, at + 1) + this.suggestion + ' ' + inputHTML.substring(position), }) - } + } - return true; + return true; } handleMessageInputKeydown(event) { - const okCodes = [37,38,39,40,16,91,18,46,8]; + const okCodes = [ + 'ArrowLeft', + 'ArrowUp', + 'ArrowRight', + 'ArrowDown', + 'Shift', + 'Meta', + 'Alt', + 'Delete', + 'Backspace', + ]; + // const okCodes = [37,38,39,40,16,91,18,46,8];//left, up , right , down , shift, left window key, alt, delete, backspace const formField = this.formMessageInput.current; let textValue = formField.innerText.trim(); // get this only to count chars let numCharsLeft = this.maxMessageLength - textValue.length; - if (event.keyCode === 13) { // enter - if (!this.prepNewLine) { - this.sendMessage(); - event.preventDefault(); - this.prepNewLine = false; - return; - } - } - if (event.keyCode === 16 || event.keyCode === 17) { // ctrl, shift - this.prepNewLine = true; - } - if (event.keyCode === 9) { // tab - if (this.autoCompleteNames()) { - event.preventDefault(); + const key = event.key; - // value could have been changed, update char count - textValue = formField.innerText.trim(); - numCharsLeft = this.maxMessageLength - textValue.length; - } - } + if (key === 'Enter') { + if (!this.prepNewLine) { + this.sendMessage(); + event.preventDefault(); + this.prepNewLine = false; + return; + } + } + if (key === 'Control' || key === 'Shift') { + this.prepNewLine = true; + } + if (key === 'Tab') { + if (this.autoCompleteNames()) { + event.preventDefault(); + + // value could have been changed, update char count + textValue = formField.innerText.trim(); + numCharsLeft = this.maxMessageLength - textValue.length; + } + } // text count - if (numCharsLeft <= this.maxMessageBuffer) { - this.setState({ + if (numCharsLeft <= this.maxMessageBuffer) { + this.setState({ inputWarning: `${numCharsLeft} chars left`, }); - if (numCharsLeft <= 0 && !okCodes.includes(event.keyCode)) { - event.preventDefault(); // prevent typing more - return; - } - } else { + if (numCharsLeft <= 0 && !okCodes.includes(key)) { + event.preventDefault(); // prevent typing more + return; + } + } else { this.setState({ inputWarning: '', }); - } - } + } + } - handleMessageInputKeyup(event) { - if (event.keyCode === 16 || event.keyCode === 17) { // ctrl, shift - this.prepNewLine = false; - } - } + handleMessageInputKeyup(event) { + if (event.key === 'Control' || event.key === 'Shift') { + this.prepNewLine = false; + } + } - handleMessageInputBlur(event) { - this.prepNewLine = false; + handleMessageInputBlur(event) { + this.prepNewLine = false; } handlePaste(event) { diff --git a/webroot/js/components/chat/chat.js b/webroot/js/components/chat/chat.js index e6a24de32..37b60cec5 100644 --- a/webroot/js/components/chat/chat.js +++ b/webroot/js/components/chat/chat.js @@ -95,9 +95,9 @@ export default class Chat extends Component { sendUsernameChange(oldName, newName, image) { const nameChange = { type: SOCKET_MESSAGE_TYPES.NAME_CHANGE, - oldName: oldName, - newName: newName, - image: image, + oldName, + newName, + image, }; this.websocket.send(nameChange); } @@ -106,12 +106,14 @@ export default class Chat extends Component { this.addMessage(message); } - // if incoming message has same id as existing message, don't add it addMessage(message) { const { messages: curMessages } = this.state; + + // if incoming message has same id as existing message, don't add it const existing = curMessages.filter(function (item) { return item.id === message.id; }) + if (existing.length === 0 || !existing) { const newState = { messages: [...curMessages, message], diff --git a/webroot/js/utils/chat.js b/webroot/js/utils/chat.js index 896c2cc92..4b6ff89b1 100644 --- a/webroot/js/utils/chat.js +++ b/webroot/js/utils/chat.js @@ -112,7 +112,10 @@ function getYoutubeIdFromURL(url) { } function getYoutubeEmbedFromID(id) { - return ``; + return ` +
+ +
`; } function getInstagramEmbedFromURL(url) {