fix(37): preserve camera choice when restoring default layouts
Build-mismatch restoration now keeps the currently selected webcam identity, restores default scene placements against that camera, and leaves cameras absent when none is selected. The integration regression test pins the creator's camera choice and restored default geometry. 612 tests green, clean build with 0 warnings.
This commit is contained in:
@@ -246,10 +246,12 @@ public partial class LayoutStore : IDisposable
|
||||
private void RestoreDefaults(string buildId)
|
||||
{
|
||||
var columnsByTable = SnapshotTables.ToDictionary(table => table, ReadColumnNames);
|
||||
var currentWebcamId = GetCurrentWebcamId();
|
||||
using var tx = _connection.BeginTransaction();
|
||||
|
||||
foreach (var table in SnapshotTables.Reverse())
|
||||
{
|
||||
if (table == "Webcam") continue;
|
||||
using var delete = _connection.CreateCommand();
|
||||
delete.Transaction = tx;
|
||||
delete.CommandText = $"DELETE FROM {table};";
|
||||
@@ -258,10 +260,16 @@ public partial class LayoutStore : IDisposable
|
||||
|
||||
foreach (var table in SnapshotTables)
|
||||
{
|
||||
if (table == "Webcam" || (table == "WebcamSceneConfig" && currentWebcamId == null)) continue;
|
||||
var columns = string.Join(", ", columnsByTable[table].Select(QuoteIdentifier));
|
||||
var values = string.Join(", ", columnsByTable[table].Select(column =>
|
||||
column == "WebcamId" && table == "WebcamSceneConfig"
|
||||
? "$webcamId"
|
||||
: QuoteIdentifier(column)));
|
||||
using var copy = _connection.CreateCommand();
|
||||
copy.Transaction = tx;
|
||||
copy.CommandText = $"INSERT INTO {table} ({columns}) SELECT {columns} FROM Default{table};";
|
||||
copy.CommandText = $"INSERT INTO {table} ({columns}) SELECT {values} FROM Default{table};";
|
||||
if (table == "WebcamSceneConfig") copy.Parameters.AddWithValue("$webcamId", currentWebcamId!);
|
||||
copy.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,39 @@ public sealed class LayoutStoreSnapshotTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DifferentBuild_RestoresWebcamPlacement_WithoutReplacingChosenCamera()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
||||
var sceneId = Guid.NewGuid().ToString();
|
||||
var defaultWebcam = new Webcam { Id = "factory-webcam", DeviceId = "factory-device", Name = "Factory camera" };
|
||||
var chosenWebcam = new Webcam { Id = "chosen-webcam", DeviceId = "chosen-device", Name = "Chosen camera" };
|
||||
try
|
||||
{
|
||||
using (var store = new LayoutStore(path))
|
||||
{
|
||||
store.Save(new[] { MakeWebcamScene(sceneId, defaultWebcam.Id, 20) }, defaultWebcam, null);
|
||||
store.PrepareLayoutSnapshots("build-a");
|
||||
store.Save(new[] { MakeWebcamScene(sceneId, chosenWebcam.Id, 200) }, chosenWebcam, null);
|
||||
}
|
||||
|
||||
using (var reopened = new LayoutStore(path))
|
||||
{
|
||||
reopened.PrepareLayoutSnapshots("build-b");
|
||||
var restored = Assert.Single(reopened.Load());
|
||||
var config = Assert.Single(restored.Elements.OfType<WebcamSceneConfig>());
|
||||
Assert.Equal(chosenWebcam.DeviceId, reopened.Webcam?.DeviceId);
|
||||
Assert.Equal(chosenWebcam.Id, config.WebcamId);
|
||||
Assert.Equal(20, config.X);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SqliteConnection.ClearAllPools();
|
||||
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
||||
}
|
||||
}
|
||||
|
||||
private static Scene MakeScene(string sourceName)
|
||||
=> MakeScene(SceneCatalog.Starting, sourceName);
|
||||
|
||||
@@ -134,6 +167,14 @@ public sealed class LayoutStoreSnapshotTests
|
||||
Elements = { new Source { Name = sourceName, Type = SourceType.TextOverlay } },
|
||||
};
|
||||
|
||||
private static Scene MakeWebcamScene(string id, string webcamId, double x)
|
||||
=> new()
|
||||
{
|
||||
Id = id,
|
||||
Name = SceneCatalog.Live,
|
||||
Elements = { new WebcamSceneConfig { WebcamId = webcamId, Name = "Webcam", X = x, Y = 20, Width = 320, Height = 180 } },
|
||||
};
|
||||
|
||||
private static SqliteConnection GetConnection(string path)
|
||||
{
|
||||
var connection = new SqliteConnection($"Data Source={path}");
|
||||
|
||||
Reference in New Issue
Block a user