From 5e26f053cb837b1180ca24d21fc74fd85f75549e Mon Sep 17 00:00:00 2001 From: Grace Kind Date: Mon, 6 Jul 2026 14:25:44 -0500 Subject: [PATCH] Update youtube embed styles --- package.json | 2 +- src/css/style.css | 36 ++--- src/js/components/youtube-embed.js | 39 +++--- src/js/templates/externalLink.template.js | 32 ++++- src/js/templates/postEmbed.template.js | 7 +- tests/e2e/specs/concerns/postEmbeds.test.js | 9 +- .../specs/components/youtube-embed.test.js | 119 ++++++++++++---- .../templates/externalLink.template.test.js | 129 +++++++++++++++++- .../templates/postEmbed.template.test.js | 11 +- 9 files changed, 299 insertions(+), 85 deletions(-) diff --git a/package.json b/package.json index 4fc408de..1046e235 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "impro", - "version": "0.17.105", + "version": "0.17.106", "type": "module", "scripts": { "start": "rm -rf \"${BUILD_DIR:-build}\" && NODE_ENV=development eleventy --serve", diff --git a/src/css/style.css b/src/css/style.css index 9a82a639..fc7a08db 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -2363,28 +2363,17 @@ animated-button { .youtube-embed { display: block; - background: var(--black); } -.youtube-embed-play-button { - display: block; +.youtube-embed.is-playing { position: relative; - width: 100%; - height: 100%; - padding: 0; - border: none; - background: none; - cursor: pointer; -} - -.youtube-embed-thumb { - display: block; - width: 100%; - height: 100%; - object-fit: cover; + border: var(--hair) solid var(--post-border-color); + border-radius: var(--video-border-radius); + overflow: hidden; + background: var(--black); + transform: translateZ(0); /* Prevents video jiggle on iPadOS scroll */ } -.youtube-embed-play-button .play-icon, .external-link-image-wrapper .play-icon { position: absolute; top: 50%; @@ -2398,11 +2387,10 @@ animated-button { transition: background 0.15s ease; } -.youtube-embed-play-button:hover .play-icon { +.youtube-embed .external-link a:hover .play-icon { background: color-mix(in srgb, var(--white) 85%, transparent); } -.youtube-embed-play-button .play-icon svg, .external-link-image-wrapper .play-icon svg { width: 100%; height: 100%; @@ -2467,6 +2455,12 @@ animated-button { pointer-events: none; } +.external-link-video-placeholder { + height: 96px; + background: var(--background-color); + border-bottom: var(--hair) solid var(--post-border-color); +} + .external-link-uri { color: var(--text-color-muted); font-size: 12px; @@ -4389,10 +4383,10 @@ chat-input .rich-text-input { outline: none; /* Cap auto-grow so a long multi-line message scrolls internally instead of pushing the whole input bar up off the top of the (short, mobile) viewport. */ - max-height: min(120px, 30vh); + max-height: min(250px, 50vh); overflow-y: auto; line-height: 1.4; - scrollbar-width: none; + scrollbar-width: thin; } chat-input .rich-text-input[contenteditable="false"] { diff --git a/src/js/components/youtube-embed.js b/src/js/components/youtube-embed.js index 4a2a14b4..98e1ec13 100644 --- a/src/js/components/youtube-embed.js +++ b/src/js/components/youtube-embed.js @@ -1,8 +1,9 @@ import { html, render } from "/js/lib/lit-html.js"; import { Component } from "/js/components/component.js"; -import { playIconTemplate } from "/js/templates/icons/playIcon.template.js"; +import { externalLinkTemplate } from "/js/templates/externalLink.template.js"; const YOUTUBE_EMBED_BASE_URL = "https://www.youtube-nocookie.com/embed"; +const DEFAULT_ASPECT_RATIO = String(16 / 9); class YoutubeEmbed extends Component { connectedCallback() { @@ -13,6 +14,9 @@ class YoutubeEmbed extends Component { this.start = this.getAttribute("start"); this.thumb = this.getAttribute("thumb"); this.videoTitle = this.getAttribute("video-title") ?? ""; + this.url = this.getAttribute("url"); + this.description = this.getAttribute("description") ?? ""; + this.aspectRatio = this.getAttribute("aspect-ratio"); this.playing = false; this.dataset.teststate = "preview"; this.render(); @@ -29,6 +33,8 @@ class YoutubeEmbed extends Component { play() { this.playing = true; this.dataset.teststate = "playing"; + this.classList.add("is-playing"); + this.style.aspectRatio = this.aspectRatio || DEFAULT_ASPECT_RATIO; this.render(); this.querySelector("iframe")?.focus(); } @@ -44,28 +50,17 @@ class YoutubeEmbed extends Component { allow="autoplay; fullscreen; encrypted-media; picture-in-picture" allowfullscreen >` - : html``, + : "Play YouTube video", + }), this, ); } diff --git a/src/js/templates/externalLink.template.js b/src/js/templates/externalLink.template.js index a322c30a..b8e0da8d 100644 --- a/src/js/templates/externalLink.template.js +++ b/src/js/templates/externalLink.template.js @@ -4,7 +4,11 @@ import { isVideoLink } from "/js/dataHelpers.js"; import { playIconTemplate } from "/js/templates/icons/playIcon.template.js"; function getDomainFromUri(uri) { - return new URL(uri).hostname; + try { + return new URL(uri).hostname; + } catch (error) { + return null; + } } export function externalLinkTemplate({ @@ -14,12 +18,28 @@ export function externalLinkTemplate({ image, lazyLoadImages, disableNavigation, + onClick, + ariaLabel = null, }) { + let clickHandler = null; + if (onClick) { + clickHandler = (event) => { + if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { + return; + } + event.preventDefault(); + event.stopPropagation(); + onClick(event); + }; + } else if (disableNavigation) { + clickHandler = (event) => event.preventDefault(); + } return html`