尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A retro AIM-style messaging app built with Vite + React Router + Supabase, mobile-first, with persistent room sessions, unread tracking, global realtime notifications, and a Capacitor iOS wrapper. Android support was removed in #147.檢視完整 README ↗A retro AIM-style messaging app built with Vite + React Router + Supabase, mobile-first, with persistent room sessions, unread tracking, global realtime notifications, and a Capacitor iOS wrapper. Android support was removed in #147.
main: marketing version 2.7 (#185). CURRENT_PROJECT_VERSION is 465, but Xcode Cloud assigns the real build number. 2.7 build 472 is in internal TestFlight, and the next 2.7 archive must be above 466./reset-password. The old recovery-code and admin reset-ticket flow was removed in April 2026.public.buddies is the one graph. Search, suggestions, and profile Add Buddy all write it (#178).rooms, room_memberships, room_messages) with persistent membership. The room unread counter was removed in #181 because it never incremented. Room invites need an accepted buddy, and there are no shareable invite links.user_dm_state) for multi-device consistency.chat-media).hiitsme:outbox:v1:<userId>) retries queued DM and room sends with backoff, deduped by client_msg_id.H.I.M. intentionally does not treat direct messages and rooms as the same product surface. The current v1 policy is:
| Capability | DMs | Rooms | Decision |
|---|---|---|---|
| Soft edit / delete | Yes | Yes | Keep parity. Core message hygiene belongs in both surfaces. |
| Emoji reactions | Yes | Yes | Keep parity. Reactions are now wired end to end in both DM and room chat. |
| Attachments / media | Yes | Yes | Keep parity at the file/media layer. |
| Inline search | Yes | Yes | Keep parity. Search is table stakes in both surfaces. |
| Presence / membership context | Buddy presence | Room participant presence | Different on purpose. DMs are relationship-first; rooms are audience-first. |
| Read receipts | Yes | No | Rooms do not expose per-user read state in v1. Too noisy and socially heavy for shared threads. |
| Delivery tracking | Yes | No | Rooms do not model message delivery state per participant in v1. |
| Forwarding | Yes | No | Forwarding remains DM-only in v1 until room moderation/distribution rules are defined. |
Disappearing messages (expires_at) | Yes | No | Ephemeral expiry is a private-conversation feature in v1, not a shared-room behavior. |
| Voice note preview type | Yes | No | DMs keep the richer voice-note metadata path; rooms stay on the simpler shared attachment model in v1. |
This is a product decision, not an unfinished parity backlog. If a room feature is not listed as supported above, assume it is intentionally out of scope until the room model is explicitly expanded.
@capacitor/core, @capacitor/ios) — iOS only; android/ was removed in #147api/ functions(The repo was migrated off Next.js in commit 5ec1d04. Folder names under src/app/ still mirror the old App Router convention, but they're plain React components wired into src/App.tsx via react-router-dom.)
/ — logged-out web porch; native / is still Sign in. ?signin=1 and /signin keep LoginPage./signin — password sign-on + account creation/reset-password — password reset/hi-its-me — main app: buddies, DM windows, room windows, settings/hi-its-me/rooms, /hi-its-me/rooms/new, /hi-its-me/rooms/:roomId/preview — room list / create / invite preview/join/:inviteCode — room invite accept/account — email, password, push permission, notification preview, data export, legal links/account/delete — two-step account erasurehiitsme.app/privacy, /terms, /support (public/{privacy,terms,support}.html)/api/admin/meCopy .env.example to .env.local, then fill in values:
cp .env.example .env.local
.env.local should contain:
# Client-side (read via import.meta.env after the Vite migration)
VITE_SUPABASE_URL=...
VITE_SUPABASE_ANON_KEY=...
# Server-side only (Vercel Functions, Edge Functions, admin tooling)
SUPABASE_SERVICE_ROLE_KEY=...
# Native bundles hitting the hosted API origin (var name kept for backward compat)
NEXT_PUBLIC_APP_API_ORIGIN=...
Optional E2E (Playwright) env vars for seeded test users:
PLAYWRIGHT_USER_A_SCREENNAME=...
PLAYWRIGHT_USER_A_PASSWORD=...
PLAYWRIGHT_USER_B_SCREENNAME=...
PLAYWRIGHT_USER_B_PASSWORD=...
Notes:
SUPABASE_SERVICE_ROLE_KEY is required for server-side recovery/admin routes.npm install would write a
second lockfile that resolves differently, so CI rejects it):pnpm install
supabase/migrations/ (canonical CLI-managed history; the readable snapshots in supabase/*.sql are not the live schema). Rooms v2, push fan-out, exclusive device tokens, and push_dispatch_log all live later in that directory than the early 2026 numbered files.If the remote project already has these schema changes and you are adopting Supabase CLI after the fact, mark already-applied versions with supabase migration repair --status applied <version> rather than replaying them. Then:
supabase login
supabase migration list
insert into public.admin_users (user_id, screenname)
select id, screenname
from public.users
where lower(screenname) = 'pakiboy24'
on conflict (user_id) do nothing;
npm run dev
Capacitor has already been initialized. The committed native project is iOS only:
ios/capacitor.config.tsThe android/ tree was deleted in #147. The android:* npm scripts are gone with it.
Current config defaults to bundled native web assets:
webDir = native-webCAPACITOR_HOSTED=1CAPACITOR_SERVER_URL=https://your-domainOn iOS the React app owns every pixel. A web UI change reaches the phone only after npm run build && npm run ios:sync and a commit of dist/ + ios/App/App/public. Never npx cap copy ios — it drops HiItsMeShellPlugin. Details: IOS_APP_STORE_RELEASE.md.
Useful commands:
# sync bundled native assets + iOS project
npm run ios:sync
# optional hosted-mode sync for debugging only
npm run ios:sync:hosted
# open Xcode
npm run ios:open
Current native-host behavior:
CFBundleVersion so a reinstall cannot keep a stale service workeroverscroll-behavior-y: none)maximum-scale=1, user-scalable=0)-webkit-touch-callout: none)capacitor.config.tspush-dispatch Edge Function). See docs/push-dispatch.md.Supabase auth sits behind the screen name:
public.users, then falls back to synthetic ${screenname}@hiitsme.app and legacy ${screenname}@buddylist.compublic.usersRecovery model:
resetPasswordForEmail) to the account's real email@hiitsme.app, @buddylist.com) cannot receive that mailHIM://reset-password; web redirect is https://hiitsme-app.vercel.app/reset-password20260426083107_drop_password_recovery.sql)active_chat_room:${roomId}GlobalNotificationListener.global_notifications_messages (DMs)global_notifications_room_messages (room messages)?dm=<senderId>?room=<roomName>push-dispatch after a send; server-side inserts (engine DMs, room prompts, buddy requests) are announced by a Postgres trigger. Outcomes land in push_dispatch_log. See docs/push-dispatch.md.public.rooms + public.room_memberships (unread via last_seen_at). The rooms-v1 table user_active_rooms is archived (_archive_user_active_rooms).room_memberships.ChatContext) upserts/deletes room_memberships directly.join_room_by_id / leave_room_by_id.src/context/ChatContext.tsx - persistent room state + unread logicsrc/components/GlobalNotificationListener.tsx - app-wide notificationssrc/components/GroupChatWindow.tsx - room UI + presencesrc/components/ChatWindow.tsx - DM UI (mobile-first dense log + collapsible formatting)src/components/IncomingMessageBanner.tsx - mobile-style notification bannersrc/components/RetroWindow.tsx - top-level mobile window shell + centered glossy titlebarsrc/app/hi-its-me/page.tsx - H.I.M. contacts, DM windows, room controlssrc/lib/clientStorage.ts - safe typed local persistence with versioned envelopessrc/lib/chatMedia.ts - attachment validation + Supabase Storage upload helperssrc/lib/outbox.ts - offline outbox queue schema + retry metadatasrc/lib/roomName.ts - shared room normalization helperscapacitor.config.ts - iOS wrapper configurationsrc/lib/pushDispatch.ts - client fan-out into the push-dispatch Edge Functionsrc/lib/pushPromptMoments.ts - contextual iOS permission prompt after friendship actionssupabase/functions/push-dispatch/index.ts - APNs delivery + push_dispatch_lognpm run lint
npm run build
npm run test:unit
npm run test:e2e
npm run ios:preflight
Can't resolve 'tailwindcss' in '/Users/...Usually means npm run dev was started from the wrong directory. Run from repo root:
cd /path/to/buddylist-app
pnpm install
pnpm run dev
The phone does not load hiitsme.app in bundled mode. Rebuild and sync:
npm run build
npm run ios:sync
Then commit dist/ and ios/App/App/public. If a reinstall still looks stale, confirm CFBundleVersion changed — AppDelegate only clears WKWebView site data when the build number changes.
Two different failures look the same from the sender's side:
push_dispatch_log shows recipients > 0 AND tokens = 0. Nobody on that account ever registered.Full runbook: docs/push-dispatch.md.
npx cap copy ios dropped HiItsMeShellPluginUse npm run ios:sync (or pnpm run ios:sync). Never hand-edit CapApp-SPM/Package.swift.
NEXT_PUBLIC_APP_API_ORIGIN too if native builds should target a different backend origin than the default production web domain.CAPACITOR_SERVER_URL aligned with your intended domain.