From e9eb553a66ee6fb8a52179f2f7b90aba5d628219 Mon Sep 17 00:00:00 2001
From: ilovemoon
Date: Sun, 5 Jan 2025 11:45:09 +0530
Subject: [PATCH] feat: integrate custom `smiz` lib (#101)
---
frontend/package-lock.json | 43 ++++---
frontend/package.json | 1 +
frontend/src/lib/components/quib.svelte | 7 +-
.../lib/components/ui/backdrop_image.svelte | 10 +-
frontend/src/lib/components/ui/zoom.svelte | 28 +++++
.../q/[name]/quibs/[id]/[slug]/+page.svelte | 7 +-
frontend/src/routes/+layout.svelte | 3 +-
frontend/src/{ => styles}/app.css | 0
frontend/src/styles/smiz.css | 106 ++++++++++++++++++
9 files changed, 185 insertions(+), 20 deletions(-)
create mode 100644 frontend/src/lib/components/ui/zoom.svelte
rename frontend/src/{ => styles}/app.css (100%)
create mode 100644 frontend/src/styles/smiz.css
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index fd4bb262..39cbef06 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
+ "name": "frontend",
"devDependencies": {
"@coreproject-moe/icons": "^0.0.67",
"@dotenvx/dotenvx": "^1.28.0",
@@ -34,6 +35,7 @@
"readable-numbers": "^1.0.8",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
+ "svelte-medium-image-zoom": "^0.1.4",
"tailwind-merge": "^2.5.4",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.9",
@@ -795,9 +797,9 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz",
- "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz",
+ "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1425,16 +1427,17 @@
}
},
"node_modules/@sveltejs/kit": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.8.3.tgz",
- "integrity": "sha512-DVBVwugfzzn0SxKA+eAmKqcZ7aHZROCHxH7/pyrOi+HLtQ721eEsctGb9MkhEuqj6q/9S/OFYdn37vdxzFPdvw==",
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.15.1.tgz",
+ "integrity": "sha512-8t7D3hQHbUDMiaQ2RVnjJJ/+Ur4Fn/tkeySJCsHtX346Q9cp3LAnav8xXdfuqYNJwpUGX0x3BqF1uvbmXQw93A==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
"cookie": "^0.6.0",
"devalue": "^5.1.0",
- "esm-env": "^1.0.0",
+ "esm-env": "^1.2.1",
"import-meta-resolve": "^4.1.0",
"kleur": "^4.1.5",
"magic-string": "^0.30.5",
@@ -1451,9 +1454,9 @@
"node": ">=18.13"
},
"peerDependencies": {
- "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1",
+ "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
"svelte": "^4.0.0 || ^5.0.0-next.0",
- "vite": "^5.0.3"
+ "vite": "^5.0.3 || ^6.0.0"
}
},
"node_modules/@sveltejs/vite-plugin-svelte": {
@@ -2847,9 +2850,9 @@
}
},
"node_modules/esm-env": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.1.4.tgz",
- "integrity": "sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.1.tgz",
+ "integrity": "sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==",
"dev": true,
"license": "MIT"
},
@@ -3863,9 +3866,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
@@ -5184,6 +5187,16 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/svelte-medium-image-zoom": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/svelte-medium-image-zoom/-/svelte-medium-image-zoom-0.1.4.tgz",
+ "integrity": "sha512-icm9p/13gLxBug6v71Xct9RHrj8T50xiliMzV8fU2diI7oy4uAdBhLo/lCOZV1FDltAmUNKfVdSmWEY0Vy4QsA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "svelte": "^5.0.0"
+ }
+ },
"node_modules/tailwind-merge": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index f6dd34a8..922e820d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -43,6 +43,7 @@
"readable-numbers": "^1.0.8",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
+ "svelte-medium-image-zoom": "^0.1.4",
"tailwind-merge": "^2.5.4",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.9",
diff --git a/frontend/src/lib/components/quib.svelte b/frontend/src/lib/components/quib.svelte
index 635a97ab..cc508004 100644
--- a/frontend/src/lib/components/quib.svelte
+++ b/frontend/src/lib/components/quib.svelte
@@ -3,6 +3,7 @@
import type { components } from '$lib/clients/v1';
import Avatar from '$lib/components/ui/avatar.svelte';
import BackdropImage from '$lib/components/ui/backdrop_image.svelte';
+ import Zoom from '$lib/components/ui/zoom.svelte';
import { cn } from '$lib/functions/classnames';
import { FormatDate } from '$lib/functions/date';
import { is_valid } from '$lib/functions/is_valid';
@@ -45,7 +46,11 @@
{quib.content}
{:else}
-
+
+
+
+
+
{/if}
{/snippet}
diff --git a/frontend/src/lib/components/ui/backdrop_image.svelte b/frontend/src/lib/components/ui/backdrop_image.svelte
index bdfed1c6..dca18c48 100644
--- a/frontend/src/lib/components/ui/backdrop_image.svelte
+++ b/frontend/src/lib/components/ui/backdrop_image.svelte
@@ -1,15 +1,17 @@
-
+ {#if children}
+ {@render children()}
+ {:else}
+
+ {/if}
diff --git a/frontend/src/lib/components/ui/zoom.svelte b/frontend/src/lib/components/ui/zoom.svelte
new file mode 100644
index 00000000..61a0d59c
--- /dev/null
+++ b/frontend/src/lib/components/ui/zoom.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+ {#snippet icon_zoom()}
+
+ {/snippet}
+ {#snippet icon_unzoom()}
+
+ {/snippet}
+
+ {#snippet zoom_content({ img, button_unzoom, modal_state })}
+
+ {@render img()}
+
+ {@render button_unzoom()}
+
+ {/snippet}
+
+ {@render children()}
+
diff --git a/frontend/src/routes/(app)/q/[name]/quibs/[id]/[slug]/+page.svelte b/frontend/src/routes/(app)/q/[name]/quibs/[id]/[slug]/+page.svelte
index f6738989..b5b02844 100644
--- a/frontend/src/routes/(app)/q/[name]/quibs/[id]/[slug]/+page.svelte
+++ b/frontend/src/routes/(app)/q/[name]/quibs/[id]/[slug]/+page.svelte
@@ -6,6 +6,7 @@
import TopIcon from '$lib/components/icons/top.svelte';
import Avatar from '$lib/components/ui/avatar.svelte';
import BackdropImage from '$lib/components/ui/backdrop_image.svelte';
+ import Zoom from '$lib/components/ui/zoom.svelte';
import { cn } from '$lib/functions/classnames';
import { FormatDate } from '$lib/functions/date';
import { is_valid } from '$lib/functions/is_valid';
@@ -90,7 +91,11 @@
{quib.content}
{:else}
-
+
+
+
+
+
{/if}
diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte
index 5ffee085..9895c5d7 100644
--- a/frontend/src/routes/+layout.svelte
+++ b/frontend/src/routes/+layout.svelte
@@ -4,7 +4,8 @@
import Modals from '$lib/components/modals/index.svelte';
import Sidebar from '$lib/components/sidebar.svelte';
import { createAuthStore } from '$lib/stores/auth.svelte';
- import '../app.css';
+ import '../styles/app.css';
+ import '../styles/smiz.css';
import { defineCustomElements } from '@coreproject-moe/icons/loader';
import { onMount, type Snippet } from 'svelte';
diff --git a/frontend/src/app.css b/frontend/src/styles/app.css
similarity index 100%
rename from frontend/src/app.css
rename to frontend/src/styles/app.css
diff --git a/frontend/src/styles/smiz.css b/frontend/src/styles/smiz.css
new file mode 100644
index 00000000..e7bf3aca
--- /dev/null
+++ b/frontend/src/styles/smiz.css
@@ -0,0 +1,106 @@
+[data-smiz-ghost] {
+ position: absolute;
+ pointer-events: none;
+}
+
+[data-smiz-btn-zoom],
+[data-smiz-btn-unzoom] {
+ /* background-color: rgba(0, 0, 0, 0.7); */
+ border-radius: 50%;
+ /* border: none; */
+ /* box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); */
+ /* color: #fff; */
+ height: 40px;
+ margin: 0;
+ outline: none !important;
+ /* outline-offset: 2px; */
+ padding: 9px;
+ touch-action: manipulation;
+ width: 40px;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+[data-smiz-btn-zoom]:not(:focus):not(:active) {
+ position: absolute;
+ clip: rect(0 0 0 0);
+ clip-path: inset(50%);
+ height: 1px;
+ overflow: hidden;
+ pointer-events: none;
+ white-space: nowrap;
+ width: 1px;
+}
+
+[data-smiz-btn-zoom] {
+ position: absolute;
+ inset: 10px 10px auto auto;
+ /* cursor: zoom-in; */
+}
+
+[data-smiz-btn-unzoom] {
+ position: absolute;
+ inset: 20px 20px auto auto;
+ /* cursor: zoom-out; */
+ z-index: 1;
+}
+
+[data-smiz-content='found'] img,
+[data-smiz-content='found'] [role='img'],
+[data-smiz-content='found'] [data-zoom] {
+ cursor: zoom-in;
+}
+
+[data-smiz-modal]::backdrop {
+ display: none;
+}
+
+[data-smiz-modal][open] {
+ position: fixed;
+ width: 100vw;
+ width: 100dvw;
+ height: 100vh;
+ height: 100dvh;
+ max-width: none;
+ max-height: none;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ overflow: hidden;
+}
+
+[data-smiz-modal-overlay] {
+ position: absolute;
+ inset: 0;
+ transition: background-color 0.3s;
+}
+
+[data-smiz-modal-overlay='hidden'] {
+ background-color: oklch(var(--b3) / 0);
+}
+
+[data-smiz-modal-overlay='visible'] {
+ background-color: oklch(var(--b3) / 0.55);
+}
+
+[data-smiz-modal-content] {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+[data-smiz-modal-img] {
+ position: absolute;
+ cursor: zoom-out;
+ transform-origin: top left;
+ transition: transform 0.3s;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ [data-smiz-modal-overlay],
+ [data-smiz-modal-img] {
+ transition-duration: 0.01ms !important;
+ }
+}