- fix chrome mobile form focus bug by specifying class. when form focuses media query widths change and may think portrait is in landcape and therefore hide the form.
- cleanup now unused methods - jump to bottom from vue prop listener
This commit is contained in:
parent
594e1c774a
commit
cf27b157e6
@ -87,11 +87,8 @@ GW TODO:
|
||||
</div>
|
||||
|
||||
<div id="user-content" class="user-content">
|
||||
|
||||
<!-- USER CONTENT... -->
|
||||
<div v-html="description"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -101,13 +98,12 @@ GW TODO:
|
||||
|
||||
|
||||
<div id="user-content-touch" class="user-content">
|
||||
|
||||
<!-- USER CONTENT... -->
|
||||
<div v-html="description"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="chat-container" class="bg-gray-800">
|
||||
|
||||
<div id="messages-container">
|
||||
<div v-for="message in messages">
|
||||
<div class="message flex">
|
||||
@ -129,7 +125,7 @@ GW TODO:
|
||||
<form id="message-form" class="flex">
|
||||
|
||||
<input type="hidden" name="inputAuthor" id="self-message-author" />
|
||||
|
||||
|
||||
<textarea
|
||||
id="message-body-form"
|
||||
placeholder="Message"
|
||||
|
@ -7,6 +7,7 @@ async function setupApp() {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
window.app = new Vue({
|
||||
el: "#app-container",
|
||||
data: {
|
||||
@ -18,16 +19,28 @@ async function setupApp() {
|
||||
description: "",
|
||||
title: "",
|
||||
},
|
||||
watch: {
|
||||
messages: {
|
||||
deep: true,
|
||||
handler: function (newMessages, oldMessages) {
|
||||
if (newMessages.length !== oldMessages.length) {
|
||||
// jump to bottom
|
||||
jumpToBottom(appMessaging.scrollableMessagesContainer);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// init messaging interactions
|
||||
var appMessagingMisc = new Messaging();
|
||||
appMessagingMisc.init();
|
||||
var appMessaging = new Messaging();
|
||||
appMessaging.init();
|
||||
|
||||
const config = await new Config().init();
|
||||
app.title = config.title;
|
||||
|
||||
const configFileLocation = "./js/config.json";
|
||||
const configFileLocation = "./js/config.json";
|
||||
|
||||
try {
|
||||
const pageContentFile = "/static/content.md"
|
||||
@ -46,7 +59,7 @@ async function setupApp() {
|
||||
|
||||
var websocketReconnectTimer;
|
||||
function setupWebsocket() {
|
||||
clearTimeout(websocketReconnectTimer)
|
||||
clearTimeout(websocketReconnectTimer);
|
||||
|
||||
// Uncomment to point to somewhere other than goth.land
|
||||
const protocol = location.protocol == "https:" ? "wss" : "ws"
|
||||
@ -60,35 +73,34 @@ function setupWebsocket() {
|
||||
// Ignore non-chat messages (such as keepalive PINGs)
|
||||
if (model.type !== SocketMessageTypes.CHAT) { return; }
|
||||
|
||||
const message = new Message(model)
|
||||
const message = new Message(model);
|
||||
|
||||
const existing = this.app.messages.filter(function (item) {
|
||||
return item.id === message.id
|
||||
return item.id === message.id;
|
||||
})
|
||||
|
||||
if (existing.length === 0 || !existing) {
|
||||
this.app.messages.push(message);
|
||||
setTimeout(() => { jumpToBottom("#messages-container"); } , 50); // could be better. is there a sort of Vue "componentDidUpdate" we can do this on?
|
||||
this.app.messages = [...this.app.messages, message];
|
||||
}
|
||||
}
|
||||
|
||||
ws.onclose = (e) => {
|
||||
// connection closed, discard old websocket and create a new one in 5s
|
||||
ws = null
|
||||
ws = null;
|
||||
console.log("Websocket closed.")
|
||||
websocketReconnectTimer = setTimeout(setupWebsocket, 5000)
|
||||
websocketReconnectTimer = setTimeout(setupWebsocket, 5000);
|
||||
}
|
||||
|
||||
// On ws error just close the socket and let it re-connect again for now.
|
||||
ws.onerror = (e) => {
|
||||
console.log("Websocket error: ", e)
|
||||
ws.close()
|
||||
console.log("Websocket error: ", e);
|
||||
ws.close();
|
||||
}
|
||||
|
||||
window.ws = ws;
|
||||
}
|
||||
|
||||
setupApp()
|
||||
setupApp();
|
||||
|
||||
setupWebsocket()
|
||||
setupWebsocket();
|
||||
|
||||
|
@ -12,12 +12,9 @@ class Message {
|
||||
this.type = model.type;
|
||||
}
|
||||
|
||||
addNewlines(str) {
|
||||
return str.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
}
|
||||
formatText() {
|
||||
var linked = autoLink(this.body, { embed: true });
|
||||
return this.addNewlines(linked);
|
||||
return addNewlines(linked);
|
||||
}
|
||||
userColor() {
|
||||
return messageBubbleColorForString(this.author);
|
||||
@ -25,7 +22,6 @@ class Message {
|
||||
}
|
||||
|
||||
|
||||
// convert newlines to <br>s
|
||||
|
||||
class Messaging {
|
||||
constructor() {
|
||||
@ -41,25 +37,24 @@ class Messaging {
|
||||
this.keyChatDisplayed = "owncast_chat";
|
||||
|
||||
this.tagAppContainer = document.querySelector("#app-container");
|
||||
|
||||
this.tagChatToggle = document.querySelector("#chat-toggle");
|
||||
|
||||
this.textUserInfoDisplay = document.querySelector("#user-info-display");
|
||||
this.tagUserInfoChanger = document.querySelector("#user-info-change");
|
||||
|
||||
this.tagUsernameDisplay = document.querySelector("#username-display");
|
||||
this.imgUsernameAvatar = document.querySelector("#username-avatar");
|
||||
this.tagMessageFormWarning = document.querySelector("#message-form-warning");
|
||||
|
||||
this.inputMessageAuthor = document.querySelector("#self-message-author");
|
||||
|
||||
this.tagMessageFormWarning = document.querySelector("#message-form-warning");
|
||||
|
||||
this.inputChangeUserName = document.querySelector("#username-change-input");
|
||||
|
||||
this.btnUpdateUserName = document.querySelector("#button-update-username");
|
||||
this.btnCancelUpdateUsername = document.querySelector("#button-cancel-change");
|
||||
this.btnSubmitMessage = document.querySelector("#button-submit-message");
|
||||
|
||||
this.formMessageInput = document.querySelector("#message-body-form");
|
||||
|
||||
this.imgUsernameAvatar = document.querySelector("#username-avatar");
|
||||
this.textUserInfoDisplay = document.querySelector("#user-info-display");
|
||||
|
||||
this.scrollableMessagesContainer = document.querySelector("#messages-container");
|
||||
}
|
||||
init() {
|
||||
this.tagChatToggle.addEventListener("click", this.handleChatToggle.bind(this));
|
||||
@ -74,16 +69,13 @@ class Messaging {
|
||||
this.initLocalStates();
|
||||
|
||||
if (hasTouchScreen()) {
|
||||
this.scrollableMessagesContainer = document.body;
|
||||
this.tagAppContainer.classList.add("touch-screen");
|
||||
window.onorientationchange = this.handleOrientationChange.bind(this);
|
||||
this.handleOrientationChange();
|
||||
|
||||
// this.formMessageInput.addEventListener("focus", this.handleKeyboardAppear.bind(this));
|
||||
// this.formMessageInput.addEventListener("blur", this.handleKeyboardOut.bind(this));
|
||||
} else {
|
||||
this.tagAppContainer.classList.add("desktop");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
initLocalStates() {
|
||||
@ -103,7 +95,7 @@ class Messaging {
|
||||
if (this.chatDisplayed) {
|
||||
this.tagAppContainer.classList.add("chat");
|
||||
this.tagAppContainer.classList.remove("no-chat");
|
||||
setTimeout(() => { jumpToBottom(); } , 50);
|
||||
jumpToBottom(this.scrollableMessagesContainer);
|
||||
} else {
|
||||
this.tagAppContainer.classList.add("no-chat");
|
||||
this.tagAppContainer.classList.remove("chat");
|
||||
@ -111,10 +103,6 @@ class Messaging {
|
||||
}
|
||||
|
||||
handleOrientationChange() {
|
||||
// mobileVHhack();
|
||||
// if small landscape, hide chat
|
||||
// var mql = window.matchMedia("(orientation: landscape)"); // what it _was_
|
||||
|
||||
var isPortrait = Math.abs(window.orientation % 180) === 0;
|
||||
|
||||
if(!isPortrait) {
|
||||
@ -128,15 +116,6 @@ class Messaging {
|
||||
}
|
||||
}
|
||||
|
||||
// handleKeyboardAppear() {
|
||||
// setTimeout(() => {this.tagAppContainer.classList.add("message-input-focus");}, 50);
|
||||
// mobileVHhack();
|
||||
// }
|
||||
// handleKeyboardOut() {
|
||||
// setTimeout(() => {this.tagAppContainer.classList.remove("message-input-focus");}, 50);
|
||||
// mobileVHhack();
|
||||
// }
|
||||
|
||||
handleChatToggle() {
|
||||
this.chatDisplayed = !this.chatDisplayed;
|
||||
if (this.chatDisplayed) {
|
||||
@ -179,7 +158,6 @@ class Messaging {
|
||||
var okCodes = [37,38,39,40,16,91,18,46,8];
|
||||
var value = this.formMessageInput.value.trim();
|
||||
var numCharsLeft = this.maxMessageLength - value.length;
|
||||
|
||||
if (event.keyCode === 13) { // enter
|
||||
if (!this.prepNewLine) {
|
||||
this.submitChat(value);
|
||||
|
@ -22,13 +22,17 @@ function clearLocalStorage(key) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
function jumpToBottom(id) {
|
||||
const div = id ? document.querySelector(id) : document.body;
|
||||
div.scrollTo({
|
||||
top: div.scrollHeight,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
// jump down to the max height of a div, with a slight delay
|
||||
function jumpToBottom(element) {
|
||||
if (!element) return;
|
||||
|
||||
setTimeout(() => {
|
||||
element.scrollTo({
|
||||
top: element.scrollHeight,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}, 50, element);
|
||||
}
|
||||
|
||||
function uuidv4() {
|
||||
@ -38,17 +42,10 @@ function uuidv4() {
|
||||
});
|
||||
}
|
||||
|
||||
function setVHvar() {
|
||||
var vh = window.innerHeight * 0.01;
|
||||
// Then we set the value in the --vh custom property to the root of the document
|
||||
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
||||
console.log("== new vh", vh)
|
||||
// convert newlines to <br>s
|
||||
function addNewlines(str) {
|
||||
return str.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
}
|
||||
// delayed
|
||||
function mobileVHhack() {
|
||||
setTimeout(setVHvar, 100);
|
||||
}
|
||||
|
||||
|
||||
// Trying to determine if browser is mobile/tablet.
|
||||
// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
|
||||
|
@ -9,6 +9,17 @@
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Tailwind sets list styles to none. I don't know why. */
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: unset;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
background: transparent;
|
||||
@ -378,6 +389,7 @@ header h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 640px ) {
|
||||
:root {
|
||||
--video-container-height: 36vh;
|
||||
@ -391,28 +403,20 @@ header h1 {
|
||||
}
|
||||
|
||||
@media screen and (orientation: landscape) and (max-width: 1024px) {
|
||||
:root {
|
||||
:root .landscape {
|
||||
--video-container-height: 75vh;
|
||||
}
|
||||
#main-mobile-container {
|
||||
.touch-screen.landscape #chat-container-wrap {
|
||||
margin-top: calc(var(--header-height) + var(--video-container-height));
|
||||
}
|
||||
.touch-screen .user-content {
|
||||
.touch-screen.landscape .user-content {
|
||||
display: block;
|
||||
}
|
||||
.touch-screen #chat-container {
|
||||
.touch-screen.landscape #chat-container {
|
||||
display: none;
|
||||
}
|
||||
.touch-screen #chat-toggle {
|
||||
.touch-screen.landscape #chat-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tailwind sets list styles to none. I don't know why. */
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: unset;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user