Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Meshtastic/Model/ConfigModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ final class BluetoothConfigEntity {

@Model
final class CannedMessageConfigEntity {
/// Deprecated (no successor, removed from active use — #2021). Retained as a stored
/// SwiftData property to preserve the schema and keep existing persisted values readable;
/// it is no longer surfaced in the UI, read, or actively written by app code.
var enabled: Bool = false
var inputbrokerEventCcw: Int32 = 0
var inputbrokerEventCw: Int32 = 0
Expand Down
3 changes: 2 additions & 1 deletion Meshtastic/Persistence/CoreDataMigrationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ private extension CoreDataMigrationService {
nodeMap: nodeMap
) { obj -> CannedMessageConfigEntity in
let sd = CannedMessageConfigEntity()
sd.enabled = (obj.value(forKey: "enabled") as? Bool) ?? false
// enabled is deprecated (no successor) and no longer written — not migrated; the
// stored property keeps its default. (#2021)
sd.inputbrokerEventCcw = (obj.value(forKey: "inputbrokerEventCcw") as? Int32) ?? 0
sd.inputbrokerEventCw = (obj.value(forKey: "inputbrokerEventCw") as? Int32) ?? 0
sd.inputbrokerEventPress = (obj.value(forKey: "inputbrokerEventPress") as? Int32) ?? 0
Expand Down
5 changes: 3 additions & 2 deletions Meshtastic/Persistence/UpdateSwiftData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,8 @@ extension MeshPackets {
if fetchedNode[0].cannedMessageConfig == nil {
let newCannedMessageConfig = CannedMessageConfigEntity()
modelContext.insert(newCannedMessageConfig)
newCannedMessageConfig.enabled = config.enabled
// config.enabled is deprecated (no successor, removed from active use);
// tolerated on read but no longer written to the stored entity. (#2021)
newCannedMessageConfig.sendBell = config.sendBell
newCannedMessageConfig.rotary1Enabled = config.rotary1Enabled
newCannedMessageConfig.updown1Enabled = config.updown1Enabled
Expand All @@ -1263,7 +1264,7 @@ extension MeshPackets {
newCannedMessageConfig.inputbrokerEventPress = Int32(config.inputbrokerEventPress.rawValue)
fetchedNode[0].cannedMessageConfig = newCannedMessageConfig
} else {
fetchedNode[0].cannedMessageConfig?.enabled = config.enabled
// config.enabled is deprecated (see above); no longer written. (#2021)
fetchedNode[0].cannedMessageConfig?.sendBell = config.sendBell
fetchedNode[0].cannedMessageConfig?.rotary1Enabled = config.rotary1Enabled
fetchedNode[0].cannedMessageConfig?.updown1Enabled = config.updown1Enabled
Expand Down
23 changes: 23 additions & 0 deletions Meshtastic/Resources/docs/developer/swiftdata.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,29 @@ <h3>Adding a New Schema Version</h3>
<li>Update <code>MeshtasticSchema.current</code> to point to the new version.</li>
</ol>
<div class="warning-callout"><strong>Warning — Never delete a <code>VersionedSchema</code>.</strong> Migration history must be preserved or the migration plan will fail on devices that skipped intermediate versions.</div>
<h3>Deprecated Properties</h3>
<p>When a proto field is deprecated upstream and the app stops using it, <strong>do not remove the corresponding <code>@Model</code> property</strong> — deleting a stored property is a schema change that would require a migration, and while V1 is unreleased there is nowhere to migrate from. Instead, retain the property as-is so:</p>
<ul>
<li>the SwiftData schema is unchanged, and</li>
<li>any values already persisted on-device remain readable.</li>
</ul>
<p>The field simply stops being surfaced in the UI, read, or actively written by app code. Mark it with a doc comment noting the deprecation and the tracking issue. Current examples:</p>
<table>
<thead>
<tr>
<th>Model</th>
<th>Property</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CannedMessageConfigEntity</code></td>
<td><code>enabled</code></td>
<td>#2021 — no successor; retained for schema/value compatibility, no longer read or written</td>
</tr>
</tbody>
</table>
<h2>Query Helpers</h2>
<p><code>QuerySwiftData.swift</code> contains helper functions for common fetches:</p>
<pre><code class="language-swift">let node = getNodeInfo(id: nodeNum, context: context)
Expand Down
10 changes: 5 additions & 5 deletions Meshtastic/Resources/docs/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -1025,20 +1025,20 @@
"node",
"stats",
"simctl",
"model",
"local",
"nodes",
"app",
"store",
"model",
"schema",
"context",
"packet",
"history",
"data",
"child",
"app",
"swift",
"schema",
"launch",
"device",
"launch",
"var",
"true",
"telemetry",
Expand All @@ -1050,7 +1050,7 @@
"type",
"set"
],
"charCount": 11360
"charCount": 12115
},
{
"id": "tak-protocol",
Expand Down
13 changes: 13 additions & 0 deletions Meshtastic/Resources/docs/markdown/developer/swiftdata.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ static let migrateV1toV2 = MigrationStage.custom(

> **Warning — Never delete a `VersionedSchema`.** Migration history must be preserved or the migration plan will fail on devices that skipped intermediate versions.

### Deprecated Properties

When a proto field is deprecated upstream and the app stops using it, **do not remove the corresponding `@Model` property** — deleting a stored property is a schema change that would require a migration, and while V1 is unreleased there is nowhere to migrate from. Instead, retain the property as-is so:

- the SwiftData schema is unchanged, and
- any values already persisted on-device remain readable.

The field simply stops being surfaced in the UI, read, or actively written by app code. Mark it with a doc comment noting the deprecation and the tracking issue. Current examples:

| Model | Property | Notes |
|-------|----------|-------|
| `CannedMessageConfigEntity` | `enabled` | #2021 — no successor; retained for schema/value compatibility, no longer read or written |

## Query Helpers

`QuerySwiftData.swift` contains helper functions for common fetches:
Expand Down
14 changes: 2 additions & 12 deletions Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ struct CannedMessagesConfig: View {
@State var hasChanges = false
@State var hasMessagesChanges = false
@State var configPreset = 0
@State var enabled = false
/// CannedMessageModule will sends a bell character with the messages.
@State var sendBell: Bool = false
/// Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating.
Expand All @@ -43,12 +42,6 @@ struct CannedMessagesConfig: View {

Section(header: Text("Options")) {

Toggle(isOn: $enabled) {

Label("Enabled", systemImage: "list.bullet.rectangle.fill")
}
.tint(.accentColor)

Toggle(isOn: $sendBell) {

Label("Send Bell", systemImage: "bell")
Expand Down Expand Up @@ -184,7 +177,8 @@ struct CannedMessagesConfig: View {
dismiss: goBack
) { fromUser, toUser in
var cmc = ModuleConfig.CannedMessageConfig()
cmc.enabled = enabled
// enabled is deprecated with no successor and removed from active
// use — intentionally not written. (#2021)
cmc.sendBell = sendBell
cmc.rotary1Enabled = rotary1Enabled
cmc.updown1Enabled = updown1Enabled
Expand Down Expand Up @@ -265,9 +259,6 @@ struct CannedMessagesConfig: View {

hasChanges = true
}
.onChange(of: enabled) { _, newEnabled in
if newEnabled != node?.cannedMessageConfig?.enabled { hasChanges = true }
}
.onChange(of: sendBell) { _, newSendBell in
if newSendBell != node?.cannedMessageConfig?.sendBell { hasChanges = true }
}
Expand Down Expand Up @@ -297,7 +288,6 @@ struct CannedMessagesConfig: View {
}
}
func setCannedMessagesValues() {
self.enabled = node?.cannedMessageConfig?.enabled ?? false
self.sendBell = node?.cannedMessageConfig?.sendBell ?? false
self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false
self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false
Expand Down
13 changes: 13 additions & 0 deletions docs/developer/swiftdata.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ static let migrateV1toV2 = MigrationStage.custom(

> **Warning — Never delete a `VersionedSchema`.** Migration history must be preserved or the migration plan will fail on devices that skipped intermediate versions.

### Deprecated Properties

When a proto field is deprecated upstream and the app stops using it, **do not remove the corresponding `@Model` property** — deleting a stored property is a schema change that would require a migration, and while V1 is unreleased there is nowhere to migrate from. Instead, retain the property as-is so:

- the SwiftData schema is unchanged, and
- any values already persisted on-device remain readable.

The field simply stops being surfaced in the UI, read, or actively written by app code. Mark it with a doc comment noting the deprecation and the tracking issue. Current examples:

| Model | Property | Notes |
|-------|----------|-------|
| `CannedMessageConfigEntity` | `enabled` | #2021 — no successor; retained for schema/value compatibility, no longer read or written |

## Query Helpers

`QuerySwiftData.swift` contains helper functions for common fetches:
Expand Down