initial commit

This commit is contained in:
Moon.eth
2026-07-29 09:16:38 +09:00
commit 586b599d4c
67 changed files with 9906 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
<script lang="ts">
/**
* Media on a status.
*
* Sensitive media is blurred rather than hidden so the layout doesn't jump
* when it's revealed, and the reveal is per-attachment because a single post
* can mix flagged and unflagged media.
*/
import type { MediaAttachment } from '$lib/api/types'
interface Props {
attachments: MediaAttachment[]
sensitive?: boolean
}
let { attachments, sensitive = false }: Props = $props()
let revealed = $state<Record<string, boolean>>({})
function isRevealed(id: string): boolean {
return !sensitive || revealed[id] === true
}
function toggle(id: string): void {
revealed = { ...revealed, [id]: !revealed[id] }
}
</script>
{#if attachments.length > 0}
<ul class="attachment-list">
{#each attachments as media (media.id)}
<li
class="attachment"
data-type={media.type}
data-sensitive={sensitive ? 'true' : 'false'}
data-revealed={isRevealed(media.id) ? 'true' : 'false'}
>
<figure class="attachment-figure">
{#if media.type === 'video' || media.type === 'gifv'}
<video
class="attachment-media"
src={media.url}
poster={media.preview_url ?? undefined}
controls
playsinline
loop={media.type === 'gifv'}
preload="none"
>
<!-- Remote media carries no caption track; declared so the
requirement is explicit rather than merely unmet. -->
<track kind="captions" />
</video>
{:else if media.type === 'audio'}
<audio class="attachment-media attachment-media--audio" src={media.url} controls preload="none"
></audio>
{:else if media.type === 'image'}
<a href={media.url} target="_blank" rel="noopener noreferrer">
<img
class="attachment-media"
src={media.preview_url ?? media.url}
alt={media.description ?? ''}
loading="lazy"
decoding="async"
/>
</a>
{:else}
<a class="attachment-media attachment-media--file" href={media.url} target="_blank" rel="noopener noreferrer">
Attachment
</a>
{/if}
{#if media.description}
<figcaption class="attachment-caption">{media.description}</figcaption>
{/if}
</figure>
{#if sensitive}
<button type="button" class="button button--small attachment-reveal" onclick={() => toggle(media.id)}>
{isRevealed(media.id) ? 'Hide' : 'Show'} sensitive media
</button>
{/if}
</li>
{/each}
</ul>
{/if}