Merge p11-w3-t2-release-share into dev (P11 11.E: release-keyed SharePopover mode, Cut header Share)
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
Color="Color.Secondary"
|
Color="Color.Secondary"
|
||||||
Disabled="@(!RendererInfo.IsInteractive)"
|
Disabled="@(!RendererInfo.IsInteractive)"
|
||||||
OnClick="@Toggle"
|
OnClick="@Toggle"
|
||||||
aria-label="Share this track" />
|
aria-label="@(IsReleaseMode ? "Share this release" : "Share this track")" />
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
|
|
||||||
<MudOverlay Visible="@_open" OnClick="@Close" AutoClose="true" />
|
<MudOverlay Visible="@_open" OnClick="@Close" AutoClose="true" />
|
||||||
@@ -31,31 +31,35 @@
|
|||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|
||||||
<MudDivider />
|
@* Embed is a single-track affordance only; a release page is not a single-track embed (§3b.3). *@
|
||||||
|
@if (!IsReleaseMode)
|
||||||
<MudCheckBox @bind-Value="Embed" Color="Color.Primary" Label="Embed player" Dense="true" />
|
|
||||||
|
|
||||||
@if (_embed)
|
|
||||||
{
|
{
|
||||||
<MudStack Row AlignItems="AlignItems.Center" Spacing="1">
|
<MudDivider />
|
||||||
<MudTextField Value="@EmbedSnippet"
|
|
||||||
T="string"
|
<MudCheckBox @bind-Value="Embed" Color="Color.Primary" Label="Embed player" Dense="true" />
|
||||||
ReadOnly="true"
|
|
||||||
Variant="Variant.Outlined"
|
@if (_embed)
|
||||||
Lines="3"
|
{
|
||||||
Margin="Margin.Dense"
|
<MudStack Row AlignItems="AlignItems.Center" Spacing="1">
|
||||||
Class="deepdrft-share-embed-field" />
|
<MudTextField Value="@EmbedSnippet"
|
||||||
<MudStack AlignItems="AlignItems.Center" Spacing="0">
|
T="string"
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy"
|
ReadOnly="true"
|
||||||
Color="Color.Primary"
|
Variant="Variant.Outlined"
|
||||||
OnClick="@CopyEmbed"
|
Lines="3"
|
||||||
aria-label="Copy embed snippet" />
|
Margin="Margin.Dense"
|
||||||
@if (_embedCopied)
|
Class="deepdrft-share-embed-field" />
|
||||||
{
|
<MudStack AlignItems="AlignItems.Center" Spacing="0">
|
||||||
<MudText Typo="Typo.caption" Color="Color.Success">Copied!</MudText>
|
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy"
|
||||||
}
|
Color="Color.Primary"
|
||||||
|
OnClick="@CopyEmbed"
|
||||||
|
aria-label="Copy embed snippet" />
|
||||||
|
@if (_embedCopied)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.caption" Color="Color.Success">Copied!</MudText>
|
||||||
|
}
|
||||||
|
</MudStack>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
</MudStack>
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|||||||
@@ -1,20 +1,35 @@
|
|||||||
|
using DeepDrftModels.Enums;
|
||||||
|
using DeepDrftPublic.Client.Common;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
|
|
||||||
namespace DeepDrftPublic.Client.Controls;
|
namespace DeepDrftPublic.Client.Controls;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Share affordance for the track detail page: a popover offering a canonical-link copy
|
/// Share affordance with two modes from one source of clipboard/popover-chrome logic
|
||||||
/// and an optional iframe embed snippet. Clipboard writes go through navigator.clipboard;
|
/// (Phase 11 §3b). Track mode (<see cref="EntryKey"/> set) offers a canonical-link copy plus an
|
||||||
/// each copy shows a transient "Copied!" confirmation that resets after a short delay.
|
/// optional iframe embed snippet. Release mode (<see cref="ReleaseId"/> set) is copy-link-only —
|
||||||
|
/// it copies the absolute form of the release's canonical detail URL and hides the embed
|
||||||
|
/// affordance, since a release page is not a single-track embed. Clipboard writes go through
|
||||||
|
/// navigator.clipboard; each copy shows a transient "Copied!" confirmation that resets after a
|
||||||
|
/// short delay.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SharePopover : ComponentBase, IDisposable
|
public partial class SharePopover : ComponentBase, IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>Track mode: the vault entry key of the track to share. Mutually exclusive with the release target.</summary>
|
||||||
[Parameter] public string? EntryKey { get; set; }
|
[Parameter] public string? EntryKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Release mode: the release id to share. When set (with <see cref="ReleaseMedium"/>), the popover shares the release detail URL and omits the embed option.</summary>
|
||||||
|
[Parameter] public long? ReleaseId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Release mode: the medium of the release, used to resolve its canonical detail route.</summary>
|
||||||
|
[Parameter] public ReleaseMedium ReleaseMedium { get; set; }
|
||||||
|
|
||||||
[Inject] public required NavigationManager Navigation { get; set; }
|
[Inject] public required NavigationManager Navigation { get; set; }
|
||||||
[Inject] public required IJSRuntime JS { get; set; }
|
[Inject] public required IJSRuntime JS { get; set; }
|
||||||
|
|
||||||
|
private bool IsReleaseMode => ReleaseId is not null;
|
||||||
|
|
||||||
private bool _open;
|
private bool _open;
|
||||||
private bool _embed;
|
private bool _embed;
|
||||||
private bool _linkCopied;
|
private bool _linkCopied;
|
||||||
@@ -32,6 +47,13 @@ public partial class SharePopover : ComponentBase, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The URL "Copy link" places on the clipboard. Release mode resolves the canonical detail
|
||||||
|
// route (which carries a leading slash) and composes it against BaseUri (which carries a
|
||||||
|
// trailing slash) — trim one to avoid a doubled separator.
|
||||||
|
private string LinkUrl => IsReleaseMode
|
||||||
|
? $"{Navigation.BaseUri.TrimEnd('/')}{ReleaseRoutes.DetailHref(ReleaseId!.Value, ReleaseMedium)}"
|
||||||
|
: TrackUrl;
|
||||||
|
|
||||||
private string TrackUrl => $"{Navigation.BaseUri}track/{EntryKey}";
|
private string TrackUrl => $"{Navigation.BaseUri}track/{EntryKey}";
|
||||||
|
|
||||||
private string EmbedSnippet =>
|
private string EmbedSnippet =>
|
||||||
@@ -43,7 +65,7 @@ public partial class SharePopover : ComponentBase, IDisposable
|
|||||||
|
|
||||||
private async Task CopyLink()
|
private async Task CopyLink()
|
||||||
{
|
{
|
||||||
if (await CopyToClipboard(TrackUrl))
|
if (await CopyToClipboard(LinkUrl))
|
||||||
{
|
{
|
||||||
_linkCopied = true;
|
_linkCopied = true;
|
||||||
await ResetAfterDelay(() => _linkCopied = false);
|
await ResetAfterDelay(() => _linkCopied = false);
|
||||||
|
|||||||
@@ -79,10 +79,8 @@ else
|
|||||||
Play
|
Play
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
|
||||||
@if (firstTrack is not null)
|
@* Release-mode share: copies the canonical /cuts/{id} URL, not a single track (§3b). *@
|
||||||
{
|
<SharePopover ReleaseId="@release.Id" ReleaseMedium="@release.Medium" />
|
||||||
<SharePopover EntryKey="@firstTrack.EntryKey" />
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user