fork
Configure Feed
Select the types of activity you want to include in your feed.
this repo has no description
fork
Configure Feed
Select the types of activity you want to include in your feed.
1<script lang="ts">
2 import { Post } from "./pdsfetch";
3 import { Config } from "../../config";
4 import { onMount } from "svelte";
5 import moment from "moment";
6
7 let { post }: { post: Post } = $props();
8
9 // State for image carousel
10 let currentImageIndex = $state(0);
11
12 // Functions to navigate carousel
13 function nextImage() {
14 if (post.imagesCid && currentImageIndex < post.imagesCid.length - 1) {
15 currentImageIndex++;
16 }
17 }
18
19 function prevImage() {
20 if (currentImageIndex > 0) {
21 currentImageIndex--;
22 }
23 }
24
25 // Function to preload an image
26 function preloadImage(index: number): void {
27 if (!post.imagesCid || index < 0 || index >= post.imagesCid.length) return;
28
29 const img = new Image();
30 img.src = `${Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did=${post.authorDid}&cid=${post.imagesCid[index]}`;
31 }
32
33 // Preload adjacent images when current index changes
34 $effect(() => {
35 if (post.imagesCid && post.imagesCid.length > 1) {
36 // Preload next image if available
37 if (currentImageIndex < post.imagesCid.length - 1) {
38 preloadImage(currentImageIndex + 1);
39 }
40
41 // Preload previous image if available
42 if (currentImageIndex > 0) {
43 preloadImage(currentImageIndex - 1);
44 }
45 }
46 });
47
48 // Initial preload of images
49 onMount(() => {
50 if (post.imagesCid && post.imagesCid.length > 1) {
51 // Preload the next image if it exists
52 if (post.imagesCid.length > 1) {
53 preloadImage(1);
54 }
55 }
56 });
57</script>
58
59<div id="postContainer">
60 <div id="postHeader">
61 {#if post.authorAvatarCid}
62 <img
63 id="avatar"
64 src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post.authorAvatarCid}"
65 alt="avatar of {post.displayName}"
66 />
67 {/if}
68 <div id="headerText">
69 <a id="displayName" href="{Config.FRONTEND_URL}/profile/{post.authorDid}"
70 >{post.displayName}</a
71 >
72 <p id="handle">
73 <a href="{Config.FRONTEND_URL}/profile/{post.authorHandle}"
74 >@{post.authorHandle}</a
75 >
76
77 <a
78 id="postLink"
79 href="{Config.FRONTEND_URL}/profile/{post.authorDid}/post/{post.recordName}"
80 >{moment(post.timenotstamp).isBefore(moment().subtract(1, "month"))
81 ? moment(post.timenotstamp).format("MMM D, YYYY")
82 : moment(post.timenotstamp).fromNow()}</a
83 >
84 </p>
85 </div>
86 </div>
87 <div id="postContent">
88 {#if post.replyingUri}
89 <a
90 id="replyingText"
91 href="{Config.FRONTEND_URL}/profile/{post.replyingUri.repo}/post/{post
92 .replyingUri.rkey}">replying to {post.replyingUri.repo}</a
93 >
94 {/if}
95 {#if post.quotingUri}
96 <a
97 id="quotingText"
98 href="{Config.FRONTEND_URL}/profile/{post.quotingUri.repo}/post/{post
99 .quotingUri.rkey}">quoting {post.quotingUri.repo}</a
100 >
101 {/if}
102 <div id="postText">{post.text}</div>
103 {#if post.imagesCid && post.imagesCid.length > 0}
104 <div id="carouselContainer">
105 <img
106 id="embedImages"
107 alt="Post Image {currentImageIndex + 1} of {post.imagesCid.length}"
108 src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post
109 .imagesCid[currentImageIndex]}"
110 />
111
112 {#if post.imagesCid.length > 1}
113 <div id="carouselControls">
114 <button
115 id="prevBtn"
116 onclick={prevImage}
117 disabled={currentImageIndex === 0}>←</button
118 >
119 <div id="carouselIndicators">
120 {#each post.imagesCid as _, i}
121 <div
122 class="indicator {i === currentImageIndex ? 'active' : ''}"
123 ></div>
124 {/each}
125 </div>
126 <button
127 id="nextBtn"
128 onclick={nextImage}
129 disabled={currentImageIndex === post.imagesCid.length - 1}
130 >→</button
131 >
132 </div>
133 {/if}
134 </div>
135 {/if}
136 {#if post.videosLinkCid}
137 <!-- svelte-ignore a11y_media_has_caption -->
138 <video
139 id="embedVideo"
140 src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post.videosLinkCid}"
141 controls
142 ></video>
143 {/if}
144 {#if post.gifLink}
145 <img
146 id="embedVideo"
147 src="{post.gifLink}"
148 alt="Post GIF"
149 />
150 {/if}
151 </div>
152</div>
153
154<style>
155
156</style>