From 15be996704a07874bbeb3e0539e2eef17199eb21 Mon Sep 17 00:00:00 2001 From: Park Jisu Date: Sat, 6 Jun 2026 16:45:33 +0900 Subject: [PATCH 1/2] first : correct a typo(filename) --- src/lib/components/SidePanel.svelte | 2 +- src/routes/+page.svelte | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/lib/components/SidePanel.svelte b/src/lib/components/SidePanel.svelte index e432286..0fae3ec 100644 --- a/src/lib/components/SidePanel.svelte +++ b/src/lib/components/SidePanel.svelte @@ -72,7 +72,7 @@ .letgo-button { flex: 1; - padding: 0..75rem; + padding: 0.75rem; background: transparent; color: #111; border: 1.5px solid #ddd; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9635369..6e9b92c 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -54,11 +54,6 @@

Looking for you...

{/if} - - {#if lat && lng} - -{/if} - {#if windowWidth < 768} -- 2.43.0 From 2b4a005407719dda22d75a5198796970354afda1 Mon Sep 17 00:00:00 2001 From: Park Jisu Date: Mon, 8 Jun 2026 16:23:24 +0900 Subject: [PATCH 2/2] second: open camera --- src/lib/Firebase/config.js | 79 +++++++---- src/lib/Firebase/messages.js | 32 +++-- src/lib/components/ARComposePanel.svelte | 0 src/lib/components/ARGuideOverlay.svelte | 0 src/lib/components/ARMessageMarker.svelte | 0 src/lib/components/ARView.svelte | 165 ++++++++++++++++++++++ src/lib/components/MapView.Svelte | 21 +++ src/lib/stores/arStore.js | 9 ++ src/routes/+page.svelte | 100 ++++++++++--- 9 files changed, 352 insertions(+), 54 deletions(-) create mode 100644 src/lib/components/ARComposePanel.svelte create mode 100644 src/lib/components/ARGuideOverlay.svelte create mode 100644 src/lib/components/ARMessageMarker.svelte create mode 100644 src/lib/components/ARView.svelte create mode 100644 src/lib/stores/arStore.js diff --git a/src/lib/Firebase/config.js b/src/lib/Firebase/config.js index 02b2c04..c9a11c7 100644 --- a/src/lib/Firebase/config.js +++ b/src/lib/Firebase/config.js @@ -1,28 +1,59 @@ - -// we get all our firebase config from the .env file, not included in the repo, so we don't share our API keys. -// then we initialize the app and export the database and storage so we can use them in other files - -import { initializeApp } from 'firebase/app'; +import { browser } from '$app/environment'; +import { initializeApp, getApps } from 'firebase/app'; import { getFirestore } from 'firebase/firestore'; import { getStorage } from 'firebase/storage'; -import { - PUBLIC_FIREBASE_API_KEY, - PUBLIC_FIREBASE_AUTH_DOMAIN, - PUBLIC_FIREBASE_PROJECT_ID, - PUBLIC_FIREBASE_STORAGE_BUCKET, - PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - PUBLIC_FIREBASE_APP_ID -} from '$env/static/public'; +import { env } from '$env/dynamic/public'; -const firebaseConfig = { - apiKey: PUBLIC_FIREBASE_API_KEY, - authDomain: PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: PUBLIC_FIREBASE_APP_ID -}; +/** Firebase 환경 변수가 모두 설정됐는지 확인 */ +export function isFirebaseConfigured() { + return Boolean( + env.PUBLIC_FIREBASE_API_KEY && + env.PUBLIC_FIREBASE_AUTH_DOMAIN && + env.PUBLIC_FIREBASE_PROJECT_ID && + env.PUBLIC_FIREBASE_STORAGE_BUCKET && + env.PUBLIC_FIREBASE_MESSAGING_SENDER_ID && + env.PUBLIC_FIREBASE_APP_ID + ); +} -const app = initializeApp(firebaseConfig); -export const db = getFirestore(app); -export const storage = getStorage(app); \ No newline at end of file +function getFirebaseConfig() { + return { + apiKey: env.PUBLIC_FIREBASE_API_KEY, + authDomain: env.PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: env.PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: env.PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: env.PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: env.PUBLIC_FIREBASE_APP_ID + }; +} + +let app; +let db; +let storage; + +/** Firebase 앱을 지연 초기화하고 Firestore 인스턴스를 반환 */ +export function getDb() { + if (!browser) { + throw new Error('Firestore는 브라우저에서만 사용할 수 있습니다.'); + } + + if (!isFirebaseConfigured()) { + throw new Error( + 'Firebase 환경 변수가 설정되지 않았습니다. .env.example을 참고해 .env 파일을 만드세요.' + ); + } + + if (!app) { + app = getApps().length ? getApps()[0] : initializeApp(getFirebaseConfig()); + db = getFirestore(app); + storage = getStorage(app); + } + + return db; +} + +/** Firebase Storage 인스턴스 반환 */ +export function getStorageInstance() { + getDb(); + return storage; +} diff --git a/src/lib/Firebase/messages.js b/src/lib/Firebase/messages.js index b216022..6bd546e 100644 --- a/src/lib/Firebase/messages.js +++ b/src/lib/Firebase/messages.js @@ -1,16 +1,24 @@ -import { collection, query, where, getDocs } from 'firebase/firestore'; // tools for building and running db queries -import { db } from './config'; // database connection -import { getQueryPrefix } from '$lib/utils/geohash'; // convert coordinates into geohash string +import { collection, query, where, getDocs } from 'firebase/firestore'; +import { getDb, isFirebaseConfigured } from './config.js'; +import { getQueryPrefix } from '$lib/utils/geohash.js'; export async function getNearbyMessages(lat, lng) { - const prefix = getQueryPrefix(lat, lng); + if (!isFirebaseConfigured()) { + console.warn( + 'Firebase가 설정되지 않아 메시지를 불러오지 못했습니다. 프로젝트 루트에 .env 파일을 추가하세요.' + ); + return []; + } - const q = query( - collection(db, 'messages'), - where('geohash', '>=', prefix), - where('geohash', '<', prefix + 'z') - ); + const prefix = getQueryPrefix(lat, lng); + const db = getDb(); - const snapshot = await getDocs(q); - return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); -} \ No newline at end of file + const q = query( + collection(db, 'messages'), + where('geohash', '>=', prefix), + where('geohash', '<', prefix + 'z') + ); + + const snapshot = await getDocs(q); + return snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() })); +} diff --git a/src/lib/components/ARComposePanel.svelte b/src/lib/components/ARComposePanel.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/ARGuideOverlay.svelte b/src/lib/components/ARGuideOverlay.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/ARMessageMarker.svelte b/src/lib/components/ARMessageMarker.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/ARView.svelte b/src/lib/components/ARView.svelte new file mode 100644 index 0000000..d67ba40 --- /dev/null +++ b/src/lib/components/ARView.svelte @@ -0,0 +1,165 @@ + + +
+ + +
+ + + {#if cameraError} +
+

{cameraError}

+

Please check camera permission in your browser.

+
+ {:else} +
+

AR Mode

+

Move your camera slowly.

+
+ {/if} +
+
+ + \ No newline at end of file diff --git a/src/lib/components/MapView.Svelte b/src/lib/components/MapView.Svelte index 837cf87..d252a65 100644 --- a/src/lib/components/MapView.Svelte +++ b/src/lib/components/MapView.Svelte @@ -10,9 +10,28 @@ let { lat, lng } = $props(); let mapDiv; + let userMarker = null; let markers = []; // keep track of pins on map + /** 내 위치 마커 (메시지 핀과 구분되는 파란 점) */ + function addUserLocationMarker(map, centerLat, centerLng) { + userMarker = new google.maps.Marker({ + position: { lat: centerLat, lng: centerLng }, + map, + title: 'Your location', + zIndex: 1000, + icon: { + path: google.maps.SymbolPath.CIRCLE, + scale: 10, + fillColor: '#4285F4', + fillOpacity: 1, + strokeColor: '#ffffff', + strokeWeight: 3 + } + }); + } + onMount (async () => { const centerLat = Number(lat); const centerLng = Number(lng); @@ -31,6 +50,8 @@ disableDefaultUI: true, gestureHandling: 'greedy' }); + + addUserLocationMarker(mapDiv, centerLat, centerLng); }); // function to rended pins diff --git a/src/lib/stores/arStore.js b/src/lib/stores/arStore.js new file mode 100644 index 0000000..817d01d --- /dev/null +++ b/src/lib/stores/arStore.js @@ -0,0 +1,9 @@ +import { writable } from 'svelte/store'; + +export const arStore = writable({ + isARMode: false, + currentHeading: null, + selectedScreenPoint: null, + composing: false, + focusedMessage: null +}); \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 6e9b92c..ec2be9e 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,10 +1,13 @@