Skip to content

Initial version of the mobile app#4

Open
ArtyomSavchenko wants to merge 17 commits into
developfrom
mobile-app
Open

Initial version of the mobile app#4
ArtyomSavchenko wants to merge 17 commits into
developfrom
mobile-app

Conversation

@ArtyomSavchenko

@ArtyomSavchenko ArtyomSavchenko commented Jul 9, 2026

Copy link
Copy Markdown
Member

Overview

Adds an iOS/Android mobile app that wraps the Platform web frontend in a Capacitor native shell, plus a CI pipeline that produces installable Android test artifacts on every change.

Mobile shell (mobile/)

  • Capacitor 7 project with native Android and iOS projects. The web bundle built by dev/prod is copied into www/ and loaded from local resources (local-first: the app opens without a server; backend URLs come from the bundled config.json).
  • Native error handling: a custom WebViewClient (Android) and WKNavigationDelegate (iOS) intercept load failures (connection refused, timeout, no network) and show a native "Connection Error" screen with a Retry button. Both platforms monitor connectivity; the splash screen is held until the WebView loads.
  • Permissions: camera/microphone declared and prompted at runtime via Capacitor's built-in handlers (calls, voice messages, photo capture); notification permission (Android 13+) requested once on first launch; iOS usage descriptions for camera/mic/photo library.
  • Attachment downloads: WebView downloads are routed to the system DownloadManager (public Downloads dir, cookie passthrough, completion notification) — previously they were silently ignored.
  • App id org.platformcollective.app — brand-neutral, chosen before any distribution since store listings and update paths are permanently tied to it. Display name and icons intentionally keep Huly branding until the new brand is decided.
  • Stable debug keystore committed to the repo (standard debug credentials, not a secret) so test APKs from CI and local builds install over each other without uninstalling. versionCode/versionName overridable via env; CI stamps the run number.

Web app changes

  • Login: network-level failures now show "Server is unavailable" instead of a generic unknown error across login / guest login / signup / OTP / workspace creation flows, with translations for all 11 languages.
  • dev/prod: branding fetch no longer crashes app boot when BRANDING_URL is unreachable; a fallback error UI is shown if platform initialization fails outside the native shell.
  • Configs: config-mobile.json (local dev) and config-mobile-huly.json (huly.app cloud, absolute file URLs usable from a device — used by CI). The copy script accepts MOBILE_CONFIG to select the bundled config.

CI

  • New Mobile workflow (.github/workflows/mobile.yml): builds the web bundle → cap syncgradlew assembleDebug → uploads the huly-android-debug-apk artifact (14-day retention). Runs on pushes/PRs touching mobile/ and manually via workflow dispatch with a selectable config input. iOS is not built in CI yet (needs a macOS runner and Apple signing).
  • Main CI integration for the new rush project: mobile added to the CacheFolders cache list (svelte-check/test rely on it to carry .rush/temp state), a format stub script, and a pnpm-lock update.

Testing

  • Mobile workflow is green end-to-end: APK builds, is signed with the committed debug keystore, and bundles the huly.app config (verified in CI logs).
  • The exact web bundle shipped in the APK was smoke-tested in Chromium with a phone viewport: the login screen renders with no JS errors.
  • On-device testing: download the huly-android-debug-apk artifact from the latest Mobile workflow run and install it.

Known gaps (follow-ups)

  • OAuth logins (GitHub/Google) do not complete inside the WebView — needs system-browser flow plus a deep-link return, including account-service support. Email/password login works.
  • Push notifications are not implemented (FCM/APNs plus notification-service delivery).
  • Real-device audit of mobile layout/keyboard/safe-areas is pending.

🤖 Generated with Claude Code

https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny

ArtyomSavchenko and others added 17 commits February 2, 2026 13:43
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
Signed-off-by: Artem Savchenko <armisav@gmail.com>
…ioning)

- Add config-mobile-huly.json: huly.app cloud config with absolute file URLs
  usable from a device (relative /files URLs do not work in the native shell)
- Support MOBILE_CONFIG env var in copy-web.js to select the bundled config
- Commit a stable debug keystore and wire it into the debug signing config so
  debug APKs from CI and local builds install over each other
- Allow overriding versionCode/versionName via env; CI stamps run number
- Fix executable bit on android/gradlew

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
Builds the web bundle, syncs Capacitor and uploads a debug APK on
pushes/PRs touching mobile/ and on manual dispatch with a selectable
bundled config.json (default: huly.app cloud backend).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
Signed-off-by: Artem Savchenko <armisav@gmail.com>
The +x set via update-index was overwritten by a later 'git add -A' from
a 644 working copy, so CI failed with 'Permission denied'. Fix the mode
in git and chmod defensively in the workflow before invoking gradle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
…loads

- Declare CAMERA, RECORD_AUDIO, MODIFY_AUDIO_SETTINGS and POST_NOTIFICATIONS
  in AndroidManifest so Capacitor's BridgeWebChromeClient can grant
  getUserMedia requests from the web app (calls, voice messages, photo capture)
- Route WebView downloads to the system DownloadManager (public Downloads dir,
  cookie passthrough, completion notification); previously attachment
  downloads were silently ignored
- Add iOS usage descriptions for camera, microphone and photo library
  (required for the corresponding WKWebView permission prompts)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
window.Capacitor is not declared on the Window type, which failed
'rush validate' (TS2339) and blocked PR CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
svelte-check/test jobs skip 'rush install' and rely on the cached
CacheFolders to carry each project's .rush/temp state from the build
job. The mobile folder was missing from that list, so Rush failed to
compute the repo inputs snapshot ('Build cache is only supported if
running in a Git repository'). The formatting job additionally requires
every changed project to define a 'format' script — add the same stub
dev/prod uses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
…d 13+)

POST_NOTIFICATIONS was declared but never requested, so notifications
would stay silently blocked on API 33+. Camera/mic runtime prompts are
already handled by Capacitor's BridgeWebChromeClient (Android) and
WebViewDelegationHandler (iOS) with the declarations added earlier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
…ive.app

The app id is effectively immutable once builds are distributed (store
listings and update paths are tied to it), and io.huly.platform is
derived from a domain/brand this fork is moving away from. Display name
and icons intentionally keep Huly branding until the new brand is
chosen — those are cheap to swap later.

- Android: namespace/applicationId, Java package move, package_name and
  custom_url_scheme strings
- iOS: PRODUCT_BUNDLE_IDENTIFIER
- capacitor.config.ts appId, README

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
faker-generated space names like 'late' or 'dis' substring-match other
nav buttons ('Templates', 'discontinue'), tripping Playwright strict
mode in ES-40 (TESTS-391).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019FZunPGufTZSRHuyTkTrny
@ArtyomSavchenko ArtyomSavchenko changed the title Mobile app Initial version of the mobile app Jul 9, 2026
@ArtyomSavchenko ArtyomSavchenko marked this pull request as ready for review July 9, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants