diff --git a/DeepDrftPublic.Client/Controls/SharePopover.razor b/DeepDrftPublic.Client/Controls/SharePopover.razor index 73980bc..b1843af 100644 --- a/DeepDrftPublic.Client/Controls/SharePopover.razor +++ b/DeepDrftPublic.Client/Controls/SharePopover.razor @@ -6,7 +6,7 @@ Color="Color.Secondary" Disabled="@(!RendererInfo.IsInteractive)" OnClick="@Toggle" - aria-label="Share this track" /> + aria-label="@(IsReleaseMode ? "Share this release" : "Share this track")" /> @@ -31,31 +31,35 @@ } - - - - - @if (_embed) + @* Embed is a single-track affordance only; a release page is not a single-track embed (§3b.3). *@ + @if (!IsReleaseMode) { - - - - - @if (_embedCopied) - { - Copied! - } + + + + + @if (_embed) + { + + + + + @if (_embedCopied) + { + Copied! + } + - + } } diff --git a/DeepDrftPublic.Client/Controls/SharePopover.razor.cs b/DeepDrftPublic.Client/Controls/SharePopover.razor.cs index 111f766..a6217c3 100644 --- a/DeepDrftPublic.Client/Controls/SharePopover.razor.cs +++ b/DeepDrftPublic.Client/Controls/SharePopover.razor.cs @@ -1,20 +1,35 @@ +using DeepDrftModels.Enums; +using DeepDrftPublic.Client.Common; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace DeepDrftPublic.Client.Controls; /// -/// Share affordance for the track detail page: a popover offering a canonical-link copy -/// and an optional iframe embed snippet. Clipboard writes go through navigator.clipboard; -/// each copy shows a transient "Copied!" confirmation that resets after a short delay. +/// Share affordance with two modes from one source of clipboard/popover-chrome logic +/// (Phase 11 §3b). Track mode ( set) offers a canonical-link copy plus an +/// optional iframe embed snippet. Release mode ( 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. /// public partial class SharePopover : ComponentBase, IDisposable { + /// Track mode: the vault entry key of the track to share. Mutually exclusive with the release target. [Parameter] public string? EntryKey { get; set; } + /// Release mode: the release id to share. When set (with ), the popover shares the release detail URL and omits the embed option. + [Parameter] public long? ReleaseId { get; set; } + + /// Release mode: the medium of the release, used to resolve its canonical detail route. + [Parameter] public ReleaseMedium ReleaseMedium { get; set; } + [Inject] public required NavigationManager Navigation { get; set; } [Inject] public required IJSRuntime JS { get; set; } + private bool IsReleaseMode => ReleaseId is not null; + private bool _open; private bool _embed; 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 EmbedSnippet => @@ -43,7 +65,7 @@ public partial class SharePopover : ComponentBase, IDisposable private async Task CopyLink() { - if (await CopyToClipboard(TrackUrl)) + if (await CopyToClipboard(LinkUrl)) { _linkCopied = true; await ResetAfterDelay(() => _linkCopied = false); diff --git a/DeepDrftPublic.Client/Pages/CutDetail.razor b/DeepDrftPublic.Client/Pages/CutDetail.razor index a08f561..2500049 100644 --- a/DeepDrftPublic.Client/Pages/CutDetail.razor +++ b/DeepDrftPublic.Client/Pages/CutDetail.razor @@ -79,10 +79,8 @@ else Play - @if (firstTrack is not null) - { - - } + @* Release-mode share: copies the canonical /cuts/{id} URL, not a single track (§3b). *@ +