diff --git a/Android/app/build.gradle.kts b/Android/app/build.gradle.kts
index de832e18..732693b2 100644
--- a/Android/app/build.gradle.kts
+++ b/Android/app/build.gradle.kts
@@ -11,8 +11,8 @@ android {
applicationId = "com.archipelago.app"
minSdk = 26
targetSdk = 35
- versionCode = 27
- versionName = "0.5.7"
+ versionCode = 28
+ versionName = "0.5.8"
vectorDrawables {
useSupportLibrary = true
diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml
index bad2ab4d..1ed5e9a3 100644
--- a/Android/app/src/main/AndroidManifest.xml
+++ b/Android/app/src/main/AndroidManifest.xml
@@ -23,6 +23,18 @@
android:usesCleartextTraffic="true"
tools:targetApi="35">
+
+
+
+
+
Unit) {
+fun IntroScreen(
+ onContinue: () -> Unit,
+ // Mesh Party works with no node at all (phone↔phone) — offered right on
+ // the first screen so a friend who just got the app can join a party.
+ onMeshParty: () -> Unit = {},
+) {
val logoAlpha = remember { Animatable(0f) }
var showContent by remember { mutableStateOf(false) }
@@ -143,6 +148,14 @@ fun IntroScreen(onContinue: () -> Unit) {
onClick = onContinue,
modifier = Modifier.fillMaxWidth().height(56.dp),
)
+
+ Spacer(modifier = Modifier.height(12.dp))
+
+ GlassButton(
+ text = stringResource(R.string.mesh_party),
+ onClick = onMeshParty,
+ modifier = Modifier.fillMaxWidth().height(48.dp),
+ )
}
}
}
diff --git a/Android/app/src/main/java/com/archipelago/app/ui/screens/PartyScreen.kt b/Android/app/src/main/java/com/archipelago/app/ui/screens/PartyScreen.kt
index a8042182..e16ebfb9 100644
--- a/Android/app/src/main/java/com/archipelago/app/ui/screens/PartyScreen.kt
+++ b/Android/app/src/main/java/com/archipelago/app/ui/screens/PartyScreen.kt
@@ -281,6 +281,16 @@ fun PartyScreen(
)
}
Spacer(Modifier.height(12.dp))
+ // Hand the app itself to a friend: shares this install's own APK
+ // through the system sheet (Quick Share/Bluetooth), so a nearby
+ // phone gets the companion with zero internet — the whole party
+ // premise.
+ GlassButton(
+ text = "Share this app",
+ onClick = { shareCompanionApk(context) },
+ modifier = Modifier.fillMaxWidth().height(48.dp),
+ )
+ Spacer(Modifier.height(12.dp))
}
// Party QR scanner overlay
@@ -364,3 +374,28 @@ private fun renderQr(payload: String, size: Int = 640): Bitmap? = try {
} catch (_: Exception) {
null
}
+
+/** Share this install's own APK via the system share sheet — a nearby friend
+ * gets the companion with no internet at all (Quick Share / Bluetooth). */
+private fun shareCompanionApk(context: android.content.Context) {
+ try {
+ val src = java.io.File(context.applicationInfo.sourceDir)
+ val dir = java.io.File(context.cacheDir, "share").apply { mkdirs() }
+ val out = java.io.File(dir, "archipelago-companion.apk")
+ src.copyTo(out, overwrite = true)
+ val uri = androidx.core.content.FileProvider.getUriForFile(
+ context, "${context.packageName}.fileprovider", out,
+ )
+ val send = android.content.Intent(android.content.Intent.ACTION_SEND).apply {
+ type = "application/vnd.android.package-archive"
+ putExtra(android.content.Intent.EXTRA_STREAM, uri)
+ addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+ context.startActivity(
+ android.content.Intent.createChooser(send, "Share Archipelago Companion")
+ .addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK),
+ )
+ } catch (_: Exception) {
+ // No share targets / copy failed — nothing sensible to do here.
+ }
+}
diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml
index 40be6925..6f92ff2c 100644
--- a/Android/app/src/main/res/values/strings.xml
+++ b/Android/app/src/main/res/values/strings.xml
@@ -11,6 +11,7 @@
Your Sovereign\nPersonal Server
Bitcoin node, app platform, and private cloud — all in one box you control.
Get Started
+ Mesh Party
Use HTTPS
Port (optional)
Saved Servers
diff --git a/Android/app/src/main/res/xml/file_paths.xml b/Android/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 00000000..40e6b2d8
--- /dev/null
+++ b/Android/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/neode-ui/public/packages/archipelago-companion.apk b/neode-ui/public/packages/archipelago-companion.apk
index d48fe5b3..6f33528e 100644
Binary files a/neode-ui/public/packages/archipelago-companion.apk and b/neode-ui/public/packages/archipelago-companion.apk differ