feat(android): add capacitor wrapper project
This commit is contained in:
11
.gitignore
vendored
11
.gitignore
vendored
@@ -53,6 +53,7 @@ test-results/
|
||||
*.AppImage
|
||||
*.deb
|
||||
*.rpm
|
||||
*.apk
|
||||
|
||||
resources/bin
|
||||
|
||||
@@ -88,3 +89,13 @@ artifacts/**
|
||||
!artifacts/releases/**/*.AppImage
|
||||
!artifacts/releases/**/*.deb
|
||||
!artifacts/releases/**/*.rpm
|
||||
|
||||
# Allow committing release binaries when explicitly staged under installers/.
|
||||
!installers/
|
||||
installers/**
|
||||
!installers/**/*.exe
|
||||
!installers/**/*.apk
|
||||
!installers/**/*.aab
|
||||
!installers/**/*.zip
|
||||
!installers/**/*.yml
|
||||
!installers/**/*.blockmap
|
||||
|
||||
18
mobile/README.md
Normal file
18
mobile/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# DeskClaw Android (APK)
|
||||
|
||||
This is a Capacitor wrapper around the DeskClaw web UI.
|
||||
|
||||
It produces an APK that bundles the UI for offline rendering. It does not embed the full Electron main-process features.
|
||||
|
||||
## Build (Debug APK)
|
||||
|
||||
```bash
|
||||
cd mobile
|
||||
pnpm run web:build
|
||||
pnpm run web:sync
|
||||
pnpm install
|
||||
pnpm exec cap sync android
|
||||
cd android
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
14
mobile/capacitor.config.ts
Normal file
14
mobile/capacitor.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { CapacitorConfig } from '@capacitor/cli'
|
||||
|
||||
const config: CapacitorConfig = {
|
||||
appId: 'dev.deskclaw.app',
|
||||
appName: 'DeskClaw',
|
||||
webDir: 'www',
|
||||
bundledWebRuntime: false,
|
||||
server: {
|
||||
androidScheme: 'https',
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
24
mobile/package.json
Normal file
24
mobile/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "deskclaw-mobile",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.31.0",
|
||||
"scripts": {
|
||||
"web:build": "cd .. && pnpm run build:vite",
|
||||
"web:sync": "node scripts/sync-web.mjs",
|
||||
"android:init": "pnpm install && pnpm exec cap init DeskClaw dev.deskclaw.app --web-dir=www --npm-client=pnpm",
|
||||
"android:add": "pnpm exec cap add android",
|
||||
"android:sync": "pnpm exec cap sync android",
|
||||
"android:apk:debug": "cd android && ./gradlew assembleDebug",
|
||||
"android:apk:release": "cd android && ./gradlew assembleRelease"
|
||||
},
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^7.4.3",
|
||||
"@capacitor/core": "^7.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "^7.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
38
mobile/scripts/sync-web.mjs
Normal file
38
mobile/scripts/sync-web.mjs
Normal file
@@ -0,0 +1,38 @@
|
||||
import { mkdir, readdir, rm, copyFile, stat } from 'node:fs/promises'
|
||||
import { join, resolve } from 'node:path'
|
||||
|
||||
async function copyDir(srcDir, dstDir) {
|
||||
await mkdir(dstDir, { recursive: true })
|
||||
const entries = await readdir(srcDir, { withFileTypes: true })
|
||||
for (const entry of entries) {
|
||||
const src = join(srcDir, entry.name)
|
||||
const dst = join(dstDir, entry.name)
|
||||
if (entry.isDirectory()) {
|
||||
await copyDir(src, dst)
|
||||
continue
|
||||
}
|
||||
if (entry.isFile()) {
|
||||
await copyFile(src, dst)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const repoRoot = resolve(process.cwd(), '..')
|
||||
const fromDir = join(repoRoot, 'dist')
|
||||
const toDir = resolve(process.cwd(), 'www')
|
||||
|
||||
const st = await stat(fromDir).catch(() => null)
|
||||
if (!st || !st.isDirectory()) {
|
||||
throw new Error(`Missing dist/ at ${fromDir}. Run: pnpm -C .. run build:vite`)
|
||||
}
|
||||
|
||||
await rm(toDir, { recursive: true, force: true })
|
||||
await copyDir(fromDir, toDir)
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user