2
0

Add support for displaying link previews for Admin UI (#35958)

This commit is contained in:
Emelia Smith
2025-10-10 10:43:48 +02:00
committed by GitHub
parent c858fc77ef
commit 81350c7cfb
7 changed files with 154 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
import { createRoot } from 'react-dom/client';
import Rails from '@rails/ujs';
import { decode, ValidationError } from 'blurhash';
import ready from '../mastodon/ready';
@@ -362,6 +363,46 @@ ready(() => {
document.querySelectorAll('[data-admin-component]').forEach((element) => {
void mountReactComponent(element);
});
document
.querySelectorAll<HTMLCanvasElement>('canvas[data-blurhash]')
.forEach((canvas) => {
const blurhash = canvas.dataset.blurhash;
if (blurhash) {
try {
// decode returns a Uint8ClampedArray<ArrayBufferLike> not Uint8ClampedArray<ArrayBuffer>
const pixels = decode(
blurhash,
32,
32,
) as Uint8ClampedArray<ArrayBuffer>;
const ctx = canvas.getContext('2d');
const imageData = new ImageData(pixels, 32, 32);
ctx?.putImageData(imageData, 0, 0);
} catch (err) {
if (err instanceof ValidationError) {
// ignore blurhash validation errors
return;
}
throw err;
}
}
});
document
.querySelectorAll<HTMLDivElement>('.preview-card')
.forEach((previewCard) => {
const spoilerButton = previewCard.querySelector('.spoiler-button');
if (!spoilerButton) {
return;
}
spoilerButton.addEventListener('click', () => {
previewCard.classList.toggle('preview-card--image-visible');
});
});
}).catch((reason: unknown) => {
throw reason;
});

View File

@@ -1969,6 +1969,61 @@ a.sparkline {
display: list-item;
}
}
.preview-card {
position: relative;
max-width: 566px;
.status-card__image {
&--video {
aspect-ratio: 16 / 9;
}
&--large {
aspect-ratio: 1.91 / 1;
}
aspect-ratio: 1;
}
.spoiler-button__overlay__label {
outline: 1px solid var(--media-outline-color);
}
.hide-button {
// Toggled to appear when the preview-card is unblurred:
display: none;
position: absolute;
top: 5px;
right: 5px;
color: $white;
border: 0;
outline: 1px solid var(--media-outline-color);
background-color: color.change($black, $alpha: 0.45);
backdrop-filter: $backdrop-blur-filter;
padding: 3px 12px;
border-radius: 99px;
font-size: 14px;
font-weight: 700;
line-height: 20px;
&:hover,
&:focus {
background-color: color.change($black, $alpha: 0.9);
}
}
&.preview-card--image-visible {
.hide-button {
display: block;
}
.spoiler-button__overlay,
.status-card__image-preview {
display: none;
}
}
}
}
.admin {