Skip to content

Commit

Permalink
feat(sponsorblock/chapters): Add SponsorBlock chapters model
Browse files Browse the repository at this point in the history
  • Loading branch information
angelobreuer committed Feb 27, 2024
1 parent 5de0473 commit b9c8f57
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/Lavalink4NET.Integrations.SponsorBlock/Chapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Lavalink4NET.Integrations.SponsorBlock;

using System;

public sealed record class Chapter(
string Name,
TimeSpan Start,
TimeSpan End,
TimeSpan Duration);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Lavalink4NET.Integrations.SponsorBlock.Events;

using System;

public sealed class ChapterStartedEventArgs
{
public ChapterStartedEventArgs(ulong guildId, Chapter chapter)
{
ArgumentNullException.ThrowIfNull(chapter);

GuildId = guildId;
Chapter = chapter;
}

public ulong GuildId { get; }

public Chapter Chapter { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Lavalink4NET.Integrations.SponsorBlock.Events;

using System;
using System.Collections.Immutable;

public sealed class ChaptersLoadedEventArgs : EventArgs
{
public ChaptersLoadedEventArgs(ulong guildId, ImmutableArray<Chapter> chapters)
{
GuildId = guildId;
Chapters = chapters;
}

public ulong GuildId { get; }

public ImmutableArray<Chapter> Chapters { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Lavalink4NET.Integrations.SponsorBlock.Payloads;

using System.Text.Json.Serialization;
using Lavalink4NET.Protocol.Converters;
using Lavalink4NET.Protocol.Payloads;

public sealed record class ChapterStartedEventPayload(
#if NET7_0_OR_GREATER
[property: JsonRequired]
#endif
[property: JsonPropertyName("guildId")]
[property: JsonConverter(typeof(SnowflakeJsonConverter))]
ulong GuildId,

#if NET7_0_OR_GREATER
[property: JsonRequired]
#endif
[property: JsonPropertyName("chapter")]
ChapterModel Chapter) : IEventPayload;
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
namespace Lavalink4NET.Integrations.SponsorBlock.Payloads;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

internal class ChaptersLoadedEventPayload
{
}
using System.Collections.Immutable;
using System.Text.Json.Serialization;
using Lavalink4NET.Protocol.Converters;
using Lavalink4NET.Protocol.Payloads;

public sealed record class ChaptersLoadedEventPayload(
#if NET7_0_OR_GREATER
[property: JsonRequired]
#endif
[property: JsonPropertyName("guildId")]
[property: JsonConverter(typeof(SnowflakeJsonConverter))]
ulong GuildId,

#if NET7_0_OR_GREATER
[property: JsonRequired]
#endif
[property: JsonPropertyName("chapters")]
ImmutableArray<ChapterModel> Chapters) : IEventPayload;
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public interface ISponsorBlockPlayerListener : ILavalinkPlayerListener
ValueTask NotifySegmentSkippedAsync(Segment segment, CancellationToken cancellationToken = default);

ValueTask NotifySegmentsLoadedAsync(ImmutableArray<Segment> segments, CancellationToken cancellationToken = default);

ValueTask NotifyChapterStartedAsync(Chapter chapter, CancellationToken cancellationToken = default);

ValueTask NotifyChaptersLoadedAsync(ImmutableArray<Chapter> chapters, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ static SponsorBlockIntegration()
// Register events
PayloadJsonConverter.RegisterEvent("SegmentsLoaded", SponsorBlockJsonSerializerContext.Default.SegmentsLoadedEventPayload);
PayloadJsonConverter.RegisterEvent("SegmentSkipped", SponsorBlockJsonSerializerContext.Default.SegmentSkippedEventPayload);
PayloadJsonConverter.RegisterEvent("ChaptersLoaded", SponsorBlockJsonSerializerContext.Default.ChaptersLoadedEventPayload);
PayloadJsonConverter.RegisterEvent("ChapterStarted", SponsorBlockJsonSerializerContext.Default.ChapterStartedEventPayload);
}

public SponsorBlockIntegration(IAudioService audioService)
Expand All @@ -35,6 +37,10 @@ public SponsorBlockIntegration(IAudioService audioService)

public event AsyncEventHandler<SegmentsLoadedEventArgs>? SegmentsLoaded;

public event AsyncEventHandler<ChapterStartedEventArgs>? ChapterStarted;

public event AsyncEventHandler<ChaptersLoadedEventArgs>? ChaptersLoaded;

async ValueTask ILavalinkIntegration.ProcessPayloadAsync(IPayload payload, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand All @@ -45,6 +51,12 @@ async ValueTask ILavalinkIntegration.ProcessPayloadAsync(IPayload payload, Cance
StartOffset: model.StartOffset,
EndOffset: model.EndOffset);

static Chapter CreateChapter(ChapterModel model) => new(
Name: model.Name,
Start: model.Start,
End: model.End,
Duration: model.Duration);

if (payload is SegmentSkippedEventPayload segmentSkippedEventPayload)
{
var segment = CreateSegment(segmentSkippedEventPayload.Segment);
Expand Down Expand Up @@ -92,5 +104,53 @@ await playerListener
.ConfigureAwait(false);
}
}

if (payload is ChaptersLoadedEventPayload chaptersLoadedEventPayload)
{
var chapters = chaptersLoadedEventPayload.Chapters.Select(CreateChapter).ToImmutableArray();

var eventArgs = new ChaptersLoadedEventArgs(
guildId: chaptersLoadedEventPayload.GuildId,
chapters: chapters);

await ChaptersLoaded
.InvokeAsync(this, eventArgs)
.ConfigureAwait(false);

var player = await _audioService.Players
.GetPlayerAsync(chaptersLoadedEventPayload.GuildId, cancellationToken)
.ConfigureAwait(false);

if (player is ISponsorBlockPlayerListener playerListener)
{
await playerListener
.NotifyChaptersLoadedAsync(chapters, cancellationToken)
.ConfigureAwait(false);
}
}

if (payload is ChapterStartedEventPayload chapterStartedEventPayload)
{
var chapter = CreateChapter(chapterStartedEventPayload.Chapter);

var eventArgs = new ChapterStartedEventArgs(
guildId: chapterStartedEventPayload.GuildId,
chapter: chapter);

await ChapterStarted
.InvokeAsync(this, eventArgs)
.ConfigureAwait(false);

var player = await _audioService.Players
.GetPlayerAsync(chapterStartedEventPayload.GuildId, cancellationToken)
.ConfigureAwait(false);

if (player is ISponsorBlockPlayerListener playerListener)
{
await playerListener
.NotifyChapterStartedAsync(chapter, cancellationToken)
.ConfigureAwait(false);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
[JsonSerializable(typeof(ImmutableArray<SegmentCategory>))]
[JsonSerializable(typeof(SegmentsLoadedEventPayload))]
[JsonSerializable(typeof(SegmentSkippedEventPayload))]
[JsonSerializable(typeof(ChaptersLoadedEventPayload))]
[JsonSerializable(typeof(ChapterStartedEventPayload))]
internal sealed partial class SponsorBlockJsonSerializerContext : JsonSerializerContext
{
}

0 comments on commit b9c8f57

Please sign in to comment.