0

- 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:
Ginger Wong 2020-06-18 00:06:10 -07:00
parent 594e1c774a
commit cf27b157e6
5 changed files with 69 additions and 82 deletions

View File

@ -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"

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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;
}