add options pane, add ping volume and hide player controls settings

options-pane
Kay 2023-01-28 15:04:05 +01:00
parent e43184ab49
commit bcd36e2269
6 changed files with 644 additions and 489 deletions

View File

@ -53,17 +53,52 @@
<div id="video-container"></div>
<div id="chatbox-container">
<div id="viewer-list"></div>
<div id="chatbox"></div>
<form id="chatbox-send">
<input
type="text"
placeholder="Message... (/help for commands)"
list="emoji-autocomplete"
/>
<div id="emoji-autocomplete"></div>
<!-- DO NOT ADD SPACING INSIDE THE TAG IT WILL BREAK THE CSS kthxbye -->
</form>
<section id="viewing">
<div id="viewer-list"></div>
<div id="chatbox"></div>
<form id="chatbox-send">
<input
type="text"
placeholder="Message... (/help for commands)"
list="emoji-autocomplete"
/>
<div id="emoji-autocomplete"></div>
<!-- DO NOT ADD SPACING INSIDE THE TAG IT WILL BREAK THE CSS kthxbye -->
</form>
</section>
<section id="options">
<h2>settings</h2>
<hr />
<form id="options-form">
<label for="plingVolume"
><input
type="range"
min="0"
max="100"
value="100"
id="plingVolume"
onchange="handlePlingVolume(this)"
/>
ping volume</label
>
<label
><input
id="playerControlsShown"
type="checkbox"
onchange="togglePlayerControlsShown(this)"
/>hide controls when loading video player</label
>
</form>
</section>
<div id="options-toggle">
<button
aria-label="settings"
id="options-icon"
onclick="toggleOptionPane(event, this)"
>
⚙️
</button>
</div>
</div>
<script type="module" src="/main.mjs?v=bfdcf2"></script>

View File

@ -0,0 +1,43 @@
export const toggleOptionPane = (event, element) => {
event.preventDefault();
// show options
if (
!document.querySelector("#options").style.display ||
document.querySelector("#options").style.display === "none"
) {
// using this to do any potential init logic for the fields too
loadPlayerControlsShown(document.querySelector("#playerControlsShown"))
loadPlingVolume(document.querySelector("#plingVolume"))
element.innerText = "❌";
document.querySelector("#options").style.display = "block";
return (document.querySelector("#viewing").style.display = "none");
}
// hide options
element.innerText = "⚙️";
document.querySelector("#options").style.display = "none";
document.querySelector("#viewing").style.display = "block";
};
const getPlayerControlsShown = () => localStorage.getItem("watch-party-default-allow-controls") || false
// delete from storage on false to prevent weird js boolean parsing (Boolean('false') === True)
const setPlayerControlShown = (boolean) => !boolean
? localStorage.removeItem("watch-party-default-allow-controls")
: localStorage.setItem("watch-party-default-allow-controls", boolean)
export const togglePlayerControlsShown = (element) => {
const isShown = element.checked
setPlayerControlShown(!isShown)
}
const loadPlayerControlsShown = (element) => {
const isShown = getPlayerControlsShown()
element.checked = !isShown
}
const getPlingVolume = () => localStorage.getItem("watch-party-pling-volume") || 100
const setPlingVolume = (value) => localStorage.setItem("watch-party-pling-volume", value)
export const handlePlingVolume = (element) => {
setPlingVolume(element.value)
}
const loadPlingVolume = (element) => {
element.value = getPlingVolume()
}

View File

@ -1,80 +1,82 @@
export const pling = () => {
const maxGain = 0.3;
const duration = 0.22;
const fadeDuration = 0.1;
const secondBeepOffset = 0.05;
const thirdBeepOffset = 2 * secondBeepOffset;
const ctx = new AudioContext();
const firstBeepGain = ctx.createGain();
firstBeepGain.connect(ctx.destination);
firstBeepGain.gain.setValueAtTime(0.01, ctx.currentTime);
firstBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + fadeDuration
);
firstBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + (duration - fadeDuration)
);
firstBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + duration
);
const firstBeep = ctx.createOscillator();
firstBeep.connect(firstBeepGain);
firstBeep.frequency.value = 400;
firstBeep.type = "sine";
const secondBeepGain = ctx.createGain();
secondBeepGain.connect(ctx.destination);
secondBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + secondBeepOffset);
secondBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + secondBeepOffset + fadeDuration
);
secondBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + secondBeepOffset + (duration - fadeDuration)
);
secondBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + secondBeepOffset + duration
);
const secondBeep = ctx.createOscillator();
secondBeep.connect(secondBeepGain);
secondBeep.frequency.value = 600;
secondBeep.type = "sine";
const thirdBeepGain = ctx.createGain();
thirdBeepGain.connect(ctx.destination);
thirdBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + thirdBeepOffset);
thirdBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + thirdBeepOffset + fadeDuration
);
thirdBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + thirdBeepOffset + (duration - fadeDuration)
);
thirdBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + thirdBeepOffset + duration
);
const thirdBeep = ctx.createOscillator();
thirdBeep.connect(thirdBeepGain);
thirdBeep.frequency.value = 900;
thirdBeep.type = "sine";
firstBeep.start(ctx.currentTime);
firstBeep.stop(ctx.currentTime + duration);
secondBeep.start(ctx.currentTime + secondBeepOffset);
secondBeep.stop(ctx.currentTime + (secondBeepOffset + duration));
thirdBeep.start(ctx.currentTime + thirdBeepOffset);
thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration));
};
export const pling = () => {
// technically volume 0 breaks it but its the wanted outcome i guess?
const maxGain =
(Number(localStorage.getItem("watch-party-pling-volume")) / 100 ?? 1) * 0.3;
const duration = 0.22;
const fadeDuration = 0.1;
const secondBeepOffset = 0.05;
const thirdBeepOffset = 2 * secondBeepOffset;
const ctx = new AudioContext();
const firstBeepGain = ctx.createGain();
firstBeepGain.connect(ctx.destination);
firstBeepGain.gain.setValueAtTime(0.01, ctx.currentTime);
firstBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + fadeDuration
);
firstBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + (duration - fadeDuration)
);
firstBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + duration
);
const firstBeep = ctx.createOscillator();
firstBeep.connect(firstBeepGain);
firstBeep.frequency.value = 400;
firstBeep.type = "sine";
const secondBeepGain = ctx.createGain();
secondBeepGain.connect(ctx.destination);
secondBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + secondBeepOffset);
secondBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + secondBeepOffset + fadeDuration
);
secondBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + secondBeepOffset + (duration - fadeDuration)
);
secondBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + secondBeepOffset + duration
);
const secondBeep = ctx.createOscillator();
secondBeep.connect(secondBeepGain);
secondBeep.frequency.value = 600;
secondBeep.type = "sine";
const thirdBeepGain = ctx.createGain();
thirdBeepGain.connect(ctx.destination);
thirdBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + thirdBeepOffset);
thirdBeepGain.gain.exponentialRampToValueAtTime(
maxGain,
ctx.currentTime + thirdBeepOffset + fadeDuration
);
thirdBeepGain.gain.setValueAtTime(
maxGain,
ctx.currentTime + thirdBeepOffset + (duration - fadeDuration)
);
thirdBeepGain.gain.exponentialRampToValueAtTime(
0.01,
ctx.currentTime + thirdBeepOffset + duration
);
const thirdBeep = ctx.createOscillator();
thirdBeep.connect(thirdBeepGain);
thirdBeep.frequency.value = 900;
thirdBeep.type = "sine";
firstBeep.start(ctx.currentTime);
firstBeep.stop(ctx.currentTime + duration);
secondBeep.start(ctx.currentTime + secondBeepOffset);
secondBeep.stop(ctx.currentTime + (secondBeepOffset + duration));
thirdBeep.start(ctx.currentTime + thirdBeepOffset);
thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration));
};

View File

@ -228,7 +228,6 @@ export const joinSession = async () => {
is_playing
);
// TODO: Allow the user to set this somewhere
let defaultAllowControls = false;
try {
defaultAllowControls = localStorage.getItem(

View File

@ -1,7 +1,15 @@
import { setupJoinSessionForm } from "./lib/join-session.mjs?v=bfdcf2";
import {
toggleOptionPane,
togglePlayerControlsShown,
handlePlingVolume
} from "./lib/options-pane.mjs?v=bfdcf2";
const main = () => {
setupJoinSessionForm();
window.toggleOptionPane = toggleOptionPane;
window.togglePlayerControlsShown = togglePlayerControlsShown;
window.handlePlingVolume = handlePlingVolume
};
if (document.readyState === "complete") {

View File

@ -1,397 +1,465 @@
*,
*:before,
*:after {
box-sizing: border-box;
}
:root {
--bg-rgb: 28, 23, 36;
--fg-rgb: 234, 234, 248;
--accent-rgb: 181, 127, 220;
--fg: rgb(var(--fg-rgb));
--bg: rgb(var(--bg-rgb));
--default-user-color: rgb(126, 208, 255);
--accent: rgb(var(--accent-rgb));
--fg-transparent: rgba(var(--fg-rgb), 0.25);
--bg-transparent: rgba(var(--bg-rgb), 0.25);
--autocomplete-bg: linear-gradient(
var(--fg-transparent),
var(--fg-transparent)
),
linear-gradient(var(--bg), var(--bg));
--chip-bg: linear-gradient(
var(--accent-transparent),
var(--accent-transparent)
),
linear-gradient(var(--bg), var(--bg));
--accent-transparent: rgba(var(--accent-rgb), 0.25);
}
html {
background-color: var(--bg);
color: var(--fg);
font-size: 1.125rem;
font-family: sans-serif;
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
overscroll-behavior: none;
width: 100%;
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
video {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
#video-container {
flex-grow: 0;
flex-shrink: 1;
display: none;
}
a {
color: var(--accent);
}
.chip {
color: var(--fg);
background: var(--chip-bg);
text-decoration: none;
padding: 0 0.5rem 0 1.45rem;
display: inline-flex;
position: relative;
font-size: 0.9rem;
height: 1.125rem;
align-items: center;
border-radius: 2rem;
overflow: hidden;
}
.chip::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 1.125rem;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: var(--accent-transparent);
background-repeat: no-repeat;
background-size: 18px;
background-position: center;
}
.join-chip::before {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTggNXYxNGwxMS03eiIvPjwvc3ZnPg==");
}
.time-chip::before {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTExLjk5IDJDNi40NyAyIDIgNi40OCAyIDEyczQuNDcgMTAgOS45OSAxMEMxNy41MiAyMiAyMiAxNy41MiAyMiAxMlMxNy41MiAyIDExLjk5IDJ6TTEyIDIwYy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz48cGF0aCBkPSJNMTIuNSA3SDExdjZsNS4yNSAzLjE1Ljc1LTEuMjMtNC41LTIuNjd6Ii8+PC9zdmc+");
}
label {
display: block;
}
input[type="url"],
input[type="text"] {
background: #fff;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 6px;
color: rgba(0, 0, 0, 0.8);
display: block;
margin: 0.5em 0;
padding: 0.5em 1em;
line-height: 1.5;
font-family: sans-serif;
font-size: 1em;
width: 100%;
resize: none;
overflow-x: wrap;
overflow-y: scroll;
}
button {
background-color: var(--accent);
border: var(--accent);
border-radius: 6px;
color: #fff;
padding: 0.5em 1em;
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
font-family: sans-serif;
font-size: 1em;
width: 100%;
user-select: none;
border: 1px solid rgba(0, 0, 0, 0);
line-height: 1.5;
cursor: pointer;
margin: 0.5em 0;
}
button:disabled {
filter: saturate(0.75);
opacity: 0.75;
cursor: default;
}
button.small-button {
font-size: 0.75em;
padding-top: 0;
padding-bottom: 0;
}
.subtitle-track-group {
display: flex;
}
.subtitle-track-group > * {
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-right: 1ch !important;
}
#pre-join-controls,
#create-controls {
margin: 0;
flex-grow: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#join-session-form,
#create-session-form {
width: 500px;
max-width: 100%;
padding: 1rem;
}
#join-session-form > *:first-child,
#create-session-form > *:first-child {
margin-top: 0;
}
#post-create-message {
display: none;
width: 100%;
font-size: 0.85em;
}
#chatbox-container {
display: none;
}
.chat-message {
overflow-wrap: break-word;
margin-bottom: 0.125rem;
}
.chat-message > strong,
#viewer-list strong {
color: var(--user-color, var(--default-user-color));
}
.chat-message.user-join,
.chat-message.user-leave,
.chat-message.ping {
font-style: italic;
}
.chat-message.set-time,
.chat-message.set-playing,
.chat-message.join-session {
font-style: italic;
text-align: right;
font-size: 0.85em;
}
.chat-message.command-message {
font-size: 0.85em;
}
.chat-message.set-time > strong,
.chat-message.set-playing > strong,
.chat-message.join-session > strong {
color: unset !important;
}
.emoji {
width: 2ch;
height: 2ch;
object-fit: contain;
margin-bottom: -0.35ch;
}
#chatbox {
padding: 0.5em 1em;
overflow-y: scroll;
flex-shrink: 1;
flex-grow: 1;
}
#viewer-list {
padding: 0.5em 1em;
/* TODO: turn this into max-height instead of fixed height without breaking the chatbox height */
overflow-y: scroll;
border-bottom: var(--fg-transparent);
border-bottom-style: solid;
max-height: 4rem;
flex-shrink: 0;
}
#chatbox-container {
background-color: var(--bg);
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 36ch;
min-width: 36ch;
overflow: hidden;
}
#chatbox-send {
padding: 0 1em;
padding-bottom: 0.5em;
position: relative;
}
#chatbox-send > input {
font-size: 0.75em;
width: 100%;
}
#emoji-autocomplete {
position: absolute;
bottom: 3.25rem;
background-image: var(--autocomplete-bg);
border-radius: 6px;
width: calc(100% - 2rem);
max-height: 8.5rem;
overflow-y: auto;
clip-path: inset(0 0 0 0 round 8px);
}
#emoji-autocomplete:empty {
display: none;
}
.emoji-option {
background: transparent;
font-size: 0.75rem;
text-align: left;
margin: 0 0.25rem;
border-radius: 4px;
width: calc(100% - 0.5rem);
display: flex;
align-items: center;
padding: 0.25rem 0.5rem;
scroll-margin: 0.25rem;
}
.emoji-option:first-child {
margin-top: 0.25rem;
}
.emoji-option:last-child {
margin-bottom: 0.25rem;
}
.emoji-option .emoji {
width: 1.25rem;
height: 1.25rem;
margin: 0 0.5rem 0 0;
font-size: 2.25ch;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
flex-shrink: 0;
}
.emoji-name {
overflow: hidden;
text-overflow: ellipsis;
}
.emoji-option.selected {
background: var(--fg-transparent);
}
#join-session-colour {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: none;
padding: 0;
border-radius: 6px;
overflow: hidden;
margin: 0.5em 0;
height: 2rem;
width: 2.5rem;
cursor: pointer;
}
input[type="color"]::-moz-color-swatch {
border: none;
margin: 0;
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: none;
margin: 0;
padding: 0;
}
input[type="color"]::-webkit-color-swatch-wrapper {
border: none;
margin: 0;
padding: 0;
}
@media (min-aspect-ratio: 4/3) {
body {
flex-direction: row;
}
#chatbox-container {
height: 100vh !important;
flex-grow: 0;
}
#video-container {
flex-grow: 1;
}
#chatbox {
height: calc(100vh - 5em - 4em) !important;
}
}
*,
*:before,
*:after {
box-sizing: border-box;
}
:root {
--bg-rgb: 28, 23, 36;
--fg-rgb: 234, 234, 248;
--accent-rgb: 181, 127, 220;
--accent-darker: rgb(95, 37, 136); /*50% darker*/
--accent-darkest: rgb(47, 19, 68); /*75% darker*/
--fg: rgb(var(--fg-rgb));
--bg: rgb(var(--bg-rgb));
--default-user-color: rgb(126, 208, 255);
--accent: rgb(var(--accent-rgb));
--fg-transparent: rgba(var(--fg-rgb), 0.25);
--bg-transparent: rgba(var(--bg-rgb), 0.25);
--autocomplete-bg: linear-gradient(
var(--fg-transparent),
var(--fg-transparent)
),
linear-gradient(var(--bg), var(--bg));
--chip-bg: linear-gradient(
var(--accent-transparent),
var(--accent-transparent)
),
linear-gradient(var(--bg), var(--bg));
--accent-transparent: rgba(var(--accent-rgb), 0.25);
}
html {
background-color: var(--bg);
color: var(--fg);
font-size: 1.125rem;
font-family: sans-serif;
}
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
overscroll-behavior: none;
width: 100%;
height: 100%;
}
body {
display: flex;
flex-direction: column;
}
video {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
#video-container {
flex-grow: 0;
flex-shrink: 1;
display: none;
}
a {
color: var(--accent);
}
.chip {
color: var(--fg);
background: var(--chip-bg);
text-decoration: none;
padding: 0 0.5rem 0 1.45rem;
display: inline-flex;
position: relative;
font-size: 0.9rem;
height: 1.125rem;
align-items: center;
border-radius: 2rem;
overflow: hidden;
}
.chip::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 1.125rem;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: var(--accent-transparent);
background-repeat: no-repeat;
background-size: 18px;
background-position: center;
}
.join-chip::before {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTggNXYxNGwxMS03eiIvPjwvc3ZnPg==");
}
.time-chip::before {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTExLjk5IDJDNi40NyAyIDIgNi40OCAyIDEyczQuNDcgMTAgOS45OSAxMEMxNy41MiAyMiAyMiAxNy41MiAyMiAxMlMxNy41MiAyIDExLjk5IDJ6TTEyIDIwYy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz48cGF0aCBkPSJNMTIuNSA3SDExdjZsNS4yNSAzLjE1Ljc1LTEuMjMtNC41LTIuNjd6Ii8+PC9zdmc+");
}
label {
display: block;
}
input[type="url"],
input[type="text"] {
background: #fff;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 6px;
color: rgba(0, 0, 0, 0.8);
display: block;
margin: 0.5em 0;
padding: 0.5em 1em;
line-height: 1.5;
font-family: sans-serif;
font-size: 1em;
width: 100%;
resize: none;
overflow-x: wrap;
overflow-y: scroll;
}
button {
background-color: var(--accent);
border: var(--accent);
border-radius: 6px;
color: #fff;
padding: 0.5em 1em;
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
font-family: sans-serif;
font-size: 1em;
width: 100%;
user-select: none;
border: 1px solid rgba(0, 0, 0, 0);
line-height: 1.5;
cursor: pointer;
margin: 0.5em 0;
}
button:disabled {
filter: saturate(0.75);
opacity: 0.75;
cursor: default;
}
button.small-button {
font-size: 0.75em;
padding-top: 0;
padding-bottom: 0;
}
.subtitle-track-group {
display: flex;
}
.subtitle-track-group > * {
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-right: 1ch !important;
}
#pre-join-controls,
#create-controls {
margin: 0;
flex-grow: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#join-session-form,
#create-session-form {
width: 500px;
max-width: 100%;
padding: 1rem;
}
#join-session-form > *:first-child,
#create-session-form > *:first-child {
margin-top: 0;
}
#post-create-message {
display: none;
width: 100%;
font-size: 0.85em;
}
#chatbox-container {
display: none;
}
.chat-message {
overflow-wrap: break-word;
margin-bottom: 0.125rem;
}
.chat-message > strong,
#viewer-list strong {
color: var(--user-color, var(--default-user-color));
}
.chat-message.user-join,
.chat-message.user-leave,
.chat-message.ping {
font-style: italic;
}
.chat-message.set-time,
.chat-message.set-playing,
.chat-message.join-session {
font-style: italic;
text-align: right;
font-size: 0.85em;
}
.chat-message.command-message {
font-size: 0.85em;
}
.chat-message.set-time > strong,
.chat-message.set-playing > strong,
.chat-message.join-session > strong {
color: unset !important;
}
.emoji {
width: 2ch;
height: 2ch;
object-fit: contain;
margin-bottom: -0.35ch;
}
#chatbox {
padding: 0.5em 1em;
overflow-y: scroll;
flex-shrink: 1;
flex-grow: 1;
}
#viewer-list {
padding: 0.5em 1em;
/* TODO: turn this into max-height instead of fixed height without breaking the chatbox height */
overflow-y: scroll;
border-bottom: var(--fg-transparent);
border-bottom-style: solid;
max-height: 4rem;
flex-shrink: 0;
}
#chatbox-container {
background-color: var(--bg);
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
flex-basis: 36ch;
min-width: 36ch;
overflow: hidden;
}
#chatbox-send {
padding: 0 1em;
position: relative;
}
#chatbox-send > input {
font-size: 0.75em;
width: 100%;
}
#emoji-autocomplete {
position: absolute;
bottom: 3.25rem;
background-image: var(--autocomplete-bg);
border-radius: 6px;
width: calc(100% - 2rem);
max-height: 8.5rem;
overflow-y: auto;
clip-path: inset(0 0 0 0 round 8px);
}
#emoji-autocomplete:empty {
display: none;
}
.emoji-option {
background: transparent;
font-size: 0.75rem;
text-align: left;
margin: 0 0.25rem;
border-radius: 4px;
width: calc(100% - 0.5rem);
display: flex;
align-items: center;
padding: 0.25rem 0.5rem;
scroll-margin: 0.25rem;
}
.emoji-option:first-child {
margin-top: 0.25rem;
}
.emoji-option:last-child {
margin-bottom: 0.25rem;
}
.emoji-option .emoji {
width: 1.25rem;
height: 1.25rem;
margin: 0 0.5rem 0 0;
font-size: 2.25ch;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
flex-shrink: 0;
}
.emoji-name {
overflow: hidden;
text-overflow: ellipsis;
}
.emoji-option.selected {
background: var(--fg-transparent);
}
#join-session-colour {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: none;
padding: 0;
border-radius: 6px;
overflow: hidden;
margin: 0.5em 0;
height: 2rem;
width: 2.5rem;
cursor: pointer;
}
#options-toggle {
padding: 0 1em 1em;
position: relative;
text-align: right;
margin-top: auto;
}
#options-toggle #options-icon {
padding: 3px 10px;
font-size: 1em;
max-width: 3em;
color: transparent;
text-shadow: 0 0 0 white;
border: none;
box-shadow:0px 0px 0px 2px var(--accent-darkest) inset;
transform-style: preserve-3d;
transition: cubic-bezier(0, 0, 0.58, 1), cubic-bezier(0, 0, 0.58, 1);
transition-duration: 150ms;
}
#options-toggle #options-icon::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--accent-darker);
border-radius: inherit;
border: none;
box-shadow:0px 0px 0px 2px var(--accent-darkest) inset;
transform: translate3d(0, 0.5em, -1em);
transition: cubic-bezier(0, 0, 0.58, 1), cubic-bezier(0, 0, 0.58, 1);
transition-duration: 150ms;
}
#options-toggle #options-icon:hover {
transform: translate(0, 0.15em);
background-color: rgb(173, 113, 216); /*5% darker accent*/
}
#options-toggle #options-icon:hover::before {
transform: translate3d(0, 0.35em, -1em);
}
#options-toggle #options-icon:active {
transform: translate(0em, 0.5em);
background-color: rgb(165, 100, 213); /*10% darker accent*/
}
#options-toggle #options-icon:active::before {
transform: translate3d(0, 0, -1em);
}
#options {
display: none; /* default for sections is block */
padding: 01em;
}
input[type="color"]::-moz-color-swatch {
border: none;
margin: 0;
padding: 0;
}
input[type="color"]::-webkit-color-swatch {
border: none;
margin: 0;
padding: 0;
}
input[type="color"]::-webkit-color-swatch-wrapper {
border: none;
margin: 0;
padding: 0;
}
@media (min-aspect-ratio: 4/3) {
body {
flex-direction: row;
}
#chatbox-container {
height: 100vh !important;
flex-grow: 0;
}
#video-container {
flex-grow: 1;
}
#chatbox {
height: calc(100vh - 5em - 4em) !important;
}
}