your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { SelectThemePopover } from '$lib/components/select-theme';
3 import { getHideProfileSection, getProfilePosition } from '$lib/helper';
4 import type { WebsiteData } from '$lib/types';
5 import { Button } from '@foxui/core';
6 import { getIsMobile } from './context';
7
8 let { data = $bindable() }: { data: WebsiteData } = $props();
9
10 let accentColor = $derived(data.publication?.preferences?.accentColor ?? 'pink');
11 let baseColor = $derived(data.publication?.preferences?.baseColor ?? 'stone');
12
13 function updateTheme(newAccent: string, newBase: string) {
14 data.publication.preferences ??= {};
15 data.publication.preferences.accentColor = newAccent;
16 data.publication.preferences.baseColor = newBase;
17 data = { ...data };
18 }
19
20 let profilePosition = $derived(getProfilePosition(data));
21
22 function toggleProfilePosition() {
23 data.publication.preferences ??= {};
24 data.publication.preferences.profilePosition = profilePosition === 'side' ? 'top' : 'side';
25 data = { ...data };
26 }
27
28 let isMobile = getIsMobile();
29</script>
30
31<div class={['fixed top-2 left-14 z-20 flex gap-2']}>
32 <Button
33 size="icon"
34 onclick={() => {
35 data.publication.preferences ??= {};
36 data.publication.preferences.hideProfileSection =
37 !data.publication.preferences?.hideProfileSection;
38 data = { ...data };
39 }}
40 variant="ghost"
41 >
42 {#if !getHideProfileSection(data)}
43 <svg
44 xmlns="http://www.w3.org/2000/svg"
45 fill="none"
46 viewBox="0 0 24 24"
47 stroke-width="1.5"
48 stroke="currentColor"
49 class="size-5!"
50 >
51 <path
52 stroke-linecap="round"
53 stroke-linejoin="round"
54 d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88"
55 />
56 </svg>
57 {:else}
58 <svg
59 xmlns="http://www.w3.org/2000/svg"
60 fill="none"
61 viewBox="0 0 24 24"
62 stroke-width="1.5"
63 stroke="currentColor"
64 class="size-5!"
65 >
66 <path
67 stroke-linecap="round"
68 stroke-linejoin="round"
69 d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z"
70 />
71 <path
72 stroke-linecap="round"
73 stroke-linejoin="round"
74 d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
75 />
76 </svg>
77 {/if}
78 </Button>
79
80 <!-- Position toggle button (desktop only) -->
81 {#if !isMobile() && !getHideProfileSection(data)}
82 <Button size="icon" type="button" onclick={toggleProfilePosition} variant="ghost">
83 {#if profilePosition === 'side'}
84 <svg
85 xmlns="http://www.w3.org/2000/svg"
86 fill="none"
87 viewBox="0 0 24 24"
88 stroke-width="1.5"
89 stroke="currentColor"
90 class="size-5!"
91 >
92 <path
93 stroke-linecap="round"
94 stroke-linejoin="round"
95 d="m4.5 19.5 15-15m0 0H8.25m11.25 0v11.25"
96 />
97 </svg>
98 {:else}
99 <svg
100 xmlns="http://www.w3.org/2000/svg"
101 fill="none"
102 viewBox="0 0 24 24"
103 stroke-width="1.5"
104 stroke="currentColor"
105 class="size-5!"
106 >
107 <path
108 stroke-linecap="round"
109 stroke-linejoin="round"
110 d="m19.5 4.5-15 15m0 0h11.25m-11.25 0V8.25"
111 />
112 </svg>
113 {/if}
114 </Button>
115 {/if}
116
117 <!-- Theme selection -->
118 <SelectThemePopover
119 {accentColor}
120 {baseColor}
121 onchanged={(newAccent, newBase) => updateTheme(newAccent, newBase)}
122 />
123</div>