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). *@
+