[READ-ONLY] Mirror of https://github.com/flo-bit/skywatched. review movies and tv shows, based on at proto
skywatched.app
4.2 kB
121 lines
1<script lang="ts">
2 import { crosspostModal, user } from '$lib/state.svelte';
3 import { toast } from 'svelte-sonner';
4
5 let ratingText = $derived.by(() => {
6 const ratingText = `I rated "${crosspostModal.title}" with ${crosspostModal.rating} star${crosspostModal.rating === 1 ? '' : 's'} on skywatched.app`;
7
8 let text = crosspostModal.review
9 ? `My review for "${crosspostModal.title}" on skywatched.app:<br /> <br />${crosspostModal.review}`
10 : ratingText;
11
12 if (text.length > 299) {
13 text = text.slice(0, 295) + '...';
14 }
15
16 return text;
17 });
18</script>
19
20{#if crosspostModal.showModal}
21 <div class="relative z-50" aria-labelledby="modal-title" role="dialog" aria-modal="true">
22 <div
23 class="fixed inset-0 bg-base-950/90 backdrop-blur-sm transition-opacity"
24 onclick={() => (crosspostModal.showModal = false)}
25 aria-hidden="true"
26 ></div>
27 <div class="pointer-events-none fixed inset-0 z-50 h-[100dvh] w-screen overflow-y-auto">
28 <div class="flex h-[100dvh] items-end justify-center p-4 text-center sm:items-center sm:p-0">
29 <div
30 class="pointer-events-auto relative w-full transform overflow-hidden rounded-lg border border-base-800 bg-base-900 px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:max-w-md sm:p-6"
31 >
32 <button
33 class="absolute right-2 top-2 rounded-full bg-base-800/50 p-1 hover:bg-base-800/80"
34 onclick={() => (crosspostModal.showModal = false)}
35 >
36 <svg
37 xmlns="http://www.w3.org/2000/svg"
38 fill="none"
39 viewBox="0 0 24 24"
40 stroke-width="1.5"
41 stroke="currentColor"
42 class="size-4"
43 >
44 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
45 </svg>
46
47 <span class="sr-only">close</span>
48 </button>
49
50 <div>
51 <h3 class="text-md mb-4 font-semibold text-base-50" id="modal-title">
52 Crosspost to Bluesky
53 </h3>
54
55 <p class="text-sm text-base-300">Do you want to crosspost this review to Bluesky?</p>
56
57 <div class="mt-4 rounded-xl border border-base-800 p-4 bg-base-950">
58 <div class="flex items-center gap-2">
59 {#if user.avatar}
60 <img src={user.avatar} alt="user avatar" class="size-5 rounded-full" />
61 {/if}
62 <div class="truncate text-sm font-medium">
63 {user.displayName || user.handle}
64 </div>
65 </div>
66
67 <p class="mt-2 text-sm text-base-300">
68 {@html ratingText}
69 </p>
70
71 <div class="relative mt-4 aspect-2 h-auto w-full rounded-md bg-base-800 overflow-hidden border border-base-800">
72
73 <div class="absolute flex items-center justify-center inset-0 h-full w-full bg-base-950/90">
74 <p>Loading image...</p>
75 </div>
76 <img
77 src="/review/{encodeURIComponent(crosspostModal.uri ?? '')}/og.png"
78 alt="crosspost"
79 class="absolute inset-0 h-full w-full object-cover"
80 />
81 </div>
82 </div>
83 </div>
84 <div class="mt-5 sm:mt-6">
85 <button
86 onclick={async () => {
87 crosspostModal.hide();
88 }}
89 type="button"
90 class="inline-flex w-full justify-center rounded-md border border-base-700 bg-white/5 px-3 py-2 text-sm font-semibold text-base-300 shadow-sm hover:bg-white/10 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-600"
91 >No thanks</button
92 >
93
94 <button
95 onclick={async () => {
96 crosspostModal.showModal = false;
97
98 const response = await fetch(`/api/crosspost`, {
99 method: 'POST',
100 body: JSON.stringify({
101 uri: crosspostModal.uri
102 })
103 });
104
105 if (!response.ok) {
106 toast.error('Failed to crosspost');
107 return;
108 }
109
110 toast.success('Crossposted to Bluesky');
111 }}
112 type="button"
113 class="mt-2 inline-flex w-full justify-center rounded-md border border-accent-900 bg-accent-950/80 px-3 py-2 text-sm font-semibold text-accent-300 shadow-sm hover:bg-accent-950 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent-600"
114 >Post to Bluesky</button
115 >
116 </div>
117 </div>
118 </div>
119 </div>
120 </div>
121{/if}