No updates detected yet. GitHub releases will appear here.
A couple website
翻訳待ち
Loading the full README.
Read the full README ↗A private little web app for two people: pairing by code, live chat with reactions, pokes and love notes, couple trivia, daily tasks, one-time photo "snaps", and an installable PWA. No build step — it is a static site backed by Firebase (Auth and Firestore; no Storage bucket or paid plan needed).
| File | What it is |
|---|---|
public/index.html | The whole app (markup, styles and the module script). public/our-little-world.html just redirects here for old links. |
public/service-worker.js, public/manifest.webmanifest, public/icon*.svg/png | PWA: offline shell, install metadata, icons. |
public/fonts/ | Nunito, the rounded typeface, bundled so every phone shows the same font and nothing is loaded from Google. Its SIL Open Font License is Nunito-OFL.txt. |
firestore.rules, firebase.json, .firebaserc | Firestore security rules and CLI config (project aytt-677b4). |
api/couple-portrait.js | Optional Vercel function that draws the AI couple portrait (see below). |
api/notify.js, package.json | Vercel function that sends push notifications to your partner's phone (see below). |
vercel.json, .vercelignore | Security headers and the functions' timeouts for the Vercel deployment; files a command-line deploy must never upload. |
tw-local-app/Start TW.command | Double-click on a Mac to serve public/ on http://localhost:8765. |
cd public && python3 -m http.server 8765 --bind 127.0.0.1
Then open http://localhost:8765. Sign-in and sync talk to the real Firebase project, so use real accounts there.
Only the public/ folder is served as the website (so the rules, Firebase config and helper scripts at the repo root are
never downloadable); api/ holds the serverless functions. It deploys on Vercel (project tw, live at https://our-tw.vercel.app; the older
ay-five-umber.vercel.app address still works too). The security rules are not part of that deploy — publish them
whenever firestore.rules changes (the cycle tracker and account deletion both need the latest ones), either with the Firebase CLI:
firebase deploy --only firestore:rules --project aytt-677b4
or by pasting the file into Firebase console → Firestore Database → Rules and clicking Publish.
Each of you can add a photo from the home screen. With both photos in, the home screen shows a collage of the two of you with your days-together count (from the day you set), free and instant. If you both tick “Let AI use my photo”, either of you can ask for an AI-drawn couple portrait instead.
The AI drawing runs through api/couple-portrait.js, which calls Google's Gemini image model. To switch it on:
GEMINI_API_KEY with that key, then redeploy.GEMINI_IMAGE_MODEL to use a different image model (default gemini-2.5-flash-image).Until the key exists the function answers “not configured” and the app keeps the collage. The function only accepts signed-in TW users (it checks their Firebase ID token), allows one portrait per person per minute, and never stores the photos.
Messages, pokes, notes, snaps, surprises, bouquets and tasks reach your partner's phone as real notifications, even when
TW is closed. Each phone saves its push address under couples/{id}/push (turn it on in Settings → Notifications), and
api/notify.js sends the push through the browser's push service using Web Push (VAPID). To switch it on:
npx web-push generate-vapid-keys. The public key is already in index.html
(VAPID_PUBLIC_KEY); if you make new keys, replace it there.VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY and, optionally, VAPID_SUBJECT
(for example mailto:[email protected]), then redeploy. Keep the private key out of the repo.firestore.rules (they now include the push collection).The function only accepts signed-in TW users (it checks their Firebase ID token), reads the couple and devices using that user's own token so the security rules apply, and answers “not configured” until the keys exist, in which case TW keeps using in-app alerts only.
This is the beginning of the README. Read the rest at the original. Read the full README ↗