尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Branded client photo and video galleries backed by Google Drive
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A branded, mobile-first client gallery for photos and video. You drop files into a Google Drive folder; the site picks them up automatically.查看完整 README ↗A branded, mobile-first client gallery for photos and video. You drop files into a Google Drive folder; the site picks them up automatically.
Full-screen cover, justified photo grid, dark/light mode
Lightbox with swipe, pinch-zoom, double-tap zoom, swipe-down to close, keyboard arrows
Videos stream from Drive with seeking (HTTP range requests), shown with a poster frame and duration
Clients heart favorites, add notes per photo or clip, and send their picks → rows land in a Google Sheet (+ optional email)
Per-gallery password, per-file download, and "Download all" as a .zip (everything / photos / films)
Files stay private in Drive — nothing needs to be shared publicly
Owner dashboard at /admin: sign in with Google, create galleries, drag in photos and films (they upload straight into your Drive), set passwords, pick the cover, copy the client invite
Every gallery link ends in a private code (e.g. /g/lakeshore-brand-film-3fa9c2), so clients can only reach their own gallery
It runs in demo mode with sample media until you add Google credentials, so you can try it first.
npm install
npm run dev # http://localhost:3000
CLIENTS/ ← created by the dashboard; nothing outside it is touched
├── Lakeshore CU — Brand Film/ → yoursite.com/g/lakeshore-cu-brand-film-3fa9c2
│ ├── gallery.json (optional settings)
│ ├── cover.jpg (optional hero image, hidden from grid)
│ ├── 01 Hero cut.mp4
│ ├── 02 Social 9x16.mp4
│ └── stills-001.jpg …
├── Fall Leadership Conference/
└── _Work in progress/ ← folders starting with _ stay hidden
drive.file permission, so it can only see and change the folders and files it created — never the rest of your Drive._ or . are skipped.cover.* file? The first photo is used.CACHE_SECONDS (default 60s).gallery.json (all fields optional){
"client": "Lakeshore Credit Union",
"date": "2026-09-18",
"message": "Final cuts and stills from the shoot. Heart anything you'd like to use.",
"password": "lakeshore26",
"downloads": true,
"cover": "stills-014.jpg"
}
Changing the password signs out anyone who unlocked the old one.
.json file downloads. Keep it private.[email protected]).https://galleries.sowcreativestudios.com/api/auth/callback (and the old https://client-galleries.vercel.app/api/auth/callback) (and http://localhost:3000/api/auth/callback for local testing).The CLIENTS folder is created and shared with the service account automatically the first time you make a gallery in the dashboard.
Time | Gallery | Name | Email | File | Note | Drive link | Messagedocs.google.com/spreadsheets/d/THIS_PART/edit.Copy .env.example to .env.local and fill in:
| Variable | Value |
|---|---|
GOOGLE_SERVICE_ACCOUNT_JSON | Entire contents of the JSON key (or base64 of it) |
GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET | From step 2 |
OWNER_EMAILS | Your Google account, e.g. [email protected] |
SELECTIONS_SHEET_ID | Sheet ID from step 3 |
GALLERY_SECRET | Any long random string |
STUDIO_NAME, STUDIO_TAGLINE, STUDIO_URL, STUDIO_EMAIL | Your branding |
STRIPE_SECRET_KEY | Optional. Restricted Stripe key (Checkout Sessions: Read) for pay-to-unlock |
SITE_URL | The main address, e.g. https://galleries.sowcreativestudios.com (used for sign-in, links, emails, previews) |
SHOW_INDEX | true to list unlocked galleries on the home page (off by default) |
RESEND_API_KEY, NOTIFY_EMAIL | Optional email alert via resend.com instead of Sheets notifications |
galleries.yourdomain.com).Hero — 16x9.mp4, Hero — 9x16.mp4, Hero — 1x1.mp4 and they appear as one film with a format switcher (all formats download from one menu). Drop in Hero.srt (or Hero.en.srt) and it becomes captions for that film.STRIPE_SECRET_KEY with Products: Write, Prices: Write, Payment Links: Write, Checkout Sessions: Read. In a gallery's Payment panel, enter an amount → the app creates the Stripe payment link, puts the gallery on hold and shows clients a “Pay $X” button. After Stripe confirms, the gallery unlocks on its own. From the panel you can copy the link, change the amount (the old link is turned off), cancel the request, or mark it paid if you got a check. The dashboard lists outstanding requests and recent payments.app/g/[slug]/page.tsx gallery page (lock screen or gallery)
app/api/media/[id] resized images and video posters from Drive
app/api/stream/[id] video streaming with range/seek support
app/api/download/[id] single-file download
app/api/zip/[slug] zip of the whole gallery
app/api/unlock password check → signed cookie
app/api/selections client picks → Google Sheet (+ email)
app/admin owner dashboard (gallery list + gallery manager)
app/api/auth/* Google sign-in for the owner
app/api/admin/* create/edit/delete galleries, start uploads, remove files
components/GalleryView.tsx hero, filters, grid, selection bar, send dialog
components/Lightbox.tsx viewer with gestures, notes, downloads
lib/galleries.ts reads folders/files from Drive (and demo data)
Markup is completely separate from delivery galleries. In the dashboard, open Markup → + New review. Each review project is a folder in CLIENTS/_REVIEWS with version subfolders (Version 1, Version 2…).
/review/<project> (or the Review tab on the website): notes pinned to a moment in a film, pins on photos, replies, resolve and Approve./g/…) are for delivery only. When a project is approved, create a delivery gallery and upload the finals there.vercel.json); optionally set CRON_SECRET in Vercel to lock the endpoint.?as=client to a gallery link) to check the password screen, watermarks and expiry.