0

- reduced custom styles, use mostly tailwind classes

- updated markdown css for extrausercontent
This commit is contained in:
Ginger Wong 2020-08-21 23:44:10 -07:00
parent 66dc2f84c9
commit 13cfd112b7
14 changed files with 392 additions and 395 deletions

View File

@ -66,7 +66,7 @@
} }
</style> </style>
<div class="noscript"> <div class="noscript">
<img src="https://github.com/gabek/owncast/raw/master/doc/logo.png"> <img src="https://github.com/gabek/owncast/raw/master/doc/logo.png" />
<br/> <br/>
<p> <p>
This <a href="https://github.com/gabek/owncast" target="_blank">Owncast</a> stream requires Javascript to play. This <a href="https://github.com/gabek/owncast" target="_blank">Owncast</a> stream requires Javascript to play.

View File

@ -332,7 +332,7 @@ export default class App extends Component {
const tagList = !tags.length ? const tagList = !tags.length ?
null : null :
tags.map((tag, index) => html` tags.map((tag, index) => html`
<li key="tag${index}" class="tag rounded-sm text-gray-100 bg-gray-700">${tag}</li> <li key="tag${index}" class="tag rounded-sm text-gray-100 bg-gray-700 text-xs uppercase mr-3 p-2 whitespace-no-wrap">${tag}</li>
`); `);
const socialIconsList = const socialIconsList =
@ -350,26 +350,26 @@ export default class App extends Component {
const streamInfoClass = streamOnline ? 'online' : ''; const streamInfoClass = streamOnline ? 'online' : '';
return ( return (
html` html`
<div id="app-container" class="flex ${chatClass}"> <div id="app-container" class="flex w-full flex-col justify-start relative ${chatClass}">
<div id="top-content"> <div id="top-content">
<header class="flex border-b border-gray-900 border-solid shadow-md"> <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 text-gray-400"> <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 <span
id="logo-container" id="logo-container"
class="rounded-full bg-white px-1 py-1" class="inline-block rounded-full bg-white w-8 min-w-8 min-h-8 h-8 p-1 mr-2 bg-no-repeat bg-center"
style=${bgLogo} style=${bgLogo}
> >
<img class="logo visually-hidden" src=${smallLogo} /> <img class="logo visually-hidden" src=${smallLogo} alt=""/>
</span> </span>
<span class="instance-title">${title}</span> <span class="instance-title overflow-hidden truncate">${title}</span>
</h1> </h1>
<div id="user-options-container" class="flex"> <div id="user-options-container" class="flex flex-row justify-end items-center flex-no-wrap">
<${UsernameForm} <${UsernameForm}
username=${username} username=${username}
userAvatarImage=${userAvatarImage} userAvatarImage=${userAvatarImage}
handleUsernameChange=${this.handleUsernameChange} handleUsernameChange=${this.handleUsernameChange}
/> />
<button type="button" id="chat-toggle" onClick=${this.handleChatPanelToggle} class="flex bg-gray-800 hover:bg-gray-700">💬</button> <button type="button" id="chat-toggle" onClick=${this.handleChatPanelToggle} class="flex cursor-pointer text-center justify-center items-center min-w-12 h-full bg-gray-800 hover:bg-gray-700">💬</button>
</div> </div>
</header> </header>
</div> </div>
@ -377,21 +377,20 @@ export default class App extends Component {
<main class=${mainClass}> <main class=${mainClass}>
<div <div
id="video-container" id="video-container"
class="flex owncast-video-container bg-black" class="flex owncast-video-container bg-black w-full bg-center bg-no-repeat flex flex-col items-center justify-start"
style=${bgLogoLarge} style=${bgLogoLarge}
> >
<video <video
class="video-js vjs-big-play-centered" class="video-js vjs-big-play-centered display-block w-full h-full"
id="video" id="video"
preload="auto" preload="auto"
controls controls
playsinline playsinline
> ></video>
</video>
</div> </div>
<section id="stream-info" aria-label="Stream status" class="flex font-mono bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid ${streamInfoClass}"> <section id="stream-info" aria-label="Stream status" class="flex text-center flex-row justify-between w-full text-xs 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>${streamStatusMessage}</span>
<span>${viewerCount} ${pluralize('viewer', viewerCount)}.</span> <span>${viewerCount} ${pluralize('viewer', viewerCount)}.</span>
<span>Max ${pluralize('viewer', sessionMaxViewerCount)}.</span> <span>Max ${pluralize('viewer', sessionMaxViewerCount)}.</span>
@ -399,47 +398,45 @@ export default class App extends Component {
</section> </section>
</main> </main>
<section id="user-content" aria-label="User information"> <section id="user-content" aria-label="User information" class="p-8">
<div class="user-content"> <div class="user-content flex flex-row p-8">
<div <div
class="user-image rounded-full bg-white" class="user-image rounded-full bg-white p-4 mr-8 bg-no-repeat bg-center"
style=${bgLogoLarge} style=${bgLogoLarge}
> >
<img <img
class="logo visually-hidden" class="logo visually-hidden"
alt="Logo" alt="Logo"
src=${largeLogo} src=${largeLogo}/>
>
</div> </div>
<div class="user-content-header border-b border-gray-500 border-solid"> <div class="user-content-header border-b border-gray-500 border-solid">
<h2 class="font-semibold"> <h2 class="font-semibold text-5xl">
About About <span class="streamer-name text-indigo-600">${streamerName}</span>
<span class="streamer-name text-indigo-600">${streamerName}</span>
</h2> </h2>
<ul class="social-list flex" v-if="this.platforms.length"> <ul id="social-list" class="social-list flex flex-row items-center justify-start flex-wrap">
<span class="follow-label">Follow me: </span> <span class="follow-label text-xs font-bold mr-2 uppercase">Follow me: </span>
${socialIconsList} ${socialIconsList}
</ul> </ul>
<div class="stream-summary" dangerouslySetInnerHTML=${{ __html: summary }}></div> <div id="stream-summary" class="stream-summary my-4" dangerouslySetInnerHTML=${{ __html: summary }}></div>
<ul class="tag-list flex"> <ul id="tag-list" class="tag-list flex flex-row my-4">
${tagList} ${tagList}
</ul> </ul>
</div> </div>
</div> </div>
<div <div
id="extra-user-content" id="extra-user-content"
class="extra-user-content" class="extra-user-content px-8"
dangerouslySetInnerHTML=${{ __html: extraUserContent }} dangerouslySetInnerHTML=${{ __html: extraUserContent }}
></div> ></div>
</section> </section>
<footer class="flex"> <footer class="flex flex-row justify-start p-8 opacity-50 text-xs">
<span> <span class="mx-1 inline-block">
<a href="${URL_OWNCAST}" target="_blank">About Owncast</a> <a href="${URL_OWNCAST}" target="_blank">About Owncast</a>
</span> </span>
<span>Version ${appVersion}</span> <span class="mx-1 inline-block">Version ${appVersion}</span>
</footer> </footer>
</div>
<${Chat} <${Chat}
websocket=${websocket} websocket=${websocket}

View File

@ -236,11 +236,11 @@ export default class ChatInput extends Component {
const placeholderText = generatePlaceholderText(inputEnabled, hasSentFirstChatMessage); const placeholderText = generatePlaceholderText(inputEnabled, hasSentFirstChatMessage);
return ( return (
html` html`
<div id="message-input-container" class="shadow-md bg-gray-900 border-t border-gray-700 border-solid"> <div id="message-input-container" class="w-full shadow-md bg-gray-900 border-t border-gray-700 border-solid p-4">
<${ContentEditable} <${ContentEditable}
id="message-input" id="message-input"
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-black-500 rounded py-2 px-2 my-2 focus:bg-white" class="appearance-none block w-full bg-gray-200 text-sm text-gray-700 border border-black-500 rounded py-2 px-2 my-2 focus:bg-white h-20 overflow-auto"
placeholderText=${placeholderText} placeholderText=${placeholderText}
innerRef=${this.formMessageInput} innerRef=${this.formMessageInput}
@ -254,13 +254,14 @@ export default class ChatInput extends Component {
onPaste=${this.handlePaste} onPaste=${this.handlePaste}
/> />
<div id="message-form-actions" class="flex"> <div id="message-form-actions" class="flex flex-row justify-between items-center w-full">
<span id="message-form-warning" class="text-red-600 text-xs">${inputWarning}</span> <span id="message-form-warning" class="text-red-600 text-xs">${inputWarning}</span>
<div id="message-form-actions-buttons" class="flex"> <div id="message-form-actions-buttons" class="flex flex-row justify-end items-center">
<button <button
ref=${this.emojiPickerButton} ref=${this.emojiPickerButton}
id="emoji-button" id="emoji-button"
class="mr-2 text-2xl cursor-pointer"
type="button" type="button"
style=${emojiButtonStyle} style=${emojiButtonStyle}
onclick=${this.handleEmojiButtonClick} onclick=${this.handleEmojiButtonClick}

View File

@ -95,12 +95,6 @@ export default class Chat extends Component {
receivedWebsocketMessage(message) { receivedWebsocketMessage(message) {
this.addMessage(message); this.addMessage(message);
// if (model.type === SOCKET_MESSAGE_TYPES.CHAT) {
// const message = new Message(model);
// this.addMessage(message);
// } else if (model.type === SOCKET_MESSAGE_TYPES.NAME_CHANGE) {
// this.addMessage(model);
// }
} }
// if incoming message has same id as existing message, don't add it // if incoming message has same id as existing message, don't add it
@ -181,7 +175,7 @@ export default class Chat extends Component {
if (messagesOnly) { if (messagesOnly) {
return ( return (
html` html`
<div id="messages-container"> <div id="messages-container" class="py-1 overflow-auto">
${messageList} ${messageList}
</div> </div>
`); `);
@ -189,9 +183,9 @@ export default class Chat extends Component {
return ( return (
html` html`
<section id="chat-container-wrap" class="flex"> <section id="chat-container-wrap" class="flex flex-col">
<div id="chat-container" class="bg-gray-800"> <div id="chat-container" class="bg-gray-800 flex flex-col justify-end overflow-auto">
<div id="messages-container"> <div id="messages-container" class="py-1 overflow-auto">
${messageList} ${messageList}
</div> </div>
<${ChatInput} <${ChatInput}

View File

@ -20,15 +20,17 @@ export default class Message extends Component {
const authorTextColor = { color: authorColor }; const authorTextColor = { color: authorColor };
return ( return (
html` html`
<div class="message flex"> <div class="message flex flex-row align-start p-3">
<div <div
class="message-avatar rounded-full flex items-center justify-center" class="message-avatar rounded-full flex items-center justify-center mr-3"
style=${avatarBgColor} style=${avatarBgColor}
> >
<img src=${avatar} /> <img src=${avatar} class="p-1" />
</div> </div>
<div class="message-content text-sm"> <div class="message-content text-sm break-words">
<p class="message-author text-white font-bold" style=${authorTextColor}>${author}</p> <div class="message-author text-white font-bold" style=${authorTextColor}>
${author}
</div>
<div <div
class="message-text text-gray-300 font-normal" class="message-text text-gray-300 font-normal"
dangerouslySetInnerHTML=${ dangerouslySetInnerHTML=${
@ -42,7 +44,7 @@ export default class Message extends Component {
const { oldName, newName, image } = message; const { oldName, newName, image } = message;
return ( return (
html` html`
<div class="message flex"> <div class="message flex align-start p3">
<div class="message-content text-sm"> <div class="message-content text-sm">
<img class="mr-2" src=${image} /> <img class="mr-2" src=${image} />
<div class="text-white text-center"> <div class="text-white text-center">
@ -50,7 +52,8 @@ export default class Message extends Component {
</div> </div>
</div> </div>
</div> </div>
`); `
);
} }
} }
} }

View File

@ -77,29 +77,29 @@ export default class UsernameForm extends Component {
return ( return (
html` html`
<div id="user-info"> <div id="user-info">
<div id="user-info-display" style=${styles.info} title="Click to update user name" class="flex" onClick=${this.handleDisplayForm}> <div id="user-info-display" style=${styles.info} title="Click to update user name" class="flex flex-row justify-end items-center cursor-pointer py-2 px-4 overflow-hidden w-full opacity-1 transition-opacity duration-200 hover:opacity-75" onClick=${this.handleDisplayForm}>
<img <img
src=${userAvatarImage} src=${userAvatarImage}
alt="" alt=""
id="username-avatar" id="username-avatar"
class="rounded-full bg-black bg-opacity-50 border border-solid border-gray-700" class="rounded-full bg-black bg-opacity-50 border border-solid border-gray-700 mr-2 h-8 w-8"
/> />
<span id="username-display" class="text-indigo-600">${username}</span> <span id="username-display" class="text-indigo-600 text-xs font-semibold truncate overflow-hidden whitespace-no-wrap">${username}</span>
</div> </div>
<div id="user-info-change" style=${styles.form}> <div id="user-info-change" class="flex p-1 items-center justify-end" style=${styles.form}>
<input type="text" <input type="text"
id="username-change-input" id="username-change-input"
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-black-500 rounded py-1 px-1 leading-tight focus:bg-white" class="appearance-none block w-full bg-gray-200 text-gray-700 border border-black-500 rounded py-1 px-1 leading-tight text-xs focus:bg-white"
maxlength="100" maxlength="100"
placeholder="Update username" placeholder="Update username"
value=${username} value=${username}
onKeydown=${this.handleKeydown} onKeydown=${this.handleKeydown}
ref=${this.textInput} ref=${this.textInput}
/> />
<button id="button-update-username" onClick=${this.handleUpdateUsername} class="bg-blue-500 hover:bg-blue-700 text-white py-1 px-1 rounded user-btn">Update</button> <button id="button-update-username" onClick=${this.handleUpdateUsername} type="button" class="bg-blue-500 hover:bg-blue-700 text-white text-xs uppercase p-1 mx-1 rounded cursor-pointer user-btn">Update</button>
<button id="button-cancel-change" onClick=${this.handleHideForm} class="bg-gray-900 hover:bg-gray-800 py-1 px-2 rounded user-btn text-white text-opacity-50" title="cancel">X</button> <button id="button-cancel-change" onClick=${this.handleHideForm} type="button" class="bg-gray-900 hover:bg-gray-800 py-1 px-2 mx-1 rounded cursor-pointer user-btn text-white text-xs uppercase text-opacity-50" title="cancel">X</button>
</div> </div>
</div> </div>
`); `);

View File

@ -1,43 +0,0 @@
// DEPRECATE.
import { EmojiButton } from 'https://cdn.skypack.dev/@joeattardi/emoji-button'
fetch('/emoji')
.then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok ${response.ok}`);
}
return response.json();
})
.then(json => {
setupEmojiPickerWithCustomEmoji(json);
})
.catch(error => {
this.handleNetworkingError(`Emoji Fetch: ${error}`);
});
function setupEmojiPickerWithCustomEmoji(customEmoji) {
const picker = new EmojiButton({
zIndex: 100,
theme: 'dark',
custom: customEmoji,
initialCategory: 'custom',
showPreview: false,
position: {
top: '50%',
right: '100'
}
});
const trigger = document.querySelector('#emoji-button');
trigger.addEventListener('click', () => picker.togglePicker(picker));
picker.on('emoji', emoji => {
if (emoji.url) {
const url = location.protocol + "//" + location.host + "/" + emoji.url;
const name = url.split('\\').pop().split('/').pop();
document.querySelector('#message-body-form').innerHTML += "<img class=\"emoji\" alt=\"" + name + "\" src=\"" + url + "\"/>";
} else {
document.querySelector('#message-body-form').innerHTML += emoji.emoji;
}
});
}

View File

@ -1,76 +1,6 @@
import { html } from "https://unpkg.com/htm/preact/index.mjs?module"; import { html } from "https://unpkg.com/htm/preact/index.mjs?module";
import { SOCIAL_PLATFORMS } from './utils/social.js';
const SOCIAL_PLATFORMS = { import { classNames } from './utils.js';
default: {
name: "default",
imgPos: [0,0], // [row,col]
},
facebook: {
name: "Facebook",
imgPos: [0,1],
},
twitter: {
name: "Twitter",
imgPos: [0,2],
},
instagram: {
name: "Instagram",
imgPos: [0,3],
},
snapchat: {
name: "Snapchat",
imgPos: [0,4],
},
tiktok: {
name: "TikTok",
imgPos: [0,5],
},
soundcloud: {
name: "Soundcloud",
imgPos: [0,6],
},
bandcamp: {
name: "Bandcamp",
imgPos: [0,7],
},
patreon: {
name: "Patreon",
imgPos: [0,1],
},
youtube: {
name: "YouTube",
imgPos: [0,9 ],
},
spotify: {
name: "Spotify",
imgPos: [0,10],
},
twitch: {
name: "Twitch",
imgPos: [0,11],
},
paypal: {
name: "Paypal",
imgPos: [0,12],
},
github: {
name: "Github",
imgPos: [0,13],
},
linkedin: {
name: "LinkedIn",
imgPos: [0,14],
},
discord: {
name: "Discord",
imgPos: [0,15],
},
mastodon: {
name: "Mastodon",
imgPos: [0,16],
},
};
export default function SocialIcon(props) { export default function SocialIcon(props) {
const { platform, url } = props; const { platform, url } = props;
@ -82,20 +12,28 @@ export default function SocialIcon(props) {
const name = inList ? platformInfo.name : platform; const name = inList ? platformInfo.name : platform;
const style = `--imgRow: -${imgRow}; --imgCol: -${imgCol};`; const style = `--imgRow: -${imgRow}; --imgCol: -${imgCol};`;
const itemClass = { const itemClass = classNames({
"user-social-item": true, "user-social-item": true,
"flex": true, "flex": true,
"justify-start": true,
"items-center": true,
"-mr-1": true,
"use-default": !inList, "use-default": !inList,
}; });
const labelClass = { const labelClass = classNames({
"platform-label": true, "platform-label": true,
"visually-hidden": inList, "visually-hidden": inList,
"text-indigo-800": true, "text-indigo-800": true,
}; "text-xs": true,
"uppercase": true,
"max-w-xs": true,
"inline-block": true,
});
return ( return (
html` html`
<a class=${itemClass} target="_blank" href=${url}> <a class=${itemClass} target="_blank" href=${url}>
<span class="platform-icon rounded-lg" style=${style}></span> <span class="platform-icon rounded-lg bg-no-repeat" style=${style}></span>
<span class=${labelClass}>Find me on ${name}</span> <span class=${labelClass}>Find me on ${name}</span>
</a> </a>
`); `);

View File

@ -98,7 +98,7 @@ export function hasTouchScreen() {
export function generateAvatar(hash) { export function generateAvatar(hash) {
const avatarSource = 'https://robohash.org/'; const avatarSource = 'https://robohash.org/';
const optionSize = '?size=80x80'; const optionSize = '?size=80x80';
const optionSet = '&set=set3'; const optionSet = '&set=set2';
const optionBg = ''; // or &bgset=bg1 or bg2 const optionBg = ''; // or &bgset=bg1 or bg2
return avatarSource + hash + optionSize + optionSet + optionBg; return avatarSource + hash + optionSize + optionSet + optionBg;
@ -133,3 +133,17 @@ export function setVHvar() {
export function doesObjectSupportFunction(object, functionName) { export function doesObjectSupportFunction(object, functionName) {
return typeof object[functionName] === "function"; return typeof object[functionName] === "function";
} }
// return a string of css classes
export function classNames(json) {
const classes = [];
Object.entries(json).map(function(item) {
const [ key, value ] = item;
if (value) {
classes.push(key);
}
return null;
});
return classes.join(' ');
}

View File

@ -28,7 +28,7 @@ export function formatMessageText(message, username) {
function highlightUsername(message, username) { function highlightUsername(message, username) {
const pattern = new RegExp('@?' + username.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi'); const pattern = new RegExp('@?' + username.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi');
return message.replace(pattern, '<span class="highlighted">$&</span>'); return message.replace(pattern, '<span class="highlighted font-bold bg-orange-500">$&</span>');
} }
function linkify(text, rawText) { function linkify(text, rawText) {
@ -126,8 +126,7 @@ function getInstagramEmbedFromURL(url) {
function isImage(url) { function isImage(url) {
const re = /\.(jpe?g|png|gif)$/i; const re = /\.(jpe?g|png|gif)$/i;
const isImage = re.test(url); return re.test(url);
return isImage;
} }
function getImageForURL(url) { function getImageForURL(url) {

View File

@ -0,0 +1,73 @@
// x, y pixel psitions of /img/social.gif image.
export const SOCIAL_PLATFORMS = {
default: {
name: "default",
imgPos: [0,0], // [row,col]
},
facebook: {
name: "Facebook",
imgPos: [0,1],
},
twitter: {
name: "Twitter",
imgPos: [0,2],
},
instagram: {
name: "Instagram",
imgPos: [0,3],
},
snapchat: {
name: "Snapchat",
imgPos: [0,4],
},
tiktok: {
name: "TikTok",
imgPos: [0,5],
},
soundcloud: {
name: "Soundcloud",
imgPos: [0,6],
},
bandcamp: {
name: "Bandcamp",
imgPos: [0,7],
},
patreon: {
name: "Patreon",
imgPos: [0,1],
},
youtube: {
name: "YouTube",
imgPos: [0,9 ],
},
spotify: {
name: "Spotify",
imgPos: [0,10],
},
twitch: {
name: "Twitch",
imgPos: [0,11],
},
paypal: {
name: "Paypal",
imgPos: [0,12],
},
github: {
name: "Github",
imgPos: [0,13],
},
linkedin: {
name: "LinkedIn",
imgPos: [0,14],
},
discord: {
name: "Discord",
imgPos: [0,15],
},
mastodon: {
name: "Mastodon",
imgPos: [0,16],
},
};

View File

@ -1,28 +1,58 @@
#chat-container {
position: fixed;
z-index: 9;
top: var(--header-height);
right: 0;
width: var(--right-col-width);
height: calc(100vh - var(--header-height));
/* overflow: hidden; */
/* display: flex;
flex-direction: column;
justify-content: flex-end; */
}
.touch-screen #chat-container {
height: calc(100vh - var(--header-height) - 3vh);
}
.no-chat #chat-container-wrap {
display: none;
}
.chat #chat-container-wrap {
display: block;
}
#messages-container { #messages-container {
overflow: auto; /* overflow: auto;
padding: 1em 0; padding: 1em 0; */
} }
#message-input-container { #message-input-container {
width: 100%; /* width: 100%; */
padding: 1em; /* padding: 1em; */
} }
/******************************/ /******************************/
/******************************/ /******************************/
#message-input { #message-input {
height: 5rem; /* height: 5rem; */
font-size: .85em; /* font-size: .85em; */
} }
#message-input img { #message-input img {
display: inline; display: inline;
vertical-align: middle; vertical-align: middle;
padding: 5px; padding: .25rem;
} }
#message-input .emoji { #message-input .emoji {
width: 2.2em; width: 2.2rem;
padding: .25rem;
} }
@ -61,23 +91,23 @@
#message-form-actions { #message-form-actions {
flex-direction: row; /* flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 100%; width: 100%; */
} }
#message-form-actions-buttons { #message-form-actions-buttons {
flex-direction: row; /* flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center; */
} }
/* Emoji picker button */ /* Emoji picker button */
#emoji-button { #emoji-button {
font-size: 1.75em; /* font-size: 1.75em; */
cursor: pointer; /* cursor: pointer;
margin-right: .5em; margin-right: .5em; */
} }
.emoji-picker__emoji { .emoji-picker__emoji {
border-radius: 10px; border-radius: 10px;
@ -85,11 +115,13 @@
.message { .message {
padding: .85em; /* padding: .85em; */
align-items: flex-start; /* align-items: flex-start; */
} }
.message-avatar { .message-avatar {
margin-right: .75em; height: 3.0em;
width: 3.0em;
/* margin-right: .75em; */
} }
.message-avatar img { .message-avatar img {
max-width: unset; max-width: unset;
@ -99,17 +131,17 @@
} }
.message-content { .message-content {
font-size: .85em; /* font-size: .85em; */
max-width: 85%; max-width: 85%;
word-wrap: break-word; /* word-wrap: break-word; */
} }
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT HTML */
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT HTML */
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT HTML */
.message-text a { .message-text a {
color: #7F9CF5; /* indigo-400 */ color: #7F9CF5; /* indigo-400 */
} }
@ -119,41 +151,43 @@
.message-text img { .message-text img {
display: inline; display: inline;
padding-left: 5px; padding-left: 0 .25rem;
padding-right: 5px; }
.message-text .emoji {
width: 3rem;
padding: .25rem
} }
.message-text code { .message-text code {
font-family: monospace;
background-color:darkslategrey; background-color:darkslategrey;
padding: 3px; padding: .25rem;
} }
.message-text .emoji {
width: 60px;
}
.message-text iframe { .message-text iframe {
width: 100%; width: 100%;
height: 170px; height: 12rem;
border-radius: 15px; border-radius: 1rem;
} }
.message-text .instagram-embed { .message-text .instagram-embed {
height: 314px; height: 22em;
} }
.message-text .embedded-image { .message-text .embedded-image {
width: 100%; width: 100%;
height: 170px; display: block;
border-radius: 15px; height: 15rem;
border-radius: 1rem;
} }
.message-text .highlighted { .message-text .highlighted {
color: orange; /* color: orange;
font-weight: 400; font-weight: 400;
font-size: 14px; } */
}
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT CONTENT */
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT CONTENT */
/* MESSAGE TEXT CONTENT */ /* MESSAGE TEXT CONTENT */

View File

@ -39,90 +39,90 @@ a:hover {
} }
#app-container { #app-container {
width: 100%; /* width: 100%;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
position: relative; position: relative; */
} }
header { header {
position: fixed; /* position: fixed;
width: 100%; width: 100%; */
height: var(--header-height); height: var(--header-height);
top: 0; /* top: 0;
left: 0; left: 0; */
background-color: var(--header-bg-color); background-color: var(--header-bg-color);
z-index: 10; /* z-index: 10; */
flex-direction: row; /* flex-direction: row;
justify-content: space-between; justify-content: space-between; */
flex-wrap: nowrap; /* flex-wrap: nowrap; */
} }
header h1 { header h1 {
font-size: 1.25em; /* font-size: 1.25em; */
font-weight: 100; /* font-weight: 100;
letter-spacing: 1.2; letter-spacing: 1.2; */
text-transform: uppercase; /* text-transform: uppercase; */
padding: .5em; /* padding: .5em; */
white-space: nowrap; /* white-space: nowrap; */
justify-content: flex-start; /* justify-content: flex-start;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row; */
overflow: hidden; /* overflow: hidden; */
} }
#logo-container{ #logo-container{
height: 1.75em; /* height: 1.75em;
width: 1.75em; width: 1.75em; */
min-height: 1.75em; /* min-height: 1.75em;
min-width: 1.75em; min-width: 1.75em; */
margin-right: .5em; /* margin-right: .5em; */
display: inline-block; /* display: inline-block; */
background-repeat: no-repeat; /* background-repeat: no-repeat; */
background-position: center center; /* background-position: center center; */
background-size: 1.35em; background-size: 1.35em;
} }
header .instance-title { header .instance-title {
overflow: hidden; /* overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis; */
} }
#chat-toggle { #chat-toggle {
cursor: pointer; /* cursor: pointer;
text-align: center; text-align: center; */
height: 100%; /* height: 100%;*/
min-width: 3em; min-width: 3rem;
justify-content: center; /* justify-content: center;
align-items: center; align-items: center; */
} }
footer { footer {
flex-direction: row; /* flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
font-size: .75em; font-size: .75em;
padding: 2em; padding: 2em;
opacity: .5; opacity: .5; */
} }
footer span { footer span {
display: inline-block; /* display: inline-block;
margin: 0 1em; margin: 0 1em; */
} }
/* ************************************************8 */ /* ************************************************8 */
#stream-info { #stream-info {
padding: .5em 2em; /* padding: .5em 2em; */
text-align: center; /* text-align: center;
width: 100%; width: 100%;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between; */
} }
#stream-info span { #stream-info span {
font-size: .7em; /* font-size: .7em; */
} }
.user-content { .user-content {
padding: 2em; /* padding: 2em; */
} }
/* #user-content { /* #user-content {
display: block; display: block;
@ -141,73 +141,73 @@ footer span {
height: 100%; height: 100%;
} */ } */
.stream-summary { .stream-summary {
margin: 1em 0; /* margin: 1em 0; */
} }
h2 { h2 {
font-size: 3em; /* font-size: 3em; */
} }
/* ************************************************8 */ /* ************************************************8 */
#user-options-container { #user-options-container {
flex-direction: row; /* flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
flex-wrap: nowrap; flex-wrap: nowrap; */
} }
#user-info-display { #user-info-display {
display: flex; /* display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
padding: .5em 1em; padding: .5em 1em;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%; */
} }
#username-avatar { #username-avatar {
height: 2.1em; /* height: 2.1em;
width: 2.1em; width: 2.1em;
margin-right: .5em; margin-right: .5em; */
} }
#username-display { #username-display {
font-weight: 600; /* font-weight: 600; */
font-size: .75em; /* font-size: .75em; */
white-space: nowrap; /* white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden; */
} }
#user-info-display:hover { #user-info-display:hover {
transition: opacity .2s; /* transition: opacity .2s;
opacity: .75; opacity: .75; */
} }
#user-info-change { #user-info-change {
display: none; display: none;
justify-content: flex-end; /* justify-content: flex-end;
align-items: center; align-items: center;
padding: .25em; padding: .25em; */
} }
#username-change-input { #username-change-input {
font-size: .75em; /* font-size: .75em; */
} }
#button-update-username { #button-update-username {
font-size: .65em; /* font-size: .65em; */
text-transform: uppercase; /* text-transform: uppercase; */
height: 2.5em; /* height: 2.5em; */
} }
#button-cancel-change { #button-cancel-change {
cursor: pointer; /* cursor: pointer; */
height: 2.5em; /* height: 2.5em; */
font-size: .65em; /* font-size: .65em; */
} }
.user-btn { .user-btn {
margin: 0 .25em; /* margin: 0 .25em; */
} }
/* ************************************************8 */ /* ************************************************8 */
@ -260,16 +260,10 @@ h2 {
/* ************************************************8 */ /* ************************************************8 */
.no-chat #chat-container-wrap {
display: none;
}
.no-chat footer { .no-chat footer {
justify-content: center; justify-content: center;
} }
.chat #chat-container-wrap {
display: block;
}
.chat #video-container, .chat #video-container,
.chat #stream-info, .chat #stream-info,
@ -278,23 +272,6 @@ h2 {
} }
#chat-container {
position: fixed;
z-index: 9;
top: var(--header-height);
right: 0;
width: var(--right-col-width);
height: calc(100vh - var(--header-height));
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.touch-screen #chat-container {
height: calc(100vh - var(--header-height) - 3vh);
}

View File

@ -1,71 +1,71 @@
.user-content { .user-content {
padding: 3em; /* padding: 3rem; */
display: flex; /* display: flex;
flex-direction: row; flex-direction: row; */
} }
.user-content .user-image { .user-content .user-image {
padding: 1em; /* padding: 1rem;
margin-right: 2em; margin-right: 2rem; */
min-width: var(--user-image-width); min-width: var(--user-image-width);
width: var(--user-image-width); width: var(--user-image-width);
height: var(--user-image-width); height: var(--user-image-width);
max-height: var(--user-image-width); max-height: var(--user-image-width);
background-repeat: no-repeat; /* background-repeat: no-repeat;
background-position: center center; background-position: center center; */
background-size: calc(var(--user-image-width) - 1em); background-size: calc(var(--user-image-width) - 1em);
} }
.user-content-header { .user-content-header {
margin-bottom: 2em; /* margin-bottom: 2rem; */
} }
.tag-list { .tag-list {
flex-direction: row; /* flex-direction: row; */
margin: 1em 0; /* margin: 1em 0; */
} }
.tag-list li { .tag-list li {
font-size: .75em; /* font-size: .75rem; */
text-transform: uppercase; /* text-transform: uppercase; */
margin-right: .75em; /* margin-right: .75rem; */
padding: .5em; /* padding: .5rem; */
} }
.social-list { .social-list {
flex-direction: row; /* flex-direction: row; */
align-items: center; /* align-items: center; */
justify-content: flex-start; /* justify-content: flex-start; */
flex-wrap: wrap; /* flex-wrap: wrap; */
} }
.social-list .follow-label { .social-list .follow-label {
font-weight: bold; /* font-weight: bold; */
font-size: .75em; /* font-size: .75rem; */
margin-right: .5em; /* margin-right: .5rem; */
text-transform: uppercase; /* text-transform: uppercase; */
} }
.user-social-item { .user-social-item {
display: flex; /* display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
margin-right: -.25em; margin-right: -.25rem; */
} }
.user-social-item .platform-icon { .user-social-item .platform-icon {
--icon-width: 40px; --icon-width: 40px;
height: var(--icon-width); height: var(--icon-width);
width: var(--icon-width); width: var(--icon-width);
background-image: url(/img/social-icons.gif); background-image: url(/img/social-icons.gif);
background-repeat: no-repeat; /* background-repeat: no-repeat; */
background-position: calc(var(--imgCol) * var(--icon-width)) calc(var(--imgRow) * var(--icon-width)); background-position: calc(var(--imgCol) * var(--icon-width)) calc(var(--imgRow) * var(--icon-width));
transform: scale(.65); transform: scale(.65);
} }
.user-social-item.use-default .platform-label { .user-social-item.use-default .platform-label {
font-size: .7em; /* font-size: .7rem; */
text-transform: uppercase; /* text-transform: uppercase; */
display: inline-block; /* display: inline-block; */
max-width: 10em; /* max-width: 10rem; */
} }
@ -75,124 +75,134 @@ Assumes markup converted from markdown input.
*/ */
#extra-user-content { #extra-user-content {
padding: 1em 3em 3em 3em; /* padding: 1rem 3rem 3rem 3rem; */
}
#extra-user-content ul,
#extra-user-content ol {
margin: 0;
padding: 0;
} }
#extra-user-content ol { #extra-user-content ol {
list-style: decimal; list-style: decimal;
margin-left: 1.5rem;
} }
#extra-user-content ul { #extra-user-content ul {
list-style: unset; list-style: unset;
margin-left: 1.5rem;
} }
#extra-user-content h1, /* #extra-user-content h1,
#extra-user-content h2, #extra-user-content h2,
#extra-user-content h3, #extra-user-content h3,
#extra-user-content h4 { #extra-user-content h4 {
color: #111111; color: #111111;
font-weight: 400; font-weight: 400;
} } */
#extra-user-content h1, #extra-user-content h1,
#extra-user-content h2, #extra-user-content h2,
#extra-user-content h3, #extra-user-content h3,
#extra-user-content h4, #extra-user-content h4,
#extra-user-content h5, #extra-user-content h5,
#extra-user-content p { #extra-user-content h6 {
margin-bottom: 24px; margin: 0;
padding: 0; padding: 0;
margin: 1.5rem 0 .5rem;
font-weight: 600;
line-height: 1.2;
} }
#extra-user-content h1 { #extra-user-content h1 {
font-size: 48px; font-size: 2.1rem;
} }
#extra-user-content h2 { #extra-user-content h2 {
font-size: 36px; font-size: 1.8rem;
margin: 24px 0 6px;
} }
#extra-user-content h3 { #extra-user-content h3 {
font-size: 24px; font-size: 1.5rem;
} }
#extra-user-content h4 { #extra-user-content h4 {
font-size: 21px; font-size: 1.2rem;
} }
#extra-user-content h5 { #extra-user-content h5 {
font-size: 18px; font-size: 1.25rem;
}
#extra-user-content h6 {
font-weight: 400;
font-size: 1rem;
}
#extra-user-content p {
margin-top: 0;
margin-bottom: 1rem;
} }
#extra-user-content a { #extra-user-content a {
color: #0099ff; color: #0099ff;
margin: 0;
padding: 0;
vertical-align: baseline;
}
#extra-user-content ul, #extra-user-content ol {
padding: 0;
margin: 0;
} }
#extra-user-content li { #extra-user-content li {
line-height: 24px; line-height: 1.5rem;
} }
#extra-user-content li ul, #extra-user-content li ul { #extra-user-content li ul,
margin-left: 24px; } #extra-user-content li ul {
margin-left: 1.5rem;
#extra-user-content p, #extra-user-content ul, #extra-user-content ol {
font-size: 16px;
line-height: 24px;
} }
#extra-user-content pre {
padding: 0px 24px;
max-width: 800px; #extra-user-content blockquote {
white-space: pre-wrap; border-left: .25rem solid #bbc;
padding: 0 1rem;
}
#extra-user-content blockquote p {
margin: 1rem 0;
} }
#extra-user-content pre,
#extra-user-content code { #extra-user-content code {
font-family: Consolas, Monaco, Andale Mono, monospace; font-family: monospace;
line-height: 1.5; font-size: .85rem;
font-size: 13px; background-color: #eee;
color: #900;
}
#extra-user-content pre {
margin: 1rem 0;
padding: 1rem;
max-width: 80%;
white-space: pre-wrap;
} }
#extra-user-content aside { #extra-user-content aside {
display: block; display: block;
float: right; float: right;
width: 390px; width: 35%;
}
#extra-user-content blockquote {
margin: 1em 2em;
max-width: 476px;
}
#extra-user-content blockquote p {
color: #666;
max-width: 460px;
} }
#extra-user-content hr { #extra-user-content hr {
width: 540px; width: 100%;
text-align: left; border-top: 1px solid #666;
margin: 0 auto 0 0; margin-bottom: 1rem;
color: #999;
} }
#extra-user-content table { #extra-user-content table {
border-collapse: collapse; border-collapse: collapse;
margin: 1em 1em; margin: 1em 1rem;
border: 1px solid #CCC; border: 1px solid #CCC;
} }
#extra-user-content table thead { #extra-user-content table thead {
background-color: #EEE; background-color: #eee;
} }
#extra-user-content table thead td { #extra-user-content table thead td {
@ -200,6 +210,6 @@ Assumes markup converted from markdown input.
} }
#extra-user-content table td { #extra-user-content table td {
padding: 0.5em 1em; padding: 0.5rem 1rem;
border: 1px solid #CCC; border: 1px solid #CCC;
} }