Skip to content

Commit 918ae90

Browse files
committed
Fix thumbnails not displaying full video labels on new YouTube layout
Fixes ajayyy#2332
1 parent e1e6660 commit 918ae90

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

maze-utils

src/utils/thumbnails.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { isOnInvidious, parseYouTubeVideoIDFromURL } from "../../maze-utils/src/video";
1+
import { extractVideoID, isOnInvidious } from "../../maze-utils/src/video";
22
import Config from "../config";
33
import { getHasStartSegment, getVideoLabel } from "./videoLabels";
44
import { getThumbnailSelector, setThumbnailListener } from "../../maze-utils/src/thumbnailManagement";
55
import { VideoID } from "../types";
66
import { getSegmentsForVideo } from "./segmentData";
7+
import { onMobile } from "../../maze-utils/src/pageInfo";
78

89
export async function handleThumbnails(thumbnails: HTMLImageElement[]): Promise<void> {
910
await Promise.all(thumbnails.map((t) => {
@@ -18,7 +19,7 @@ export async function labelThumbnail(thumbnail: HTMLImageElement): Promise<HTMLE
1819
return null;
1920
}
2021

21-
const videoID = extractVideoID(thumbnail);
22+
const videoID = await extractVideoIDFromElement(thumbnail);
2223
if (!videoID) {
2324
hideThumbnailLabel(thumbnail);
2425
return null;
@@ -61,7 +62,7 @@ function thumbnailHoverListener(e: MouseEvent) {
6162
let fetched = false;
6263
const preFetch = async () => {
6364
fetched = true;
64-
const videoID = extractVideoID(thumbnail);
65+
const videoID = await extractVideoIDFromElement(thumbnail);
6566
if (videoID && await getHasStartSegment(videoID)) {
6667
void getSegmentsForVideo(videoID, false);
6768
}
@@ -84,18 +85,28 @@ function thumbnailHoverListener(e: MouseEvent) {
8485
function getLink(thumbnail: HTMLImageElement): HTMLAnchorElement | null {
8586
if (isOnInvidious()) {
8687
return thumbnail.parentElement as HTMLAnchorElement | null;
87-
} else if (thumbnail.nodeName.toLowerCase() === "yt-thumbnail-view-model") {
88-
return thumbnail.closest("yt-lockup-view-model")?.querySelector("a.yt-lockup-metadata-view-model-wiz__title");
88+
} else if (!onMobile()) {
89+
const link = thumbnail.querySelector("a#thumbnail, a.reel-item-endpoint, a.yt-lockup-metadata-view-model__title, a.yt-lockup-metadata-view-model__title-link, a.yt-lockup-view-model__content-image, a.yt-lockup-metadata-view-model-wiz__title") as HTMLAnchorElement;
90+
if (link) {
91+
return link;
92+
} else if (thumbnail.nodeName === "YTD-HERO-PLAYLIST-THUMBNAIL-RENDERER"
93+
|| thumbnail.nodeName === "YT-THUMBNAIL-VIEW-MODEL"
94+
) {
95+
return thumbnail.closest("a") as HTMLAnchorElement;
96+
} else {
97+
return null;
98+
}
8999
} else {
90-
return thumbnail.querySelector("#thumbnail");
100+
// Big thumbnails, compact thumbnails, shorts, channel feature, playlist header
101+
return thumbnail.querySelector("a.media-item-thumbnail-container, a.compact-media-item-image, a.reel-item-endpoint, :scope > a, .amsterdam-playlist-thumbnail-wrapper > a") as HTMLAnchorElement;
91102
}
92103
}
93104

94-
function extractVideoID(thumbnail: HTMLImageElement): VideoID | null {
105+
async function extractVideoIDFromElement(thumbnail: HTMLImageElement): Promise<VideoID | null> {
95106
const link = getLink(thumbnail);
96107
if (!link || link.nodeName !== "A" || !link.href) return null; // no link found
97108

98-
return parseYouTubeVideoIDFromURL(link.href)?.videoID;
109+
return await extractVideoID(link);
99110
}
100111

101112
function getOldThumbnailLabel(thumbnail: HTMLImageElement): HTMLElement | null {

0 commit comments

Comments
 (0)