small fixes, small sound feedback, & opening screen

This commit is contained in:
2026-06-13 16:03:55 +09:00
parent cdbff7a560
commit 5f8d224d84
14 changed files with 1269 additions and 164 deletions

View File

@@ -0,0 +1,169 @@
<script>
// Archive page: lists every message this device (anonymous Firebase UID) has authored
import { onMount } from 'svelte';
import { getMyMessages } from '$lib/firebase/messages.js';
import { getDecayInfo } from '$lib/utils/time.js';
let messages = $state([]);
let loading = $state(true);
onMount(async () => {
messages = await getMyMessages();
loading = false;
});
</script>
<div class="archive">
<div class="archive-header">
<a href="/" class="back">← Back to map</a>
<h1>Your messages</h1>
<p class="subtitle">Everything you've left behind</p>
</div>
{#if loading}
<div class="loading">Loading your messages...</div>
{:else if messages.length === 0}
<div class="empty">
<p>You haven't left any messages yet.</p>
<a href="/" class="go-back">Go leave one →</a>
</div>
{:else}
<div class="list">
{#each messages as msg}
<!-- fade-out timing for this message -->
{@const decay = getDecayInfo(msg.createdAt, msg.lastEchoAt)}
<div class="card" class:faded={decay.isExpired}>
{#if msg.imageUrl}
<img class="card-img" src={msg.imageUrl} alt="message" />
{/if}
<p class="card-text">{msg.text}</p>
<div class="card-meta">
{#if decay.isExpired}
<span class="status faded">🌫️ Faded</span>
{:else}
<span class="status alive">✦ Alive</span>
{/if}
<span></span>
<span>left {decay.daysAgo} days ago</span>
<span></span>
<span>{decay.daysLeft} days left</span>
<span></span>
<span>echoed {msg.echoCount} times</span>
</div>
</div>
{/each}
</div>
{/if}
</div>
<style>
.archive {
max-width: 600px;
margin: 0 auto;
padding: 2rem 1.5rem 4rem;
font-family: sans-serif;
}
.archive-header {
margin-bottom: 2rem;
}
.back {
font-size: 0.85rem;
color: #999;
text-decoration: none;
display: inline-block;
margin-bottom: 1rem;
}
.back:hover { color: #111; }
h1 {
font-size: 1.6rem;
font-weight: 700;
color: #111;
margin-bottom: 0.3rem;
}
.subtitle {
font-size: 0.85rem;
color: #aaa;
}
.loading {
text-align: center;
color: #aaa;
padding: 3rem 0;
font-size: 0.9rem;
}
.empty {
text-align: center;
padding: 3rem 0;
color: #aaa;
}
.go-back {
display: inline-block;
margin-top: 0.75rem;
color: #c4a8f5;
text-decoration: none;
font-size: 0.9rem;
}
.list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.card {
background: white;
border: 1px solid #eee;
border-radius: 14px;
padding: 1.2rem;
transition: opacity 0.2s;
}
.card.faded {
opacity: 0.5;
}
.card-img {
width: 100%;
max-height: 200px;
object-fit: cover;
border-radius: 10px;
margin-bottom: 0.75rem;
}
.card-text {
font-size: 0.95rem;
color: #111;
line-height: 1.6;
margin-bottom: 0.75rem;
}
.card-meta {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
font-size: 0.75rem;
color: #bbb;
align-items: center;
}
.status {
font-weight: 600;
font-size: 0.75rem;
}
.status.alive { color: #c4a8f5; }
.status.faded { color: #ccc; }
</style>