feat: restore legacy drag events and Tornado launch integration

This commit is contained in:
2026-07-15 15:35:25 +09:00
parent 6e0c275fdd
commit 06a16e5741
32 changed files with 3096 additions and 101 deletions

View File

@@ -40,6 +40,11 @@ public sealed record LegacySelectPlaylistRowIntent(
public sealed record LegacyMoveSelectedPlaylistRowsIntent(
LegacyPlaylistMoveDirection Direction) : LegacyUiIntent;
public sealed record LegacyReorderPlaylistRowsIntent(
string SourceRowId,
string TargetRowId,
LegacyDragDropPosition Position) : LegacyUiIntent;
public sealed record LegacyDeleteSelectedPlaylistRowsIntent : LegacyUiIntent;
public sealed record LegacyDeleteAllPlaylistRowsIntent : LegacyUiIntent;
@@ -54,6 +59,12 @@ public sealed record LegacySwapTabsIntent(
LegacyOperatorTabId Source,
LegacyOperatorTabId Target) : LegacyUiIntent;
public sealed record LegacyHoverSwapTabsIntent(
LegacyOperatorTabId Source,
LegacyOperatorTabId Target,
int ExpectedSourceIndex,
int ExpectedTargetIndex) : LegacyUiIntent;
public sealed record LegacySetMovingAveragesIntent(bool Ma5, bool Ma20) : LegacyUiIntent;
public sealed record LegacyActivateFixedActionIntent(string ActionId) : LegacyUiIntent;
@@ -180,12 +191,19 @@ public sealed record LegacyMoveOperatorCatalogDraftRowIntent(
string RowId,
LegacyOperatorCatalogMoveDirection Direction) : LegacyUiIntent;
public sealed record LegacyReorderOperatorCatalogDraftRowIntent(
string SourceRowId,
string TargetRowId,
LegacyDragDropPosition Position) : LegacyUiIntent;
public sealed record LegacyRemoveOperatorCatalogDraftRowIntent(string RowId) : LegacyUiIntent;
public sealed record LegacySetOperatorCatalogDraftBuyAmountIntent(
string RowId,
decimal BuyAmount) : LegacyUiIntent;
public sealed record LegacyCheckOperatorCatalogThemeNameIntent(string Name) : LegacyUiIntent;
public sealed record LegacySaveOperatorCatalogIntent(string Name) : LegacyUiIntent;
public sealed record LegacyDeleteOperatorCatalogIntent : LegacyUiIntent;
@@ -336,12 +354,14 @@ public static class LegacyBridgeProtocol
"set-all-playlist-enabled" => ParseAllEnabled(payload),
"select-playlist-row" => ParsePlaylistSelection(payload),
"move-selected-playlist-rows" => ParsePlaylistMove(payload),
"reorder-playlist-rows" => ParsePlaylistReorder(payload),
"delete-selected-playlist-rows" => ParseDeleteSelected(payload),
"delete-all-playlist-rows" => ParseDeleteAll(payload),
"toggle-active-playlist-enabled" => ParseToggleActiveEnabled(payload),
"select-playlist-boundary" => ParsePlaylistBoundary(payload),
"select-tab" => ParseTabSelection(payload),
"swap-tabs" => ParseTabSwap(payload),
"hover-swap-tabs" => ParseTabHoverSwap(payload),
"set-moving-averages" => ParseMovingAverages(payload),
"activate-fixed-action" => ParseFixedAction(payload),
"activate-fixed-section" => ParseFixedSection(payload),
@@ -423,9 +443,13 @@ public static class LegacyBridgeProtocol
"activate-operator-catalog-stock" =>
ParseOperatorCatalogStockActivation(payload),
"move-operator-catalog-draft-row" => ParseOperatorCatalogDraftMove(payload),
"reorder-operator-catalog-draft-row" =>
ParseOperatorCatalogDraftReorder(payload),
"remove-operator-catalog-draft-row" => ParseOperatorCatalogDraftRemove(payload),
"set-operator-catalog-draft-buy-amount" =>
ParseOperatorCatalogDraftBuyAmount(payload),
"check-operator-catalog-theme-name" =>
ParseOperatorCatalogThemeNameCheck(payload),
"save-operator-catalog" => ParseOperatorCatalogSave(payload),
"delete-operator-catalog" => ParseOperatorCatalogEmpty(
payload,
@@ -831,6 +855,8 @@ public static class LegacyBridgeProtocol
snapshot.OperatorCatalog.SelectedResultId,
snapshot.OperatorCatalog.CodeLabel,
snapshot.OperatorCatalog.EditorName,
snapshot.OperatorCatalog.ThemeNameAvailability,
snapshot.OperatorCatalog.CheckedThemeName,
draftRows = snapshot.OperatorCatalog.DraftRows.Select(row => new
{
row.RowId,
@@ -853,6 +879,7 @@ public static class LegacyBridgeProtocol
snapshot.OperatorCatalog.SchemaValidated,
snapshot.OperatorCatalog.WritesQuarantined,
snapshot.OperatorCatalog.CanBeginCreate,
snapshot.OperatorCatalog.CanCheckThemeName,
snapshot.OperatorCatalog.CanSave,
snapshot.OperatorCatalog.CanDelete,
snapshot.OperatorCatalog.CanAddStock,
@@ -1136,6 +1163,25 @@ public static class LegacyBridgeProtocol
: null;
}
private static LegacyUiIntent? ParsePlaylistReorder(JsonElement payload)
{
if (!HasOnlyProperties(payload, "sourceRowId", "targetRowId", "position") ||
!TryString(payload, "sourceRowId", 128, out var sourceRowId) ||
!TryString(payload, "targetRowId", 128, out var targetRowId) ||
!IsSafeIdentifier(sourceRowId) ||
!IsSafeIdentifier(targetRowId) ||
string.Equals(sourceRowId, targetRowId, StringComparison.Ordinal) ||
!TryString(payload, "position", 8, out var positionText))
{
return null;
}
var position = ParseDragDropPosition(positionText);
return position.HasValue
? new LegacyReorderPlaylistRowsIntent(sourceRowId, targetRowId, position.Value)
: null;
}
private static LegacyUiIntent? ParseDeleteSelected(JsonElement payload) =>
HasOnlyProperties(payload) ? new LegacyDeleteSelectedPlaylistRowsIntent() : null;
@@ -1174,6 +1220,27 @@ public static class LegacyBridgeProtocol
? new LegacySwapTabsIntent(source, target)
: null;
private static LegacyUiIntent? ParseTabHoverSwap(JsonElement payload)
{
if (!HasOnlyProperties(
payload,
"source",
"target",
"expectedSourceIndex",
"expectedTargetIndex") ||
!TryTabId(payload, "source", out var source) ||
!TryTabId(payload, "target", out var target) ||
source == target ||
!TryInt32(payload, "expectedSourceIndex", 0, 9, out var sourceIndex) ||
!TryInt32(payload, "expectedTargetIndex", 0, 9, out var targetIndex) ||
sourceIndex == targetIndex)
{
return null;
}
return new LegacyHoverSwapTabsIntent(source, target, sourceIndex, targetIndex);
}
private static LegacyUiIntent? ParseMovingAverages(JsonElement payload) =>
HasOnlyProperties(payload, "ma5", "ma20") &&
TryBoolean(payload, "ma5", out var ma5) &&
@@ -1630,6 +1697,28 @@ public static class LegacyBridgeProtocol
: null;
}
private static LegacyUiIntent? ParseOperatorCatalogDraftReorder(JsonElement payload)
{
if (!HasOnlyProperties(payload, "sourceRowId", "targetRowId", "position") ||
!TryString(payload, "sourceRowId", 128, out var sourceRowId) ||
!TryString(payload, "targetRowId", 128, out var targetRowId) ||
!IsSafeIdentifier(sourceRowId) ||
!IsSafeIdentifier(targetRowId) ||
string.Equals(sourceRowId, targetRowId, StringComparison.Ordinal) ||
!TryString(payload, "position", 8, out var positionText))
{
return null;
}
var position = ParseDragDropPosition(positionText);
return position.HasValue
? new LegacyReorderOperatorCatalogDraftRowIntent(
sourceRowId,
targetRowId,
position.Value)
: null;
}
private static LegacyUiIntent? ParseOperatorCatalogDraftRemove(JsonElement payload) =>
HasOnlyProperties(payload, "rowId") &&
TryString(payload, "rowId", 128, out var rowId) &&
@@ -1662,6 +1751,19 @@ public static class LegacyBridgeProtocol
? new LegacySaveOperatorCatalogIntent(name)
: null;
private static LegacyUiIntent? ParseOperatorCatalogThemeNameCheck(JsonElement payload) =>
HasOnlyProperties(payload, "name") &&
TrySafeString(
payload,
"name",
128,
allowEmpty: false,
allowUnderscore: true,
out var name) &&
string.Equals(name, name.Trim(), StringComparison.Ordinal)
? new LegacyCheckOperatorCatalogThemeNameIntent(name)
: null;
private static LegacyUiIntent? ParseNamedPlaylistEmpty(
JsonElement payload,
Func<LegacyUiIntent> factory) =>
@@ -2361,6 +2463,13 @@ public static class LegacyBridgeProtocol
value >= minimum && value <= maximum;
}
private static LegacyDragDropPosition? ParseDragDropPosition(string value) => value switch
{
"before" => LegacyDragDropPosition.Before,
"after" => LegacyDragDropPosition.After,
_ => null
};
private static bool TryInt64(
JsonElement element,
string name,