mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-12 23:32:50 -04:00
4.8 KiB
4.8 KiB
Data Persistence Guide
DMS plugins have three tiers of data persistence, each suited for different use cases.
Tier 1: Plugin Data (Settings)
Persisted to settings.json. Use for user preferences and configuration.
Saving
pluginService.savePluginData(pluginId, "key", value)
Loading
var value = pluginService.loadPluginData(pluginId, "key", defaultValue)
Reactive Access via pluginData
PluginComponent has a reactive pluginData property that auto-loads from settings:
PluginComponent {
property string displayText: pluginData?.text || "Default"
property bool showIcon: pluginData?.showIcon !== undefined ? pluginData.showIcon : true
}
Reacting to Settings Changes
When settings are changed (e.g., from the settings UI), react with Connections:
Connections {
target: pluginService
function onPluginDataChanged(changedId) {
if (changedId !== pluginId) return
displayText = pluginService.loadPluginData(pluginId, "text", "Default")
showIcon = pluginService.loadPluginData(pluginId, "showIcon", true)
}
}
Tier 2: Plugin State
Persisted to a separate state file. Use for runtime state that should survive restarts but is not user-configurable (history, cache, counters).
Saving
pluginService.savePluginState(pluginId, "key", value)
Loading
var state = pluginService.loadPluginState(pluginId, "key", defaultValue)
Additional Methods
pluginService.clearPluginState(pluginId)
pluginService.removePluginStateKey(pluginId, "key")
Example: Persistent History
Item {
property var history: []
Component.onCompleted: {
history = pluginService?.loadPluginState(pluginId, "history", []) || []
}
function addToHistory(entry) {
history.unshift({
text: entry,
timestamp: Date.now()
})
if (history.length > 100) history = history.slice(0, 100)
pluginService?.savePluginState(pluginId, "history", history)
}
function clearHistory() {
history = []
pluginService?.removePluginStateKey(pluginId, "history")
}
}
Tier 3: Global Variables (Runtime Only)
NOT persisted. Shared across all instances of a plugin. Use for cross-instance state synchronization (multi-monitor consistency, multi-instance widgets).
Using PluginGlobalVar Component
import qs.Modules.Plugins
PluginComponent {
PluginGlobalVar {
id: globalCounter
varName: "counter"
defaultValue: 0
}
horizontalBarPill: Component {
StyledRect {
// ...
StyledText {
text: "Count: " + globalCounter.value
}
MouseArea {
onClicked: globalCounter.set(globalCounter.value + 1)
}
}
}
}
PluginGlobalVar properties:
| Property | Type | Description |
|---|---|---|
varName |
string | Required: name of the global variable |
defaultValue |
any | Optional: default if not set |
value |
any | Readonly: current value |
Methods:
set(newValue)- update the value (triggers reactivity across all instances)
Using PluginService API Directly
import qs.Services
property int counter: PluginService.getGlobalVar("myPlugin", "counter", 0)
Connections {
target: PluginService
function onGlobalVarChanged(pluginId, varName) {
if (pluginId === "myPlugin" && varName === "counter") {
counter = PluginService.getGlobalVar("myPlugin", "counter", 0)
}
}
}
function increment() {
var current = PluginService.getGlobalVar("myPlugin", "counter", 0)
PluginService.setGlobalVar("myPlugin", "counter", current + 1)
}
Decision Matrix
| Need | API | Persisted | Scope |
|---|---|---|---|
| User preferences (API keys, themes, intervals) | savePluginData / loadPluginData |
Yes (settings.json) | Per plugin |
| Runtime state (history, cache, counters) | savePluginState / loadPluginState |
Yes (state file) | Per plugin |
| Cross-instance sync (multi-monitor data) | PluginGlobalVar or getGlobalVar/setGlobalVar |
No (runtime only) | All instances |
| Quick reactive reads from settings | pluginData property |
N/A (read-only) | Per instance |
Important Notes
- pluginData is reactive - bindings update automatically when data changes
- Global vars are NOT persistent - they reset when the shell restarts
- State vs Data - data is for user-facing settings, state is for internal runtime data
- Null safety - always check
pluginServiceis not null before calling methods - Signal namespacing - global var signals include
pluginIdto filter for your plugin - Performance - global vars are efficient for frequent updates; settings writes are batched