fix: w2g/chat overflowing issues
Some checks are pending
Check / check (push) Waiting to run

fix: navigation scroll on anime page
feat: forums spoilers and youtube embeds
This commit is contained in:
ThaUnknown 2025-07-06 16:18:13 +02:00
parent b258b67f1b
commit 64298ff10d
No known key found for this signature in database
6 changed files with 33 additions and 15 deletions

View file

@ -1,6 +1,6 @@
{
"name": "ui",
"version": "6.4.19",
"version": "6.4.20",
"license": "BUSL-1.1",
"private": true,
"packageManager": "pnpm@9.14.4",

View file

@ -14,17 +14,28 @@
const style = new CSSStyleSheet()
style.replaceSync(/* css */`
p {
p, details {
margin-block-start: .5em;
margin-block-end: .5em;
}
img, video {
max-width: 100%;
-webkit-user-drag: none;
}`)
}
summary {
font-weight: bold;
cursor: pointer;
list-style: none;
background: #0f0f0f;
display: inline-block;
padding: 0.4em 0.8em;
border-radius: 0.5em;
margin-block-end: .5em;
}
`)
function sanitize (html: string) {
return dompurify.sanitize(html, { ALLOWED_TAGS: ['a', 'b', 'blockquote', 'br', 'center', 'del', 'div', 'em', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'code', 'span', 'strike', 'strong', 'ul'], ALLOWED_ATTR: ['align', 'height', 'href', 'src', 'target', 'width', 'rel'] })
return dompurify.sanitize(html, { ALLOWED_TAGS: ['a', 'b', 'blockquote', 'br', 'center', 'del', 'div', 'em', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'code', 'span', 'strike', 'strong', 'ul', 'details', 'summary'], ALLOWED_ATTR: ['align', 'height', 'href', 'src', 'target', 'width', 'rel'] })
}
// i mean holy shit anilist, could you have made it any harder on yourself
@ -39,12 +50,12 @@
// eslint-disable-next-line no-useless-escape
.replace(/webm\s?\(h?([A-Za-z0-9-._~:\/?#\[\]@!$&()*+,;=%]+)\)/gi, 'webmv(`$1`)')
.replace(/~{3}([^]*?)~{3}/gm, '+++$1+++')
.replace(/~!([^]*?)!~/gm, '<div rel="spoiler">$1</div>')
.replace(/~!([^]*?)!~/gm, '<details><summary>Spoiler, click to view</summary>$1</details>')
html = sanitize(marked.parse(html, { async: false }))
.replace(/\+{3}([^]*?)\+{3}/gm, '<center>$1</center>')
// t = t.replace(/<div rel="spoiler">([\s\S]*?)<\/div>/gm, "<p><span onclick='showSpoiler(this)' class='markdown-spoiler'><i class='hide-spoiler el-icon-circle-close' onclick='hideSpoiler(this)'></i><span>$1</span></span></p>")
// t = t.replace(/youtube\s?\(([-_0-9A-Za-z]{10,15})\)/gi, "<span class='youtube' id='$1' style='width: 500px; height: 200px; max-width: 100%;'><span class='play'></span></span>")
// eslint-disable-next-line no-useless-escape
.replace(/youtube\s?\(([-_0-9A-Za-z]{10,15})\)/gi, `<iframe style='width: 500px; height: 200px; max-width: 100%; border: none;'title='youtube-embed' allow='autoplay' allowfullscreen
src='https://www.youtube-nocookie.com/embed/$1?enablejsapi=1&autoplay=0&controls=1&mute=0&disablekb=1&loop=1&playlist=$1&cc_lang_pref=ja' />`)
// eslint-disable-next-line no-useless-escape
.replace(/webmv\s?\(<code>([A-Za-z0-9-._~:\/?#\[\]@!$&()*+,;=%]+)<\/code>\)/gi, "<video muted loop controls><source src='h$1' type='video/webm'>Your browser does not support the video tag.</video>")
// t = t.replace(/(?:<a href="https?:\/\/anilist.co\/(anime|manga)\/)([0-9]+).*?>(?:https?:\/\/anilist.co\/(?:anime|manga)\/[0-9]+).*?<\/a>/gm, '<span class="media-embed" data-media-type="$1" data-media-id="$2"></span>')

View file

@ -11,10 +11,7 @@
$: processed = Object.entries(users)
</script>
<div class='flex flex-col w-full md:w-72 max-w-full px-5 overflow-y-auto md:max-h-full max-h-[40%]'>
<div class='text-md font-bold pl-1 pb-2'>
{processed.length} Member(s)
</div>
<div class='flex flex-col w-full md:w-72 max-w-full px-5 overflow-y-auto md:max-h-full max-h-[40%] min-h-0 pb-2'>
<div>
{#each processed as [key, user] (key)}
<div class='flex items-center pb-2'>

View file

@ -56,7 +56,7 @@
</p>
<Separator class='!my-6' />
</div>
<div class='flex md:flex-row flex-col-reverse w-full h-full'>
<div class='flex md:flex-row flex-col-reverse w-full h-full min-h-0'>
<div class='flex flex-col justify-end overflow-clip flex-grow px-4 pb-4 h-full min-h-0'>
<div class='h-full overflow-y-scroll min-h-0 w-full'>
<Messages messages={client.messages} />

View file

@ -9,6 +9,7 @@
import type { LayoutData } from './$types'
import { onNavigate } from '$app/navigation'
import Anilist from '$lib/components/icons/Anilist.svelte'
import MyAnimeList from '$lib/components/icons/MyAnimeList.svelte'
import { bannerSrc, hideBanner } from '$lib/components/ui/banner'
@ -61,9 +62,18 @@
$: nativeTitle = media.title?.native ?? media.title?.romaji ?? ''
$: romajiTitle = media.title?.romaji ?? media.title?.native ?? ''
let container: HTMLDivElement
onNavigate(() => {
container.scrollTo({
top: 0,
behavior: 'smooth'
})
})
</script>
<div class='min-w-0 -ml-14 pl-14 grow items-center flex flex-col h-full overflow-y-auto z-10 pointer-events-none pb-10' use:dragScroll on:scroll={handleScroll}>
<div class='min-w-0 -ml-14 pl-14 grow items-center flex flex-col h-full overflow-y-auto z-10 pointer-events-none pb-10' use:dragScroll on:scroll={handleScroll} bind:this={container}>
<div class='gap-6 w-full pt-4 md:pt-32 flex flex-col items-center justify-center max-w-[1600px] px-3 xl:px-14 pointer-events-auto overflow-x-clip'>
<div class='flex flex-col md:flex-row w-full items-center md:items-end gap-5 pt-12'>
<Dialog.Root portal='#root'>

View file

@ -64,7 +64,7 @@
</p>
<Separator class='!my-6' />
</div>
<div class='flex md:flex-row flex-col-reverse w-full h-full'>
<div class='flex md:flex-row flex-col-reverse w-full h-full min-h-0'>
<div class='flex flex-col justify-end overflow-clip flex-grow px-4 pb-4 h-full min-h-0'>
<div class='h-full overflow-y-scroll min-h-0 w-full'>
<Messages {messages} />