feat: synchronize pinned tabs across devices
Development CI / check-and-package (push) Successful in 4m18s
GitHub Git mirror / mirror (push) Successful in 28s
Development CI / image (push) Successful in 21s
Development CI / deploy-development (push) Successful in 15s

This commit is contained in:
eezd committed 2026-11-04 18:20:16 +08:00
1 parent 403824eccb
commit 5514a1e465
12 files changed
+454 -29

No files matched your search

+13 -2
View File
@@ -56,8 +56,19 @@ func (s *Store) ReplacePreferences(values map[string]json.RawMessage) error {
return tx.Commit()
}
func (s *Store) ResetPreferences() error {
_, err := s.db.Exec(`DELETE FROM settings WHERE key IN ('app.settings','plugins.enabled')`)
return err
tx, err := s.db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
if _, err = tx.Exec(`DELETE FROM settings WHERE key IN ('app.settings','plugins.enabled')`); err != nil {
return err
}
// An explicit empty list prevents older devices from migrating their local pins after a reset.
if _, err = tx.Exec(`INSERT INTO settings(key,value) VALUES ('app.settings',?)`, `{"pinnedTabs":[]}`); err != nil {
return err
}
return tx.Commit()
}
func (s *Store) ClearSessions() error { _, err := s.db.Exec(`DELETE FROM sessions`); return err }
+28
View File
@@ -48,3 +48,31 @@ func TestOpenExistingUsesNativeEscapedPathWithoutCreating(t *testing.T) {
t.Fatalf("missing database was created: %v", err)
}
}
func TestResetPreferencesRollsBackIfPinResetFails(t *testing.T) {
st, err := Open(filepath.Join(t.TempDir(), "rawmark.db"))
if err != nil {
t.Fatal(err)
}
defer st.Close()
original := map[string]string{
"app.settings": `{"fontSize":24,"pinnedTabs":["note.md"]}`,
"plugins.enabled": `{"example":true}`,
}
for key, value := range original {
if err := st.SetSetting(key, value); err != nil {
t.Fatal(err)
}
}
if _, err := st.db.Exec(`CREATE TRIGGER reject_pin_reset BEFORE INSERT ON settings WHEN NEW.key='app.settings' BEGIN SELECT RAISE(ABORT,'intentional reset failure'); END`); err != nil {
t.Fatal(err)
}
if err := st.ResetPreferences(); err == nil {
t.Fatal("固定标签重置失败必须返回错误")
}
for key, value := range original {
if got, ok, err := st.Setting(key); err != nil || !ok || got != value {
t.Fatalf("重置失败未回滚 %s: %q, %v", key, got, err)
}
}
}