feat(phase-16): anonymous play & share telemetry substrate (wave 16.1)
Player-service play-session tracker (floor + 3-bucket classify), SharePopover share tracker with debounce, sendBeacon interop, proxied rate-limited POST api/event/{play,share}, append-only event logs + incremental play_counter with server-side release resolution. Migration authored, not applied. No anonId, no read surface.
This commit is contained in:
@@ -10,6 +10,8 @@ public partial class AudioPlayerProvider : ComponentBase, IAsyncDisposable
|
||||
[Inject] public required AudioInteropService AudioInterop { get; set; }
|
||||
[Inject] public required TrackMediaClient TrackMediaClient { get; set; }
|
||||
[Inject] public required ILogger<StreamingAudioPlayerService> Logger { get; set; }
|
||||
[Inject] public required BeaconInterop Beacon { get; set; }
|
||||
[Inject] public required IPlayEventSink PlayEventSink { get; set; }
|
||||
|
||||
private IStreamingPlayerService? _audioPlayerService;
|
||||
private QueueService? _queueService;
|
||||
@@ -23,7 +25,16 @@ public partial class AudioPlayerProvider : ComponentBase, IAsyncDisposable
|
||||
// EnsureInitializedAsync — that path is correct because audio contexts
|
||||
// require a user gesture anyway. Initializing eagerly here causes 4+
|
||||
// SignalR round-trips before any content is stable.
|
||||
_audioPlayerService = new StreamingAudioPlayerService(AudioInterop, TrackMediaClient, Logger);
|
||||
var player = new StreamingAudioPlayerService(AudioInterop, TrackMediaClient, Logger);
|
||||
|
||||
// Phase 16: bind the play-session tracker to the player after construction, the same way the
|
||||
// queue binds — the player is built with `new`, not DI, so threading telemetry through its
|
||||
// constructor would force the provider to over-resolve. The tracker owns the floor/bucket logic
|
||||
// and emits via the injected sink (the beacon in production); the beacon also drives the
|
||||
// page-unload close so a mid-play tab-close still records the listen. Attached on the concrete
|
||||
// type before it is exposed through the IStreamingPlayerService field.
|
||||
player.AttachTracker(new PlayTracker(PlayEventSink), Beacon);
|
||||
_audioPlayerService = player;
|
||||
|
||||
// Provider is the SOLE owner of OnStateChanged. When the service fires,
|
||||
// the provider re-renders, which cascades to its children automatically.
|
||||
|
||||
Reference in New Issue
Block a user