1 Commits
Author SHA1 Message Date
tuxgyverandClaude Sonnet 5 eecad06eea release: v0.1.7 — dissociation automatique quand le parent supprime l'appareil
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 21:43:40 +02:00
3 changed files with 33 additions and 2 deletions

No files matched your search

+4
View File
@@ -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).
@@ -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<Boolean?> {
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<String, Any?>)
private fun configFlow(fid: String, did: String) = callbackFlow<Config?> {
+2 -2
View File
@@ -1,2 +1,2 @@
versionName=0.1.6
versionCode=7
versionName=0.1.7
versionCode=8