From 2f5fddcc6eb6ad31863057ff54deb2b84058e1e0 Mon Sep 17 00:00:00 2001 From: Maya Date: Thu, 14 Aug 2025 18:14:18 +0800 Subject: [PATCH] feat: use overlayscrollbars for cards finally no more shifting on chromium --- bun.lock | 6 + package.json | 2 + src/lib/css/app.scss | 38 ------ src/routes/+layout.svelte | 1 - src/routes/+page.svelte | 275 +++++++++++++++++++------------------- 5 files changed, 144 insertions(+), 178 deletions(-) diff --git a/bun.lock b/bun.lock index 33ce87a..3159530 100644 --- a/bun.lock +++ b/bun.lock @@ -17,6 +17,8 @@ "clsx": "^2.1.1", "lucide-svelte": "^0.475.0", "music-metadata": "^11.0.0", + "overlayscrollbars": "^2.11.5", + "overlayscrollbars-svelte": "^0.5.5", "p-queue": "^8.1.0", "riff-file": "^1.0.3", "svelte-stripe": "^1.4.0", @@ -641,6 +643,10 @@ "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "overlayscrollbars": ["overlayscrollbars@2.11.5", "", {}, "sha512-vTUfCtjJbTjiarrxl9qdK04ZxlQdB4ugXfiqctVZytYDXH259OM4whROMGDE6T8uCYmSYPqiOFIKZ1erVkJnFg=="], + + "overlayscrollbars-svelte": ["overlayscrollbars-svelte@0.5.5", "", { "peerDependencies": { "overlayscrollbars": "^2.0.0", "svelte": "^5.0.0" } }, "sha512-+dRW3YZSvFbKi5vDCpnUOHuoPLLSdu0BUVVMYZdmfVghu7XkafDRebG2y91/ImPqj6YDAUsz1rcWVYhCJSS/pQ=="], + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], diff --git a/package.json b/package.json index b3d7216..d5f1bf0 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,8 @@ "clsx": "^2.1.1", "lucide-svelte": "^0.475.0", "music-metadata": "^11.0.0", + "overlayscrollbars": "^2.11.5", + "overlayscrollbars-svelte": "^0.5.5", "p-queue": "^8.1.0", "riff-file": "^1.0.3", "svelte-stripe": "^1.4.0", diff --git a/src/lib/css/app.scss b/src/lib/css/app.scss index e81842c..7cf11b9 100644 --- a/src/lib/css/app.scss +++ b/src/lib/css/app.scss @@ -335,44 +335,6 @@ body { @apply bg-accent-purple !text-black; } -// firefox -* { - scrollbar-width: thin; - scrollbar-color: var(--bg-separator) transparent; -} - -// other browsers -*::-webkit-scrollbar { - width: 6px; - height: 6px; -} - -*::-webkit-scrollbar-track { - background: transparent; -} - -*::-webkit-scrollbar-thumb { - background-color: var(--bg-separator); - border-radius: 3px; - border: none; - opacity: 0.7; -} - -*::-webkit-scrollbar-thumb:hover { - background-color: var(--bg-separator); - opacity: 1; -} - -*::-webkit-scrollbar-corner { - background: transparent; -} - -*::-webkit-scrollbar-button { - display: none; - width: 0; - height: 0; -} - @layer components { select { @apply appearance-none; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 42fdba4..23913db 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -16,7 +16,6 @@ dropping, vertdLoaded, locale, - updateLocale, } from "$lib/store/index.svelte"; import "$lib/css/app.scss"; import { browser } from "$app/environment"; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index b13f243..3c56f9e 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -2,11 +2,13 @@ import Uploader from "$lib/components/functional/Uploader.svelte"; import Tooltip from "$lib/components/visual/Tooltip.svelte"; import { converters } from "$lib/converters"; - import { theme, vertdLoaded } from "$lib/store/index.svelte"; + import { vertdLoaded } from "$lib/store/index.svelte"; import clsx from "clsx"; import { AudioLines, BookText, Check, Film, Image } from "lucide-svelte"; import { m } from "$lib/paraglide/messages"; - import { link } from "$lib/store/index.svelte"; + import { OverlayScrollbarsComponent } from "overlayscrollbars-svelte"; + import { browser } from "$app/environment"; + import "overlayscrollbars/overlayscrollbars.css"; import { onMount } from "svelte"; const getSupportedFormats = (name: string) => @@ -79,33 +81,12 @@ let showBlur = $state(Array(Object.keys(status).length).fill(false)); onMount(() => { - const isFirefox = /firefox/i.test(navigator.userAgent); - const handleResize = () => { for (let i = 0; i < scrollContainers.length; i++) { // show bottom blur if scrollable const container = scrollContainers[i]; if (!container) return; showBlur[i] = container.scrollHeight > container.clientHeight; - - // if not on firefox, add ml-2 to card content if scrollable - // doing this because i can't figure out how to make the scrollbar *not* take up DOM space (shifting the contents to the left) - if (!isFirefox && scrollContainers[i]) { - const card = scrollContainers[i].closest( - ".file-category-card", - ); - const cardContent = card?.querySelector( - ".file-category-card-content", - ); - if (cardContent) { - const hasML2 = cardContent.classList.contains("ml-2"); - if (showBlur[i] && !hasML2) { - cardContent.classList.add("ml-2"); - } else if (!showBlur[i] && hasML2) { - cardContent.classList.remove("ml-2"); - } - } - } } }; @@ -147,124 +128,140 @@

{m["upload.cards.title"]()}

- {#each Object.entries(status) as [key, s], i} - {@const Icon = s.icon} -
-
-
- -
- {s.title} -
- -
-
-
- {#if key === "Video"} -

- - - - - {m[ - "upload.cards.video_server_processing" - ]()} - - * - - -

- {:else} -

- - {m["upload.cards.local_supported"]()} -

- {/if} -

- {@html m["upload.cards.status.text"]({ - status: s.ready - ? m["upload.cards.status.ready"]() - : m[ - "upload.cards.status.not_ready" - ](), - })} -

-
- {m[ - "upload.cards.supported_formats" - ]()}  -

- {#each s.formats.split(", ") as format, index} - {@const isPartial = - format.endsWith("*")} - {@const formatName = isPartial - ? format.slice(0, -1) - : format} - - {#if isPartial} - - {formatName}* - - {:else} - {formatName} - {/if} - {#if index < s.formats.split(", ").length - 1} - - {/if} - - {/each} -

-
-
-
- - {#if showBlur[i]} + {#if browser} + {#each Object.entries(status) as [key, s], i} + {@const Icon = s.icon} +
+
- {/if} + class={clsx("icon-container", { + "bg-accent-blue": key === "Images", + "bg-accent-purple": key === "Audio", + "bg-accent-green": key === "Documents", + "bg-accent-red": key === "Video", + })} + > + +
+ {s.title} +
+ +
+ +
+ {#if key === "Video"} +

+ + + + + {m[ + "upload.cards.video_server_processing" + ]()} + + * + + +

+ {:else} +

+ + {m[ + "upload.cards.local_supported" + ]()} +

+ {/if} +

+ {@html m["upload.cards.status.text"]({ + status: s.ready + ? m[ + "upload.cards.status.ready" + ]() + : m[ + "upload.cards.status.not_ready" + ](), + })} +

+
+ {m[ + "upload.cards.supported_formats" + ]()}  +

+ {#each s.formats.split(", ") as format, index} + {@const isPartial = + format.endsWith("*")} + {@const formatName = isPartial + ? format.slice(0, -1) + : format} + + {#if isPartial} + + {formatName}* + + {:else} + {formatName} + {/if} + {#if index < s.formats.split(", ").length - 1} + + {/if} + + {/each} +

+
+ + {#if showBlur[i]} +
+ {/if} +
+
+
-
- {/each} + {/each} + {/if}