A file in a chat keeps its name and its label
`Ref.toJson` is what the vault persists next to a message, and it never wrote `filename`, `classification` or `compartments`. They reach the far end correctly, as additive top-level keys on the envelope, so a received document ARRIVED named. It was the local copy that lost them, on the first read back out of storage. A file in a chat therefore had a name until the app was restarted and never again, which reads as a damaged file rather than as the app forgetting. `fromJson` now defaults those three to null rather than to empty. Passing nothing means "not a wire parse, read what was stored"; passing a value, including an empty one, means the envelope said so and wins. Empty defaults could not tell those two apart, and answering "" for both is exactly what made a stored file nameless. The same rule fixes `expires`. The history path hands in 0.0, and 0 means "does not expire", so every stored story read back as immortal: its bytes were never dropped and it rendered forever. A caller that names an expiry still means it; one that does not now gets what the vault kept. They are stored under the same names the shared backup format uses, so `BackupPayload` carries them straight through. A document restored from a backup arrived with no name and no label before this, which is worse than not restoring it. Four tests on the storage round trip, one on the envelope still winning, one that an attachment which never had a name does not invent one, and one carrying a document through a backup whole. Full suite: 1276 tests, no failures. No new ktlint violations in Content.kt (3 at HEAD, 3 now). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
140affc356
commit
7ab5c774cb
@@ -185,6 +185,13 @@ object BackupPayload {
|
||||
a.optDouble("dur", 0.0).takeIf { it > 0.0 }?.let { out.put("duration", it) }
|
||||
// Seconds here, milliseconds there.
|
||||
a.optDouble("exp", 0.0).takeIf { it > 0.0 }?.let { out.put("expires", secondsToMillis(it)) }
|
||||
// Stored under the same names the shared shape uses, so these three
|
||||
// pass straight through. They were not carried before because this app
|
||||
// did not keep them at all; a restored document arrived with no name
|
||||
// and no label, which is worse than not restoring it.
|
||||
a.optString("filename").takeIf { it.isNotEmpty() }?.let { out.put("filename", it) }
|
||||
a.optInt("classification", 0).takeIf { it != 0 }?.let { out.put("classification", it) }
|
||||
a.optJSONArray("compartments")?.takeIf { it.length() > 0 }?.let { out.put("compartments", it) }
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -330,6 +337,9 @@ object BackupPayload {
|
||||
.put("h", a.optInt("height"))
|
||||
a.optDouble("duration", 0.0).takeIf { it > 0.0 }?.let { out.put("dur", it) }
|
||||
a.optDouble("expires", 0.0).takeIf { it > 0.0 }?.let { out.put("exp", millisToSeconds(it)) }
|
||||
a.optString("filename").takeIf { it.isNotEmpty() }?.let { out.put("filename", it) }
|
||||
a.optInt("classification", 0).takeIf { it != 0 }?.let { out.put("classification", it) }
|
||||
a.optJSONArray("compartments")?.takeIf { it.length() > 0 }?.let { out.put("compartments", it) }
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user