Add QR pairing (terminal QR, in-app scanner, iris://pair deep link)
This commit is contained in:
1 parent
27dc7917f2
commit
7a6d922d12
63 files changed
+2073
-630
No files matched your search
@@ -8,6 +8,9 @@
|
||||
<!-- M5: ntfy listener foreground service (dataSync type on API 34). -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<!-- QR pairing (docs/20): the in-app scanner reads the camera. -->
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
<application
|
||||
android:label="Iris"
|
||||
@@ -38,8 +41,22 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="iris" android:host="chat" />
|
||||
</intent-filter>
|
||||
<!-- QR pairing (docs/20): iris://pair deep link (scanned QR / link). -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="iris" android:host="pair" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- QR pairing (docs/20): full-screen scanner launched from the
|
||||
Connect screen. Not exported; started only by our own app. -->
|
||||
<activity
|
||||
android:name="iris.platform.QrScanActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- M4: serve cached media/documents to other apps (ACTION_VIEW). -->
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
|
||||
@@ -16,11 +16,16 @@ import iris.platform.AndroidEnv
|
||||
import iris.platform.AndroidSecureStore
|
||||
import iris.platform.AppBridge
|
||||
import iris.platform.syncNtfyListener
|
||||
import iris.util.PairLink
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private val deepLinkChatId = mutableStateOf<String?>(null)
|
||||
private val deepLinkThreadId = mutableStateOf<String?>(null)
|
||||
|
||||
// QR pairing (docs/20): a parsed iris://pair link to prefill the Connect
|
||||
// screen with.
|
||||
private val pendingPair = mutableStateOf<PairLink?>(null)
|
||||
|
||||
private val notificationPermission =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { /* result ignored */ }
|
||||
|
||||
@@ -37,7 +42,13 @@ class MainActivity : ComponentActivity() {
|
||||
setContent {
|
||||
val chatId by deepLinkChatId
|
||||
val threadId by deepLinkThreadId
|
||||
IrisApp(store = store, deepLinkChatId = chatId, deepLinkThreadId = threadId)
|
||||
val pair by pendingPair
|
||||
IrisApp(
|
||||
store = store,
|
||||
deepLinkChatId = chatId,
|
||||
deepLinkThreadId = threadId,
|
||||
deepLinkPair = pair,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +75,14 @@ class MainActivity : ComponentActivity() {
|
||||
* extras or an iris://chat/<id>?thread=<tid> URI). */
|
||||
private fun handleDeepLink(intent: Intent?) {
|
||||
val data = intent?.data
|
||||
// QR pairing (docs/20): iris://pair?host=…&port=…&secure=…&token=… —
|
||||
// the whole payload is in the query string; parse it with the shared
|
||||
// PairLink parser.
|
||||
if (data?.scheme == "iris" && data.host == "pair") {
|
||||
val link = PairLink.parse(data.toString())
|
||||
if (link != null) pendingPair.value = link
|
||||
return
|
||||
}
|
||||
val chatId =
|
||||
intent?.getStringExtra("chat_id")
|
||||
?: data?.pathSegments?.firstOrNull()
|
||||
|
||||
Reference in new issue
Block a user