Presently is a camera-first AT Protocol client for sharing a photo as a
24-hour story that Flashes can display. The MVP intentionally has no feed: it
opens to the camera, captures one JPEG, optionally saves it to the device photo
library, and publishes a blue.flashes.story.post record.
apps/
android/ Jetpack Compose, CameraX, and Room
ios/ SwiftUI, AVFoundation, and SwiftData
web/ Astro marketing, privacy, terms, and support site
services/
oauth-worker/ Go ATProto OAuth metadata service for Vercel containers
docs/
MVP_PLAN.md Delivery plan, boundaries, and acceptance criteria
STORY_CONTRACT.md Published Flashes record contract used by both clients
- Both clients implement the camera/review interaction, friendly account typeahead, native OAuth/DPoP session handling, and durable local story drafts.
- Both clients model the exact current Flashes story record.
- The Go OAuth service serves native public-client metadata with the minimum create-only Flashes actor, story, and JPEG blob permissions.
- Both apps implement JPEG blob upload and
blue.flashes.story.postcreation. Login idempotently provisionsblue.flashes.actor.profile/selfwhen the account does not already have one, and failed story drafts retain their record key for safe retries. - On iOS 18 and later, Presently provides a Camera Control zoom/camera picker, a locked capture extension, and an Open Presently Camera control for Control Center and the Lock Screen. The user can select that control as the Camera Control or Action button launch action in system settings.
- On Android 7 and later, Presently provides an “Open Presently Camera” Quick Settings tile. Android does not expose Apple Camera Control or Lock Screen control extensions; the launcher and Quick Settings tile open the same camera-first experience instead.
cd apps/ios
xcodegen generate
DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer \
xcodebuild -project Presently.xcodeproj \
-scheme Presently \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' testThe simulator cannot provide a live camera. Run on a physical device to verify capture and photo-library saving.
cd apps/android
./gradlew testDebugUnitTest assembleDebug lintDebugcd services/oauth-worker
go test ./...
go build ./...
docker build -f Dockerfile.vercel .The stable production client ID is
https://oauth.presently.photo/oauth/client-metadata.json, with native callback
photo.presently.oauth:/oauth/callback. Configure the production environment
from services/oauth-worker/.env.example. Vercel detects the root
vercel.json Services configuration and builds the OAuth worker independently
from services/oauth-worker/Dockerfile.vercel. Requests for
oauth.presently.photo route to this service.
cd apps/web
npm install
npm run check
npm run buildThe root Vercel Services configuration builds the Astro site independently and
routes non-OAuth domains, including presently.photo, to the web service.
Pushes to main deploy both services through the project's Vercel Git
integration.