0

fix responsive styles

This commit is contained in:
Ginger Wong 2020-08-24 03:30:42 -07:00
parent 0b1f9db4ed
commit 2a02b75e42
9 changed files with 192 additions and 85 deletions

View File

@ -1,10 +1,3 @@
<!--
todo
- fix / consolidate responsive styles
- standalone video.html
-->
<html>
<head>
<meta charset="UTF-8" />
@ -36,10 +29,10 @@
<!-- markdown renderer -->
<script src="//unpkg.com/showdown/dist/showdown.min.js"></script>
<link href="./styles/app.css" rel="stylesheet" />
<link href="./styles/video.css" rel="stylesheet" />
<link href="./styles/chat.css" rel="stylesheet" />
<link href="./styles/user-content.css" rel="stylesheet" />
<link href="./styles/app.css" rel="stylesheet" />
</head>

View File

@ -9,27 +9,31 @@ import Chat from './components/chat/chat.js';
import Websocket from './utils/websocket.js';
import {
getLocalStorage,
setLocalStorage,
addNewlines,
classNames,
clearLocalStorage,
debounce,
generateAvatar,
generateUsername,
addNewlines,
getLocalStorage,
pluralize,
setLocalStorage,
} from './utils/helpers.js';
import {
URL_OWNCAST,
URL_CONFIG,
URL_STATUS,
TIMER_STATUS_UPDATE,
TIMER_DISABLE_CHAT_AFTER_OFFLINE,
TIMER_STREAM_DURATION_COUNTER,
TEMP_IMAGE,
MESSAGE_OFFLINE,
MESSAGE_ONLINE,
KEY_USERNAME,
HEIGHT_SHORT_WIDE,
KEY_AVATAR,
KEY_CHAT_DISPLAYED,
KEY_USERNAME,
MESSAGE_OFFLINE,
MESSAGE_ONLINE,
TEMP_IMAGE,
TIMER_DISABLE_CHAT_AFTER_OFFLINE,
TIMER_STATUS_UPDATE,
TIMER_STREAM_DURATION_COUNTER,
URL_CONFIG,
URL_OWNCAST,
URL_STATUS,
WIDTH_SINGLE_COL,
} from './utils/constants.js';
export default class App extends Component {
@ -41,7 +45,8 @@ export default class App extends Component {
displayChat: getLocalStorage(KEY_CHAT_DISPLAYED), // chat panel state
chatEnabled: false, // chat input box state
username: getLocalStorage(KEY_USERNAME) || generateUsername(),
userAvatarImage: getLocalStorage(KEY_AVATAR) || generateAvatar(`${this.username}${Date.now()}`),
userAvatarImage:
getLocalStorage(KEY_AVATAR) || generateAvatar(`${this.username}${Date.now()}`),
configData: {},
extraUserContent: '',
@ -54,6 +59,10 @@ export default class App extends Component {
viewerCount: '',
sessionMaxViewerCount: '',
overallMaxViewerCount: '',
// dom
windowWidth: window.innerWidth,
windowHeight: window.innerHeight,
};
// timers
@ -66,6 +75,7 @@ export default class App extends Component {
// misc dom events
this.handleChatPanelToggle = this.handleChatPanelToggle.bind(this);
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handleWindowResize = debounce(this.handleWindowResize.bind(this), 400);
this.handleOfflineMode = this.handleOfflineMode.bind(this);
this.handleOnlineMode = this.handleOnlineMode.bind(this);
@ -81,12 +91,11 @@ export default class App extends Component {
this.getConfig = this.getConfig.bind(this);
this.getStreamStatus = this.getStreamStatus.bind(this);
this.getExtraUserContent = this.getExtraUserContent.bind(this);
}
componentDidMount() {
this.getConfig();
window.addEventListener('resize', this.handleWindowResize);
this.player = new OwncastPlayer();
this.player.setupPlayerCallbacks({
@ -161,7 +170,6 @@ export default class App extends Component {
});
}
setConfigData(data = {}) {
const { title, extraUserInfoFileName, summary } = data;
@ -301,21 +309,30 @@ export default class App extends Component {
console.log(`>>> App Error: ${error}`);
}
handleWindowResize() {
this.setState({
windowWidth: window.innerWidth,
windowHeight: window.innerHeight,
});
}
render(props, state) {
const {
username,
userAvatarImage,
websocket,
chatEnabled,
configData,
extraUserContent,
displayChat,
viewerCount,
sessionMaxViewerCount,
extraUserContent,
overallMaxViewerCount,
playerActive,
sessionMaxViewerCount,
streamOnline,
streamStatusMessage,
chatEnabled,
userAvatarImage,
username,
viewerCount,
websocket,
windowHeight,
windowWidth,
} = state;
const {
@ -347,14 +364,23 @@ export default class App extends Component {
</li>
`);
const chatClass = displayChat ? 'chat' : 'no-chat';
const mainClass = playerActive ? 'online' : '';
const streamInfoClass = streamOnline ? 'online' : '';
const streamInfoClass = streamOnline ? 'online' : ''; // need?
const shortHeight = windowHeight <= HEIGHT_SHORT_WIDE;
const singleColMode = windowWidth <= WIDTH_SINGLE_COL && !shortHeight;
const extraAppClasses = classNames({
'chat': displayChat,
'no-chat': !displayChat,
'single-col': singleColMode,
'bg-gray-800': singleColMode && displayChat,
'short-wide': shortHeight,
})
return (
html`
<div id="app-container" class="flex w-full flex-col justify-start relative ${chatClass}">
<div id="top-content">
<div id="app-container" class="flex w-full flex-col justify-start relative ${extraAppClasses}">
<div id="top-content" class="z-50">
<header class="flex border-b border-gray-900 border-solid shadow-md fixed z-10 w-full top-0 left-0 flex flex-row justify-between flex-no-wrap">
<h1 class="flex flex-row items-center justify-start p-2 uppercase text-gray-400 text-xl font-thin tracking-wider overflow-hidden whitespace-no-wrap">
<span
@ -392,7 +418,6 @@ export default class App extends Component {
></video>
</div>
<section id="stream-info" aria-label="Stream status" class="flex text-center flex-row justify-between font-mono py-2 px-8 bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid ${streamInfoClass}">
<span>${streamStatusMessage}</span>
<span>${viewerCount} ${pluralize('viewer', viewerCount)}.</span>
@ -440,16 +465,15 @@ export default class App extends Component {
<span class="mx-1 inline-block">Version ${appVersion}</span>
</footer>
<${Chat}
websocket=${websocket}
username=${username}
userAvatarImage=${userAvatarImage}
chatEnabled=${chatEnabled}
chatEnabled //=${chatEnabled}
/>
</div>
`);
`
);
}
}

View File

@ -232,7 +232,7 @@ export default class ChatInput extends Component {
const placeholderText = generatePlaceholderText(inputEnabled, hasSentFirstChatMessage);
return (
html`
<div id="message-input-container" class="w-full shadow-md bg-gray-900 border-t border-gray-700 border-solid p-4">
<div id="message-input-container" class="fixed bottom-0 shadow-md bg-gray-900 border-t border-gray-700 border-solid p-4">
<${ContentEditable}
id="message-input"

View File

@ -21,14 +21,11 @@ export default class Chat extends Component {
this.scrollableMessagesContainer = createRef();
this.websocket = null;
this.getChatHistory = this.getChatHistory.bind(this);
this.receivedWebsocketMessage = this.receivedWebsocketMessage.bind(this);
this.websocketDisconnected = this.websocketDisconnected.bind(this);
// this.handleSubmitChatButton = this.handleSubmitChatButton.bind(this);
this.submitChat = this.submitChat.bind(this);
}
@ -39,7 +36,6 @@ export default class Chat extends Component {
if (hasTouchScreen()) {
setVHvar();
window.addEventListener("orientationchange", setVHvar);
// this.tagAppContainer.classList.add('touch-screen');
}
}

View File

@ -22,8 +22,9 @@ export default class UsernameForm extends Component {
}
handleDisplayForm() {
const { displayForm: curDisplay } = this.state;
this.setState({
displayForm: true,
displayForm: !curDisplay,
});
}
@ -65,7 +66,7 @@ export default class UsernameForm extends Component {
const formDisplayStyle = narrowSpace ? 'inline-block' : 'flex';
const styles = {
info: {
display: displayForm || narrowSpace ? 'none' : 'flex',
display: displayForm ? 'none' : 'flex',
},
form: {
display: displayForm ? formDisplayStyle : 'none',

View File

@ -27,3 +27,8 @@ export const KEY_CHAT_FIRST_MESSAGE_SENT = 'owncast_first_message_sent';
export const CHAT_INITIAL_PLACEHOLDER_TEXT = 'Type here to chat, no account necessary.';
export const CHAT_PLACEHOLDER_TEXT = 'Message';
export const CHAT_PLACEHOLDER_OFFLINE = 'Chat is offline.';
// app styling
export const WIDTH_SINGLE_COL = 730;
export const HEIGHT_SHORT_WIDE = 500;

View File

@ -128,3 +128,32 @@ export function classNames(json) {
});
return classes.join(' ');
}
// taken from
// https://medium.com/@TCAS3/debounce-deep-dive-javascript-es6-e6f8d983b7a1
export function debounce(fn, time) {
let timeout;
return function() {
const functionCall = () => fn.apply(this, arguments);
clearTimeout(timeout);
timeout = setTimeout(functionCall, time);
}
}
/*
const debouncedHandleResize = debounce(function handleResize() {
setDimensions({
height: window.innerHeight,
width: window.innerWidth
})
}, 1000)
window.addEventListener('resize', debouncedHandleResize)
window.addEventListener('keyup', debounce((e) => {
console.log(e);
}, 1000));
*/

View File

@ -1,6 +1,6 @@
/*
Spefici styles for app layout
Specific styles for main app layout.
May have overrides for other components with own stylesheets.
*/
/* variables */
@ -25,6 +25,10 @@ a:hover {
background: transparent;
}
* {
transition: all .25s;
}
button[disabled] {
opacity: .5;
pointer-events: none;
@ -68,11 +72,11 @@ header {
/* ************************************************ */
#video-container {
height: calc(var(--video-container-height));
height: var(--video-container-height);
margin-top: var(--header-height);
position: relative;
width: 100%;
/* height: calc((9 / 16) * 100vw); */
min-height: 480px;
background-size: 30%;
}
@ -97,13 +101,79 @@ header {
opacity: .75;
}
.no-chat #chat-container-wrap {
display: none;
}
/* *********** overrides when chat is on ***************************** */
.chat {
--content-width: calc(100vw - var(--right-col-width));
}
.chat #chat-container-wrap {
display: block;
}
.chat #video-container,
.chat #stream-info,
.chat #user-content {
width: calc(100% - var(--right-col-width));
width: var(--content-width);
}
.chat #video-container {
height: calc((9 / 16) * var(--content-width));
}
.short-wide.chat #video-container {
height: calc(100vh - var(--header-height) - 3rem);
min-height: auto;
}
.short-wide #message-input {
height: 3rem;
}
/* *********** single col layout ***************************** */
.single-col {
--right-col-width: 0px;
}
.single-col main {
position: fixed;
width: 100%;
z-index: 40;
}
.single-col #chat-container {
position: relative;
width: 100%;
height: auto;
}
.single-col #video-container {
min-height: auto;
width: 100%;
}
.single-col #user-content,
.single-col #chat-container-wrap {
margin-top: calc(var(--video-container-height) + var(--header-height) + 1rem);
}
.single-col #user-content .user-content {
flex-wrap: wrap;
justify-content: center;
}
.single-col.chat #user-content {
display: none;
}
.single-col #message-input-container {
width: 100%;
}
.single-col #message-input {
height: 3rem;
}
@ -116,15 +186,13 @@ header {
--right-col-width: 20em;
--user-image-width: 6em;
}
#chat-container {
width: var(--right-col-width);
}
}
/* ************************************************8 */
/* single col layout */
@media screen and (max-width: 640px ) {
/* @media screen and (max-width: 640px ) {
:root {
--right-col-width: 0;
--video-container-height: 40vh;
@ -142,7 +210,6 @@ header {
#chat-container {
width: 100%;
position: static;
/* min-height: calc(100vh - var(--header-height)); */
height: calc(100vh - var(--header-height) - var(--video-container-height) - 3vh)
}
#messages-container {
@ -166,16 +233,16 @@ header {
.chat footer {
display: none;
}
}
} */
@media screen and (max-height: 860px ) {
/* @media screen and (max-height: 860px ) {
:root {
--video-container-height: 40vh;
}
.user-content {
flex-direction: column;
}
}
} */

View File

@ -1,3 +1,5 @@
/* some base styles for chat and messaging components */
#chat-container {
position: fixed;
z-index: 9;
@ -8,20 +10,14 @@
height: calc(100vh - var(--header-height));
}
.touch-screen #chat-container {
height: calc(100vh - var(--header-height) - 3vh);
#message-input-container {
width: var(--right-col-width);
}
.no-chat #chat-container-wrap {
display: none;
#messages-container {
padding-bottom: 10rem;
}
.chat #chat-container-wrap {
display: block;
}
/******************************/
/******************************/
@ -76,10 +72,6 @@
padding: 5px;
}
.message-content {
}
/* MESSAGE TEXT HTML */