diff --git a/Services/LayoutStore.Snapshots.cs b/Services/LayoutStore.Snapshots.cs
index d1d82ec..b90da2f 100644
--- a/Services/LayoutStore.Snapshots.cs
+++ b/Services/LayoutStore.Snapshots.cs
@@ -165,6 +165,16 @@ public partial class LayoutStore : IDisposable
return true;
}
+ /// Restores the full factory snapshot without changing the active build stamp.
+ public bool RestoreAllDefaults()
+ {
+ if (GetSnapshotState(DefaultsInitializedKey) != "1") return false;
+ var buildId = GetSnapshotState(CurrentBuildIdKey);
+ if (string.IsNullOrWhiteSpace(buildId)) return false;
+ RestoreDefaults(buildId);
+ return true;
+ }
+
private string? GetCurrentWebcamId()
{
using var cmd = _connection.CreateCommand();
diff --git a/ytLive.Tests/LayoutStoreSnapshotTests.cs b/ytLive.Tests/LayoutStoreSnapshotTests.cs
index 344f4e7..e6d6bb1 100644
--- a/ytLive.Tests/LayoutStoreSnapshotTests.cs
+++ b/ytLive.Tests/LayoutStoreSnapshotTests.cs
@@ -149,6 +149,42 @@ public sealed class LayoutStoreSnapshotTests
}
}
+ [Fact]
+ public void ResetAllScenes_RestoresTheFactorySnapshot()
+ {
+ var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
+ var starting = MakeScene(SceneCatalog.Starting, "Factory starting");
+ var brb = MakeScene(SceneCatalog.Brb, "Factory BRB");
+ try
+ {
+ using (var store = new LayoutStore(path))
+ {
+ store.Save(new[] { starting, brb }, null, null);
+ store.PrepareLayoutSnapshots("build-a");
+ store.Save(new[]
+ {
+ MakeScene(starting.Id, starting.Name, "Edited starting"),
+ MakeScene(brb.Id, brb.Name, "Edited BRB"),
+ }, null, null);
+ }
+
+ using (var reopened = new LayoutStore(path))
+ {
+ reopened.PrepareLayoutSnapshots("build-a");
+ Assert.True(reopened.RestoreAllDefaults());
+
+ var scenes = reopened.Load();
+ Assert.Equal("Factory starting", Assert.Single(scenes.Single(s => s.Name == SceneCatalog.Starting).Elements.OfType()).Name);
+ Assert.Equal("Factory BRB", Assert.Single(scenes.Single(s => s.Name == SceneCatalog.Brb).Elements.OfType()).Name);
+ }
+ }
+ finally
+ {
+ SqliteConnection.ClearAllPools();
+ try { File.Delete(path); } catch { /* best-effort cleanup */ }
+ }
+ }
+
private static Scene MakeScene(string sourceName)
=> MakeScene(SceneCatalog.Starting, sourceName);