aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-04-18 18:38:14 -0700
committerFuwn <[email protected]>2024-04-18 18:38:14 -0700
commit15f52f55955d56989b7b6039c04c0df427ff1bde (patch)
tree60f1d27556628e2d552e090e190088be8197a85f /src/lib
parentfeat(badges): auto-collapse awc when owner (diff)
downloaddue.moe-15f52f55955d56989b7b6039c04c0df427ff1bde.tar.xz
due.moe-15f52f55955d56989b7b6039c04c0df427ff1bde.zip
feat(badges): badge preview pane
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/BadgeWall/BadgePreview.svelte129
-rw-r--r--src/lib/FallbackBadge.svelte12
2 files changed, 140 insertions, 1 deletions
diff --git a/src/lib/BadgeWall/BadgePreview.svelte b/src/lib/BadgeWall/BadgePreview.svelte
new file mode 100644
index 00000000..0cf7bb9c
--- /dev/null
+++ b/src/lib/BadgeWall/BadgePreview.svelte
@@ -0,0 +1,129 @@
+<script lang="ts">
+ import type { Badge } from '$lib/Database/userBadges';
+ import cdn from '$lib/Utility/cdn';
+ import { databaseTimeToDate } from '$lib/Utility/time';
+ import locale from '$stores/locale';
+ import { cubicOut } from 'svelte/easing';
+ import { tweened } from 'svelte/motion';
+
+ export let badge: Badge | undefined;
+
+ let badgeReference: HTMLImageElement;
+ const mouse = tweened(
+ { x: 0, y: 0 },
+ {
+ duration: 200 * 1.75,
+ easing: cubicOut
+ }
+ );
+
+ const handleMouseMove = (event: MouseEvent) => {
+ const boundingRectangle = badgeReference.getBoundingClientRect();
+ const factor = 1.25;
+
+ if ($mouse.x === 0 && $mouse.y === 0) $mouse = { x: event.clientX, y: event.clientY };
+
+ $mouse.x +=
+ (-(event.clientX - boundingRectangle.left - boundingRectangle.width / 2) - $mouse.x) * factor;
+ $mouse.y +=
+ (-(event.clientY - boundingRectangle.top - boundingRectangle.height / 2) - $mouse.y) * factor;
+ };
+
+ const handleMouseLeave = () => {
+ $mouse = { x: 0, y: 0 };
+ };
+</script>
+
+{#if badge}
+ <div class="badge-preview">
+ {#if badge.image}
+ <div
+ on:mousemove={handleMouseMove}
+ on:mouseleave={handleMouseLeave}
+ role="img"
+ class="badge-container"
+ >
+ <img
+ src={cdn(badge.image)}
+ bind:this={badgeReference}
+ style="transform: perspective(1000px) rotateX({$mouse.y / 10}deg) rotateY({-$mouse.x /
+ 10}deg);"
+ alt={badge.description}
+ />
+ </div>
+
+ <p />
+ {/if}
+
+ {#if badge.time}
+ {$locale().dateFormatter(databaseTimeToDate(badge.time))}
+
+ {#if (badge.designer || badge.source || badge.post) && !badge.description}
+ <p />
+ {:else if badge.description}
+ <br />
+ {/if}
+ {/if}
+
+ {#if badge.description}
+ {badge.description}
+
+ {#if badge.designer || badge.source || badge.post}
+ <p />
+ {/if}
+ {/if}
+
+ {#if badge.designer}
+ <b>Designer:</b>
+
+ {#if badge.designer.startsWith('http')}
+ <a href={badge.designer} target="_blank">
+ {badge.designer}
+ </a>
+ {:else if badge.designer.startsWith('@')}
+ <a href="https://anilist.co/user/{badge.designer.replace('@', '')}" target="_blank">
+ {badge.designer}
+ </a>
+ {:else}
+ {badge.designer}
+ {/if}
+
+ <br />
+ {/if}
+
+ {#if badge.post}
+ <b>{badge.post.includes('forum') ? 'Forum' : 'Activity'}:</b>
+
+ <a href={badge.post} target="_blank">
+ {badge.post}
+ </a>
+
+ <br />
+ {/if}
+
+ {#if badge.source}
+ <b>Source:</b>
+
+ {#if badge.source.startsWith('http')}
+ <a href={badge.source} target="_blank">
+ {badge.source}
+ </a>
+ {:else}
+ {badge.source}
+ {/if}
+ {/if}
+ </div>
+{/if}
+
+<style>
+ .badge-preview img {
+ border-radius: 8px;
+ max-width: 25vh;
+ }
+
+ .badge-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+</style>
diff --git a/src/lib/FallbackBadge.svelte b/src/lib/FallbackBadge.svelte
index 323ea791..c4604263 100644
--- a/src/lib/FallbackBadge.svelte
+++ b/src/lib/FallbackBadge.svelte
@@ -13,6 +13,7 @@
export let hideOnError = false;
export let badge: Badge;
export let style = '';
+ export let selectedBadge: Badge | null = null;
let replaceCount = 0;
let badgeReference: HTMLImageElement;
@@ -56,7 +57,16 @@
pin={`badge-${badge.id}`}
pinPosition="top"
>
- <a href={badge.post} target="_blank" class="badge-container badge">
+ <a
+ href={'#'}
+ target="_blank"
+ class="badge-container badge"
+ on:click={(e) => {
+ e.preventDefault();
+
+ selectedBadge = badge;
+ }}
+ >
<img
src={source}
alt={alternative}