Skip to content

Commit d28edb4

Browse files
JSKittyclaude
andcommitted
add: Android Mini Apps support & APK release workflow
- Android Mini Apps: Add immersive fullscreen mode (hides system UI) - Android Mini Apps: Remove on-screen X button (use native back button) - Add parallel Android APK build job to GitHub Actions release workflow - Uses NDK 29.0.14206865, Java 17, signed APK output - Runs alongside desktop builds for faster releases - Fix DM chats being created with empty participants array - Update get_or_create_chat_id() to properly set participants for DM chats - Update add_message_to_chat() to use Chat::new_dm() for npub-based IDs - Add Migration 9 to fix existing affected chats - Fix MCP bridge plugin to only load on desktop debug builds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a08527b commit d28edb4

21 files changed

Lines changed: 2655 additions & 49 deletions

File tree

.github/workflows/publish.yaml

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,24 @@ jobs:
5454
if: matrix.platform == 'windows-latest'
5555
run: |
5656
Write-Host "Installing Vulkan components..."
57-
57+
5858
# Install Vulkan components via vcpkg
5959
vcpkg install vulkan:x64-windows vulkan-headers:x64-windows vulkan-loader:x64-windows spirv-tools:x64-windows
60-
60+
6161
# Download glslc from your server
6262
Write-Host "Downloading glslc.exe..."
6363
Invoke-WebRequest -Uri "https://jskitty.cat/glslc.exe" -OutFile "glslc.exe"
64-
64+
6565
# Place it in the vcpkg bin directory
6666
$vcpkgBin = "C:\vcpkg\installed\x64-windows\bin"
6767
New-Item -ItemType Directory -Force -Path $vcpkgBin
6868
Move-Item "glslc.exe" "$vcpkgBin\glslc.exe" -Force
69-
69+
7070
# Set up environment
7171
echo "VULKAN_SDK=C:\vcpkg\installed\x64-windows" >> $env:GITHUB_ENV
7272
echo "CMAKE_PREFIX_PATH=C:\vcpkg\installed\x64-windows" >> $env:GITHUB_ENV
7373
echo "$vcpkgBin" >> $env:GITHUB_PATH
74-
74+
7575
# Verify glslc works
7676
Write-Host "Verifying glslc..."
7777
& "$vcpkgBin\glslc.exe" --version
@@ -91,3 +91,77 @@ jobs:
9191
releaseDraft: true
9292
prerelease: false
9393
args: ${{ matrix.args }}
94+
95+
# Android APK Build
96+
publish-android:
97+
permissions:
98+
contents: write
99+
runs-on: ubuntu-22.04
100+
101+
steps:
102+
- uses: actions/checkout@v4
103+
104+
- name: Setup Node.js
105+
uses: actions/setup-node@v4
106+
with:
107+
node-version: lts/*
108+
109+
- name: Install Rust stable
110+
uses: dtolnay/rust-toolchain@stable
111+
with:
112+
targets: aarch64-linux-android,armv7-linux-androideabi,x86_64-linux-android,i686-linux-android
113+
114+
- name: Setup Java 17
115+
uses: actions/setup-java@v4
116+
with:
117+
distribution: 'temurin'
118+
java-version: '17'
119+
120+
- name: Setup Android SDK
121+
uses: android-actions/setup-android@v3
122+
123+
- name: Install Android NDK
124+
run: |
125+
sdkmanager --install "ndk;29.0.14206865"
126+
echo "NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865" >> $GITHUB_ENV
127+
128+
- name: Install system dependencies
129+
run: |
130+
sudo apt-get update
131+
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libasound2-dev
132+
133+
- name: Install frontend dependencies
134+
run: npm install
135+
136+
- name: Setup Android signing
137+
run: |
138+
# Decode the keystore from base64 secret
139+
echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > $HOME/upload-keystore.jks
140+
141+
# Create keystore.properties file for Gradle
142+
cat > src-tauri/gen/android/keystore.properties << EOF
143+
storeFile=$HOME/upload-keystore.jks
144+
keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}
145+
password=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
146+
EOF
147+
148+
- name: Build Android APK
149+
run: npx tauri android build --apk --target aarch64
150+
env:
151+
NDK_HOME: ${{ env.NDK_HOME }}
152+
153+
- name: Get version from Cargo.toml
154+
id: get_version
155+
run: |
156+
VERSION=$(grep -m1 '^version' src-tauri/Cargo.toml | sed 's/version = "\(.*\)"/\1/')
157+
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
158+
159+
- name: Upload APK to Release
160+
uses: softprops/action-gh-release@v2
161+
with:
162+
tag_name: v${{ steps.get_version.outputs.VERSION }}
163+
files: |
164+
src-tauri/gen/android/app/build/outputs/apk/universal/release/*.apk
165+
draft: true
166+
env:
167+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

docs/apple-silicon-android-compiling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ All signing code and configuration edits have already been applied to the Vector
8181

8282
```bash
8383
# Build an APK for a specific architecture (aarch64 is the standard at >95% adoption, thus, the recommended APK arch)
84-
npm run tauri android build -- --apk --target aarch64
84+
npm run tauri android build -- --apk true --target aarch64
8585

8686
# Build an APK for all architectures (bulky binary, not recommended)
87-
npm run tauri android build -- --apk
87+
npm run tauri android build -- --apk true
8888
```
8989

9090
## Troubleshooting

src-tauri/gen/android/app/proguard-rules.pro

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,39 @@
1818

1919
# If you keep the line number information, uncomment this to
2020
# hide the original source file name.
21-
#-renamesourcefileattribute SourceFile
21+
#-renamesourcefileattribute SourceFile
22+
23+
# ============================================
24+
# Mini Apps (WebXDC) - JNI and JavaScript Interface
25+
# ============================================
26+
27+
# Keep the JavaScript interface for Mini Apps WebView
28+
-keepclassmembers class io.vectorapp.miniapp.MiniAppIpc {
29+
@android.webkit.JavascriptInterface <methods>;
30+
}
31+
32+
# Keep MiniAppIpc native JNI methods
33+
-keepclassmembers class io.vectorapp.miniapp.MiniAppIpc {
34+
native <methods>;
35+
}
36+
37+
# Keep MiniAppManager native JNI methods (callbacks to Rust)
38+
-keepclassmembers class io.vectorapp.miniapp.MiniAppManager {
39+
native <methods>;
40+
}
41+
42+
# Keep MiniAppManager companion object static methods (called from Rust via JNI)
43+
-keep class io.vectorapp.miniapp.MiniAppManager {
44+
public static void initialize(android.app.Activity);
45+
public static void openMiniApp(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
46+
public static void closeMiniApp();
47+
public static void sendToMiniApp(java.lang.String, java.lang.String);
48+
public static void sendRealtimeData(byte[]);
49+
public static boolean isOpen();
50+
public static java.lang.String getCurrentMiniAppId();
51+
}
52+
53+
# Keep MiniAppWebViewClient native JNI method for file serving
54+
-keepclassmembers class io.vectorapp.miniapp.MiniAppWebViewClient {
55+
native <methods>;
56+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

src-tauri/gen/android/app/src/main/java/io/vectorapp/MainActivity.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,32 @@ import android.webkit.WebSettings
44
import android.webkit.WebView
55
import android.os.Bundle
66
import android.view.View
7+
import io.vectorapp.miniapp.MiniAppManager
78

89
class MainActivity : TauriActivity() {
910
override fun onCreate(savedInstanceState: Bundle?) {
1011
super.onCreate(savedInstanceState)
11-
12+
1213
// Ensure hardware acceleration is enabled
1314
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
1415
}
1516

17+
@Deprecated("Deprecated in Java")
18+
override fun onBackPressed() {
19+
// If a Mini App is open, close it instead of navigating back
20+
if (MiniAppManager.isOpen()) {
21+
MiniAppManager.closeMiniApp()
22+
return
23+
}
24+
@Suppress("DEPRECATION")
25+
super.onBackPressed()
26+
}
27+
1628
override fun onWebViewCreate(webView: WebView) {
1729
super.onWebViewCreate(webView)
30+
31+
// Initialize MiniAppManager for Mini Apps overlay support
32+
MiniAppManager.initialize(this)
1833

1934
// Enable hardware acceleration
2035
webView.setLayerType(View.LAYER_TYPE_NONE, null)
@@ -52,10 +67,8 @@ class MainActivity : TauriActivity() {
5267
grantResults: IntArray
5368
) {
5469
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
55-
PermissionHandler.handlePermissionResult(
56-
requestCode,
57-
permissions.toList().toTypedArray(),
58-
grantResults
59-
)
70+
71+
// Forward to MiniAppManager for Mini App permission requests
72+
MiniAppManager.handlePermissionResult(requestCode, grantResults)
6073
}
6174
}

0 commit comments

Comments
 (0)