Files
Overheard/src/routes/+page.svelte
2026-06-10 12:55:45 +09:00

131 lines
3.3 KiB
Svelte

<script>
import { onMount } from 'svelte';
import MapView from '$lib/components/MapView.svelte';
import { getNearbyMessages } from '$lib/firebase/messages.js';
import { messagesStore } from '$lib/stores/messagesStore.js';
import { mapStore } from '$lib/stores/mapStore.js';
import BottomSheet from '$lib/components/BottomSheet.svelte';
import SidePanel from '$lib/components/SidePanel.svelte';
import ComposeSheet from '$lib/components/ComposeSheet.svelte';
let lat = $state();
let lng = $state();
let error = $state();
let windowWidth = $state(0);
let isMobile = $derived(windowWidth < 768);
onMount(() => {
if (!navigator.geolocation) {
error = "Your browser doesn't support geolocation :(";
return; // do nothing
}
navigator.geolocation.getCurrentPosition(
(position) => {
lat = position.coords.latitude;
lng = position.coords.longitude;
},
() => {
error = "Location access denied. Please enable location to use Overheard.";
}
);
// populate the messages store
navigator.geolocation.getCurrentPosition(
async (position) => {
const messages = await getNearbyMessages(position.coords.latitude, position.coords.longitude);
messagesStore.set(messages);
console.log('messages loaded:', $messagesStore);
}
);
});
</script>
<svelte:window bind:innerWidth={windowWidth} /> <!--this sends the windowWidth to our mobile checker -->
{#if error}
<p class="error">{error}</p>
{:else if lat && lng}
<MapView {lat} {lng} />
{:else}
<p class="loading">Looking for you...</p>
{/if}
<!-- map must fill the whole screen-->
{#if lat && lng}
<MapView {lat} {lng} />
{/if}
<!-- show the right panel based on mobile or desktop-->
{#if windowWidth < 768}
<BottomSheet message={$mapStore.selectedMessage} />
{:else}
<SidePanel message={$mapStore.selectedMessage} />
{/if}
<!--floating action button for adding a message-->
{#if !$mapStore.composing}
<button
class="fab"
class:shifted={isMobile && $mapStore.selectedMessage}
onclick={() => mapStore.set(
{selectedMessage: null, composing: true })}>
+
</button>
{/if}
<!--compose sheet (making a message)-->
{#if $mapStore.composing}
<ComposeSheet {lat} {lng} />
{/if}
<style>
:global(body) {
margin: 0;
padding: 0;
overflow: hidden;
}
.error, .loading {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
font-family: Georgia, 'Times New Roman', Times, serif;
color: #666;
}
.fab {
position: fixed;
bottom: 2rem;
right: 1.5rem;
width: 56px;
height: 56px;
border-radius: 50%;
background: #111;
color: white;
font-size: 1.8rem;
border: none;
cursor: pointer;
box-shadow: 0 4px 16px rgba(0,0,0,0.25);
z-index: 150;
display: flex;
align-items:center;
justify-content: center;
line-height: 1;
transition: bottom 0.35s cubic-bezier(0.32, 0.72, 0, 1); /* match the sheet's slide timing */
}
/* lift it above the bottom sheet so it doesn't get covered, x position stays the same */
.fab.shifted {
bottom: 35vh;
}
</style>