feat(app): Teilen-Ziel — Bilder/Videos/Dateien aus anderen Apps an ARIA

'Teilen -> ARIA' aus WhatsApp, Galerie, Browser & Co. Ablauf wie gewuenscht:
sehen WAS geteilt wurde -> WOHIN (Projekt oder Hauptchat) -> optional Text dazu.
Ohne Text geht genauso.

- Manifest: intent-filter fuer ACTION_SEND (text/image/video/audio/application)
  und ACTION_SEND_MULTIPLE. launchMode=singleTask war bereits gesetzt.
- ShareIntentModule (Kotlin): liest den Intent und kopiert die Inhalte SOFORT in
  den App-Cache — die Leseerlaubnis fuer content://-URIs gilt nur fuer diesen
  Intent und waere nach der Projektauswahl womoeglich erloschen. Liefert echte
  Dateipfade, dadurch laeuft Teilen durch exakt dieselbe Upload-Strecke wie die
  Bueroklammer (RNFS -> Base64 -> Anhang im Chat).
- MainActivity.onNewIntent: setIntent + Event an JS (best effort). Zweitweg in
  JS ueber AppState 'active' -> getSharedData(), falls das Event je nach
  RN-Architektur nicht durchkommt; getSharedData markiert den Intent als
  verbraucht, also kein doppeltes Aufpoppen.
- ShareModal: Vorschau der geteilten Inhalte, Projektliste (inkl. Hauptchat),
  optionales Textfeld. Senden erst nach Zielwahl moeglich.
- sendPendingAttachments nimmt die Anhaenge jetzt optional als Parameter — beim
  Teilen waere der State zum Aufrufzeitpunkt noch leer.
tsc --noEmit: 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 01:19:55 +02:00
co-authored by Claude Opus 4.8
parent b9354283af
commit b6195d3a53
8 changed files with 553 additions and 6 deletions
@@ -1,5 +1,6 @@
package com.ariacockpit
import android.content.Intent
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
@@ -19,4 +20,26 @@ class MainActivity : ReactActivity() {
*/
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
/**
* Teilen in die LAUFENDE App (launchMode=singleTask liefert das hier ab).
* setIntent() ist wichtig, damit getSharedData() denselben Inhalt sieht, und
* das Event weckt die JS-Seite sofort — ohne es wuerde der geteilte Inhalt
* erst beim naechsten Kaltstart auftauchen.
*/
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
// Best effort: je nach RN-Architektur ist der Kontext anders erreichbar.
// Scheitert es, greift der zuverlaessige Zweitweg — die JS-Seite fragt beim
// Zurueckkehren in den Vordergrund ohnehin nochmal via getSharedData() nach
// (setIntent() oben sorgt dafuer, dass sie denselben Inhalt sieht).
try {
val ctx = (application as? com.facebook.react.ReactApplication)
?.reactNativeHost?.reactInstanceManager?.currentReactContext
ShareIntentModule.notifyNewIntent(
ctx as? com.facebook.react.bridge.ReactApplicationContext, intent)
} catch (_: Throwable) {
}
}
}