feat: restore legacy drag events and Tornado launch integration
This commit is contained in:
@@ -23,6 +23,12 @@ public enum LegacyPlaylistMoveDirection
|
||||
Down
|
||||
}
|
||||
|
||||
public enum LegacyDragDropPosition
|
||||
{
|
||||
Before,
|
||||
After
|
||||
}
|
||||
|
||||
public enum LegacyOperatorTabId
|
||||
{
|
||||
Overseas,
|
||||
@@ -549,6 +555,29 @@ public sealed class LegacyOperatorController
|
||||
return await SelectTabAsync(source, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public Task<LegacyOperatorSnapshot> SwapTabsAtExpectedPositionsAsync(
|
||||
LegacyOperatorTabId source,
|
||||
LegacyOperatorTabId target,
|
||||
int expectedSourceIndex,
|
||||
int expectedTargetIndex,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (source == target ||
|
||||
expectedSourceIndex < 0 || expectedSourceIndex >= _tabOrder.Count ||
|
||||
expectedTargetIndex < 0 || expectedTargetIndex >= _tabOrder.Count ||
|
||||
expectedSourceIndex == expectedTargetIndex ||
|
||||
_tabOrder[expectedSourceIndex] != source ||
|
||||
_tabOrder[expectedTargetIndex] != target)
|
||||
{
|
||||
return Task.FromResult(CreateSnapshot());
|
||||
}
|
||||
|
||||
// The expected positions make a repeated dragover message idempotent. Once
|
||||
// the first message swaps the two tabs, an identical delivery no longer
|
||||
// matches the C#-owned order and therefore cannot swap them back.
|
||||
return SwapTabsAsync(source, target, cancellationToken);
|
||||
}
|
||||
|
||||
public LegacyOperatorSnapshot SetMovingAverages(bool ma5, bool ma20)
|
||||
{
|
||||
var next = new LegacyMovingAverageSelection(ma5, ma20);
|
||||
@@ -831,6 +860,31 @@ public sealed class LegacyOperatorController
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyOperatorSnapshot ReorderOperatorCatalogDraftRow(
|
||||
string sourceRowId,
|
||||
string targetRowId,
|
||||
LegacyDragDropPosition position)
|
||||
{
|
||||
if (_operatorCatalogWorkflow is null)
|
||||
{
|
||||
return ReportError("ThemeA/EList 관리 기능이 구성되지 않았습니다.");
|
||||
}
|
||||
|
||||
var beforeRevision = _operatorCatalogWorkflow.Current.Revision;
|
||||
var reordered = _operatorCatalogWorkflow.ReorderDraftRow(
|
||||
sourceRowId,
|
||||
targetRowId,
|
||||
position);
|
||||
if (reordered.Revision == beforeRevision)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
ApplyOperatorCatalogStatus();
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyOperatorSnapshot SetOperatorCatalogDraftBuyAmount(
|
||||
string rowId,
|
||||
decimal buyAmount)
|
||||
@@ -882,6 +936,23 @@ public sealed class LegacyOperatorController
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public async Task<LegacyOperatorSnapshot> CheckOperatorCatalogThemeNameAsync(
|
||||
string editorName,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_operatorCatalogWorkflow is null)
|
||||
{
|
||||
return ReportError("ThemeA 관리 기능이 구성되지 않았습니다.");
|
||||
}
|
||||
|
||||
await _operatorCatalogWorkflow.CheckThemeNameAvailabilityAsync(
|
||||
editorName,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
ApplyOperatorCatalogStatus();
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public async Task<LegacyOperatorSnapshot> SaveOperatorCatalogAsync(
|
||||
string editorName,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -2769,6 +2840,82 @@ public sealed class LegacyOperatorController
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public LegacyOperatorSnapshot ReorderPlaylistRows(
|
||||
string sourceRowId,
|
||||
string targetRowId,
|
||||
LegacyDragDropPosition position)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(sourceRowId);
|
||||
ArgumentNullException.ThrowIfNull(targetRowId);
|
||||
|
||||
var sourceIndex = FindPlaylistIndex(sourceRowId);
|
||||
var targetIndex = FindPlaylistIndex(targetRowId);
|
||||
if (sourceIndex < 0 || targetIndex < 0 || sourceIndex == targetIndex)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
var sourceWasSelected = _selectedPlaylistRowIds.Contains(sourceRowId);
|
||||
var movingIds = sourceWasSelected
|
||||
? new HashSet<string>(_selectedPlaylistRowIds, StringComparer.Ordinal)
|
||||
: new HashSet<string>([sourceRowId], StringComparer.Ordinal);
|
||||
if (movingIds.Contains(targetRowId))
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
var movingRows = _playlist
|
||||
.Where(row => movingIds.Contains(row.RowId))
|
||||
.ToArray();
|
||||
var remainingRows = _playlist
|
||||
.Where(row => !movingIds.Contains(row.RowId))
|
||||
.ToList();
|
||||
var remainingTargetIndex = remainingRows.FindIndex(row =>
|
||||
string.Equals(row.RowId, targetRowId, StringComparison.Ordinal));
|
||||
if (movingRows.Length == 0 || remainingTargetIndex < 0)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
var insertionIndex = position switch
|
||||
{
|
||||
LegacyDragDropPosition.Before => remainingTargetIndex,
|
||||
LegacyDragDropPosition.After => remainingTargetIndex + 1,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(position), position, null)
|
||||
};
|
||||
remainingRows.InsertRange(insertionIndex, movingRows);
|
||||
|
||||
var orderChanged = !_playlist
|
||||
.Select(static row => row.RowId)
|
||||
.SequenceEqual(
|
||||
remainingRows.Select(static row => row.RowId),
|
||||
StringComparer.Ordinal);
|
||||
var selectionChanged = !sourceWasSelected ||
|
||||
!string.Equals(_activePlaylistRowId, sourceRowId, StringComparison.Ordinal);
|
||||
if (!orderChanged && !selectionChanged)
|
||||
{
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
if (orderChanged)
|
||||
{
|
||||
_playlist.Clear();
|
||||
_playlist.AddRange(remainingRows);
|
||||
}
|
||||
|
||||
if (!sourceWasSelected)
|
||||
{
|
||||
_selectedPlaylistRowIds.Clear();
|
||||
_selectedPlaylistRowIds.Add(sourceRowId);
|
||||
}
|
||||
|
||||
_activePlaylistRowId = sourceRowId;
|
||||
_playlistCursorIndex = FindPlaylistIndex(sourceRowId);
|
||||
_playlistPriorCursorIndex = _playlistCursorIndex;
|
||||
Touch();
|
||||
return CreateSnapshot();
|
||||
}
|
||||
|
||||
public async Task<LegacyOperatorSnapshot> RefreshNamedPlaylistsAsync(
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user