"Final-ish" design
This commit is contained in:
parent
037dea4e40
commit
ebca274e5a
5 changed files with 202 additions and 33 deletions
|
@ -1,7 +1,58 @@
|
|||
<script lang="ts">
|
||||
import { Post } from "./pdsfetch";
|
||||
import { Config } from "../../config";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let { post }: { post: Post } = $props();
|
||||
|
||||
// State for image carousel
|
||||
let currentImageIndex = $state(0);
|
||||
|
||||
// Functions to navigate carousel
|
||||
function nextImage() {
|
||||
if (post.imagesCid && currentImageIndex < post.imagesCid.length - 1) {
|
||||
currentImageIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
function prevImage() {
|
||||
if (currentImageIndex > 0) {
|
||||
currentImageIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to preload an image
|
||||
function preloadImage(index: number): void {
|
||||
if (!post.imagesCid || index < 0 || index >= post.imagesCid.length) return;
|
||||
|
||||
const img = new Image();
|
||||
img.src = `${Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did=${post.authorDid}&cid=${post.imagesCid[index]}`;
|
||||
}
|
||||
|
||||
// Preload adjacent images when current index changes
|
||||
$effect(() => {
|
||||
if (post.imagesCid && post.imagesCid.length > 1) {
|
||||
// Preload next image if available
|
||||
if (currentImageIndex < post.imagesCid.length - 1) {
|
||||
preloadImage(currentImageIndex + 1);
|
||||
}
|
||||
|
||||
// Preload previous image if available
|
||||
if (currentImageIndex > 0) {
|
||||
preloadImage(currentImageIndex - 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Initial preload of images
|
||||
onMount(() => {
|
||||
if (post.imagesCid && post.imagesCid.length > 1) {
|
||||
// Preload the next image if it exists
|
||||
if (post.imagesCid.length > 1) {
|
||||
preloadImage(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="postContainer">
|
||||
|
@ -14,24 +65,30 @@
|
|||
/>
|
||||
{/if}
|
||||
<div id="headerText">
|
||||
<a href="{Config.FRONTEND_URL}/profile/{post.authorDid}"
|
||||
>{post.displayName} ( {post.authorHandle} )</a
|
||||
>
|
||||
|
|
||||
<a href="{Config.FRONTEND_URL}/profile/{post.authorDid}/post/{post.cid}"
|
||||
>{post.timenotstamp}</a
|
||||
<a id="displayName" href="{Config.FRONTEND_URL}/profile/{post.authorDid}"
|
||||
>{post.displayName}</a
|
||||
>
|
||||
<p id="handle">
|
||||
<a href="{Config.FRONTEND_URL}/profile/{post.authorHandle}"
|
||||
>{post.authorHandle}</a
|
||||
>
|
||||
|
||||
<a
|
||||
id="postLink"
|
||||
href="{Config.FRONTEND_URL}/profile/{post.authorDid}/post/{post.recordName}"
|
||||
>{post.timenotstamp}</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postContent">
|
||||
{#if post.replyingUri}
|
||||
<a
|
||||
id="replyingText"
|
||||
href="{Config.FRONTEND_URL}/profile/{post.replyingUri.repo}/post/{post
|
||||
.replyingUri.rkey}">replying to {post.replyingUri.repo}</a
|
||||
>
|
||||
<a
|
||||
id="replyingText"
|
||||
href="{Config.FRONTEND_URL}/profile/{post.replyingUri.repo}/post/{post
|
||||
.replyingUri.rkey}">replying to {post.replyingUri.repo}</a
|
||||
>
|
||||
{/if}
|
||||
<div id="postText">{post.text}</div>
|
||||
{#if post.quotingUri}
|
||||
<a
|
||||
id="quotingText"
|
||||
|
@ -39,27 +96,54 @@
|
|||
.quotingUri.rkey}">quoting {post.quotingUri.repo}</a
|
||||
>
|
||||
{/if}
|
||||
{#if post.imagesCid}
|
||||
<div id="imagesContainer">
|
||||
{#each post.imagesCid as imageLink}
|
||||
<img
|
||||
id="embedImages"
|
||||
alt="Post Image"
|
||||
src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={imageLink}"
|
||||
/>
|
||||
{/each}
|
||||
<div id="postText">{post.text}</div>
|
||||
{#if post.imagesCid && post.imagesCid.length > 0}
|
||||
<div id="carouselContainer">
|
||||
<img
|
||||
id="embedImages"
|
||||
alt="Post Image {currentImageIndex + 1} of {post.imagesCid.length}"
|
||||
src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post
|
||||
.imagesCid[currentImageIndex]}"
|
||||
/>
|
||||
|
||||
{#if post.imagesCid.length > 1}
|
||||
<div id="carouselControls">
|
||||
<button
|
||||
id="prevBtn"
|
||||
on:click={prevImage}
|
||||
disabled={currentImageIndex === 0}>←</button
|
||||
>
|
||||
<div id="carouselIndicators">
|
||||
{#each post.imagesCid as _, i}
|
||||
<div
|
||||
class="indicator {i === currentImageIndex ? 'active' : ''}"
|
||||
></div>
|
||||
{/each}
|
||||
</div>
|
||||
<button
|
||||
id="nextBtn"
|
||||
on:click={nextImage}
|
||||
disabled={currentImageIndex === post.imagesCid.length - 1}
|
||||
>→</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if post.videosLinkCid}
|
||||
<video
|
||||
id="embedVideo"
|
||||
src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post.videosLinkCid}"
|
||||
/>
|
||||
controls
|
||||
></video>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#postContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -79,6 +163,26 @@
|
|||
border-bottom: 1px solid #8054f0;
|
||||
font-weight: bold;
|
||||
overflow-wrap: break-word;
|
||||
height: 60px;
|
||||
}
|
||||
#displayName {
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#handle {
|
||||
color: #8054f0;
|
||||
font-size: 0.8em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#postLink {
|
||||
color: #8054f0;
|
||||
font-size: 0.8em;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#postContent {
|
||||
display: flex;
|
||||
|
@ -95,9 +199,14 @@
|
|||
padding: 0;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
#quotingText {
|
||||
font-size: 0.7em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
#postText {
|
||||
margin: 0;
|
||||
margin-bottom: 5px;
|
||||
padding: 0;
|
||||
}
|
||||
#headerText {
|
||||
|
@ -108,20 +217,68 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
#avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
margin-left: 0px;
|
||||
border-right: #8054f0 1px solid;
|
||||
}
|
||||
#embedImages {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
margin-top: 0px;
|
||||
margin-bottom: -5px;
|
||||
min-width: 500px;
|
||||
max-width: 500px;
|
||||
max-height: 500px;
|
||||
object-fit: contain;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
#carouselContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
#carouselControls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
#carouselIndicators {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
.indicator.active {
|
||||
background-color: #8054f0;
|
||||
}
|
||||
#prevBtn,
|
||||
#nextBtn {
|
||||
background-color: rgba(31, 17, 69, 0.7);
|
||||
color: white;
|
||||
border: 1px solid #8054f0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
#prevBtn:disabled,
|
||||
#nextBtn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
#embedVideo {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin-top: 10px;
|
||||
align-self: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -32,6 +32,7 @@ class Post {
|
|||
authorDid: string;
|
||||
authorAvatarCid: string | null;
|
||||
postCid: string;
|
||||
recordName: string;
|
||||
authorHandle: string;
|
||||
displayName: string;
|
||||
text: string;
|
||||
|
@ -47,6 +48,7 @@ class Post {
|
|||
account: AccountMetadata,
|
||||
) {
|
||||
this.postCid = record.cid;
|
||||
this.recordName = record.uri.split("/").slice(-1)[0];
|
||||
this.authorDid = account.did;
|
||||
this.authorAvatarCid = account.avatarCid;
|
||||
this.authorHandle = account.handle;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue