feat: restore legacy modal and drag behavior

This commit is contained in:
2026-07-16 01:33:48 +09:00
parent 83398044c6
commit d7ec571343
30 changed files with 3597 additions and 321 deletions

View File

@@ -3374,18 +3374,19 @@ public sealed class LegacyOperatorController
Touch();
return CreateSnapshot();
}
var selectedRevision = selected.NamedPlaylist?.Revision ?? -1;
var saved = await SaveCurrentNamedPlaylistAsync(cancellationToken)
.ConfigureAwait(false);
var succeeded =
(saved.NamedPlaylist?.Revision ?? -1) > selectedRevision &&
string.Equals(
saved.NamedPlaylist?.SelectedDefinitionId,
definitionId,
StringComparison.Ordinal) &&
saved.NamedPlaylist?.LastMutationOutcome is
LegacyNamedPlaylistMutationOutcome.CommittedFresh or
LegacyNamedPlaylistMutationOutcome.CommittedOptimistic &&
saved.StatusKind == LegacyOperatorStatusKind.Information;
LegacyNamedPlaylistMutationOutcome.CommittedOptimistic;
CompleteCommand(command, definitionId, succeeded);
Touch();
return CreateSnapshot();
@@ -3441,6 +3442,88 @@ public sealed class LegacyOperatorController
return CreateSnapshot();
}
/// <summary>
/// Completes a correlated named-playlist command when the native dispatch
/// boundary rejects the request or encounters an unexpected exception.
/// The terminal receipt prevents the WebView modal from waiting indefinitely;
/// the named-playlist workflow remains the authority for any write quarantine
/// that was already latched before the exception escaped.
/// </summary>
public LegacyOperatorSnapshot ReportNamedPlaylistCommandFailure(
string command,
string targetId,
string message)
{
ArgumentException.ThrowIfNullOrWhiteSpace(command);
ArgumentException.ThrowIfNullOrWhiteSpace(targetId);
if (command is not "refresh-named-playlists" and
not "select-named-playlist" and
not "create-named-playlist" and
not "delete-selected-named-playlist" and
not "load-named-playlist-by-id" and
not "save-current-named-playlist-to")
{
throw new ArgumentOutOfRangeException(
nameof(command),
command,
"Only correlated named-playlist commands can be completed here.");
}
CompleteCommand(command, targetId, succeeded: false);
return ReportError(message);
}
public LegacyOperatorSnapshot CompleteNamedPlaylistDispatch(
string command,
string requestId,
bool succeeded)
{
ArgumentException.ThrowIfNullOrWhiteSpace(command);
ArgumentException.ThrowIfNullOrWhiteSpace(requestId);
if (command is not "refresh-named-playlists" and
not "select-named-playlist" and
not "create-named-playlist" and
not "delete-selected-named-playlist")
{
throw new ArgumentOutOfRangeException(
nameof(command),
command,
"The command does not use a named-playlist dispatch id.");
}
CompleteCommand(command, requestId, succeeded);
Touch();
return CreateSnapshot();
}
/// <summary>
/// Terminates an accepted save command without making its database outcome
/// retryable. This is intentionally separate from a known pre-dispatch
/// rejection: an escaped post-dispatch exception permanently quarantines every
/// later named-playlist write in this process.
/// </summary>
public LegacyOperatorSnapshot ReportNamedPlaylistWriteOutcomeUnknown(
string command,
string targetId,
string message)
{
ArgumentException.ThrowIfNullOrWhiteSpace(command);
ArgumentException.ThrowIfNullOrWhiteSpace(targetId);
if (command is not "create-named-playlist" and
not "delete-selected-named-playlist" and
not "save-current-named-playlist-to")
{
throw new ArgumentOutOfRangeException(
nameof(command),
command,
"The command is not a named-playlist write.");
}
_namedPlaylistWorkflow?.QuarantineAmbiguousWriteOutcome();
CompleteCommand(command, targetId, succeeded: false);
return ReportError(message);
}
public LegacyOperatorSnapshot ReportInformation(string message)
{
_statusMessage = message ?? string.Empty;