From eecad06eea62a267125646c7421c296ff40c32ac Mon Sep 17 00:00:00 2001 From: tuxgyver Date: Sun, 20 Sep 2026 21:43:40 +0200 Subject: [PATCH] =?UTF-8?q?release:=20v0.1.7=20=E2=80=94=20dissociation=20?= =?UTF-8?q?automatique=20quand=20le=20parent=20supprime=20l'appareil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 4 +++ .../jttools/datacontrol/remote/RemoteSync.kt | 27 +++++++++++++++++++ version.properties | 4 +-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c79f051..574dd71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.1.7 – 2026-09-20 + +- Contrôle parental : si le parent supprime l'appareil depuis FamilyControl, DataControl se dissocie automatiquement (règles et envois arrêtés) et le note dans le journal. + ## v0.1.6 – 2026-09-20 - Onglet Journal : le bouton « Tester le VPN » est retiré (le VPN se monte correctement). diff --git a/app/src/main/java/com/jttools/datacontrol/remote/RemoteSync.kt b/app/src/main/java/com/jttools/datacontrol/remote/RemoteSync.kt index 3efd9b8..ca26e1b 100644 --- a/app/src/main/java/com/jttools/datacontrol/remote/RemoteSync.kt +++ b/app/src/main/java/com/jttools/datacontrol/remote/RemoteSync.kt @@ -8,6 +8,7 @@ import com.jttools.datacontrol.data.AppSettings import com.jttools.datacontrol.data.InstalledAppsRepository import com.jttools.datacontrol.data.SettingsRepository import com.jttools.datacontrol.data.TrafficDay +import com.jttools.datacontrol.log.AppLog import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.distinctUntilChanged @@ -94,6 +95,20 @@ class RemoteSync @Inject constructor( } .collect { cfg -> if (cfg != null) apply(cfg) } } + scope.launch { + // Si le parent supprime l'appareil de la famille, on se dissocie localement (plus de règles, + // plus d'envois qui échoueraient en silence). + settingsRepository.settingsFlow + .map { it.familyId to it.deviceId } + .distinctUntilChanged() + .flatMapLatest { (fid, did) -> if (fid == null || did == null) flowOf(null) else existenceFlow(fid, did) } + .collect { exists -> + if (exists == false) { + AppLog.w("FamilyControl", "Appareil supprimé par le parent : dissociation locale") + settingsRepository.setPairing(null, null) + } + } + } scope.launch { // Liste des applications installées, pour que le parent puisse choisir lesquelles autoriser. settingsRepository.settingsFlow.map { it.isPaired }.distinctUntilChanged().collect { paired -> @@ -102,6 +117,18 @@ class RemoteSync @Inject constructor( } } + /** Vrai/faux selon que le document de l'appareil existe côté serveur (ignore le cache local). */ + private fun existenceFlow(fid: String, did: String) = callbackFlow { + val db = gateway.db + if (db == null || gateway.ensureSignedIn() == null) { trySend(null); close(); return@callbackFlow } + val reg = db.collection("families").document(fid).collection("devices").document(did) + .addSnapshotListener { snap, err -> + if (err != null || snap == null || snap.metadata.isFromCache) return@addSnapshotListener + trySend(snap.exists()) + } + awaitClose { reg.remove() } + } + private class Config(val map: Map) private fun configFlow(fid: String, did: String) = callbackFlow { diff --git a/version.properties b/version.properties index 06e2e05..8af8958 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ -versionName=0.1.6 -versionCode=7 +versionName=0.1.7 +versionCode=8