mobile/ is Vectrum for Android, in Kotlin with Jetpack Compose. It looks like the website: MetalUI's
bone and graphite colorways, raised plates and sunk wells, Geist and Geist Mono, engraved mono labels.
What it does:
Needs JDK 17+ and the Android SDK (platform 37, build tools 36). With ANDROID_HOME set (or sdk.dir in
mobile/local.properties):
cd mobile
./gradlew assembleDebug # app/build/outputs/apk/debug/app-debug.apk
./gradlew installDebug # onto a connected device or emulator
./gradlew assembleRelease # minified, signed with the debug key; sign with your own key to publish
The app runs on Android 8.0 (API 26) and newer.
The first time it opens, the app walks through three steps:
git.example.com, 192.168.1.10:3000). Plain HTTP is fine; without http:// or https://, HTTPS is
tried first, then HTTP. The app checks that the server is a Vectrum new enough for the app before going on.SIGNUPS_DISABLED).After signing out, the app opens on the account step for the same server, with Change to pick another.
From the Android emulator, the computer running bun dev is http://10.0.2.2:3000.
The app gets the same 30-day session token the website keeps in its cookie, and stores it in the app's private
storage; Sign Out forgets it. Changing your password ends the session, as on the website. Plain http:// is
allowed for self-hosted servers on a local network; the sign-in screen warns before a password goes to a
non-local server without HTTPS.
The app talks to /api/v1 (app/api/v1/[...path]/route.ts, lib/app-api.ts): JSON, with the session token
as Authorization: Bearer <token>. It acts as the signed-in person and applies the website's permission
checks, so the app can't do anything the website wouldn't let that person do: private repositories are "not
found" to others, anyone who can read a repository may open issues and comment, and changing issues,
approving, requesting changes and merging need push access and the base branch's rules.
| Request | |
|---|---|
GET /api/v1/server | { name, api, signups }: what the setup checks before signing in |
POST /api/v1/session | { login, password } → { token, user } |
POST /api/v1/signup | { username, email, password, name } → { token, user }, when sign-ups are open |
GET /api/v1/user, /home, /explore?q=, /users/<name> | |
GET /api/v1/repos/<owner>/<repo> | the repository, its README, root files, branches and counts |
GET …/tree?ref=&path=, …/blob?ref=&path=, …/raw?ref=&path=, …/image | |
GET …/commits?ref=&page=, …/commits/<sha>, …/branches, …/events | |
GET …/issues, GET, PATCH …/issues/<n>, POST …/issues, POST …/issues/<n>/comments | |
GET …/pulls?state=, GET, PATCH …/pulls/<n>, GET …/pulls/<n>/files | |
POST …/pulls/<n>/comments, …/pulls/<n>/reviews, …/pulls/<n>/merge | |
GET …/runs?page=, …/runs/<n>, …/releases |
Errors are { "error": "…" } with a 4xx status; 401 means the session ended.
data/: the API's models (Models.kt), the HTTP client (Api.kt) and the stored session (Session.kt)ui/theme/: MetalUI's colorways (Palette.kt), type roles (Type.kt) and materials (Materials.kt:
plates, wells and caps as stacks of shadows, from MetalUI's tokens)ui/icons/: the website's glyphs as vectorsui/components/: buttons, fields, the segmented control, pills and LEDs, avatars and identicons, Markdown,
the code highlighter and viewer, diffs, sheets and toastsui/screens/: one file per area; ui/App.kt holds the navigation and the tab barui/Loader.kt: screen data kept in view models, with pull to refresh and paging