* Initial Spotify support * Remove GameAsset#ToEntity - appId doesn't seem to be necessary, and Spotify Game doesn't return appId either. * Implement SpotifyGame details * Implement song Duration prop * Add album art CDN * Fix ActivityType * Remove payload debug * Add changes according to review + Make `ApplicationId` nullable + Move ctor after propspull/986/head
@@ -1,4 +1,4 @@ | |||||
using System.Diagnostics; | |||||
using System.Diagnostics; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
@@ -1,15 +1,15 @@ | |||||
namespace Discord | |||||
namespace Discord | |||||
{ | { | ||||
public class GameAsset | public class GameAsset | ||||
{ | { | ||||
internal GameAsset() { } | internal GameAsset() { } | ||||
internal ulong ApplicationId { get; set; } | |||||
internal ulong? ApplicationId { get; set; } | |||||
public string Text { get; internal set; } | public string Text { get; internal set; } | ||||
public string ImageId { get; internal set; } | public string ImageId { get; internal set; } | ||||
public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | ||||
=> CDN.GetRichAssetUrl(ApplicationId, ImageId, size, format); | |||||
=> ApplicationId.HasValue ? CDN.GetRichAssetUrl(ApplicationId.Value, ImageId, size, format) : null; | |||||
} | } | ||||
} | |||||
} |
@@ -1,4 +1,4 @@ | |||||
using System.Diagnostics; | |||||
using System.Diagnostics; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
@@ -7,8 +7,8 @@ namespace Discord | |||||
{ | { | ||||
internal RichGame() { } | internal RichGame() { } | ||||
public string Details { get; internal set;} | |||||
public string State { get; internal set;} | |||||
public string Details { get; internal set; } | |||||
public string State { get; internal set; } | |||||
public ulong ApplicationId { get; internal set; } | public ulong ApplicationId { get; internal set; } | ||||
public GameAsset SmallAsset { get; internal set; } | public GameAsset SmallAsset { get; internal set; } | ||||
public GameAsset LargeAsset { get; internal set; } | public GameAsset LargeAsset { get; internal set; } | ||||
@@ -19,4 +19,4 @@ namespace Discord | |||||
public override string ToString() => Name; | public override string ToString() => Name; | ||||
private string DebuggerDisplay => $"{Name} (Rich)"; | private string DebuggerDisplay => $"{Name} (Rich)"; | ||||
} | } | ||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Diagnostics; | |||||
namespace Discord | |||||
{ | |||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||||
public class SpotifyGame : Game | |||||
{ | |||||
public string[] Artists { get; internal set; } | |||||
public string AlbumArt { get; internal set; } | |||||
public string AlbumTitle { get; internal set; } | |||||
public string TrackTitle { get; internal set; } | |||||
public string SyncId { get; internal set; } | |||||
public string SessionId { get; internal set; } | |||||
public TimeSpan? Duration { get; internal set; } | |||||
internal SpotifyGame() { } | |||||
public override string ToString() => Name; | |||||
private string DebuggerDisplay => $"{Name} (Spotify)"; | |||||
} | |||||
} |
@@ -1,4 +1,4 @@ | |||||
#pragma warning disable CS1591 | |||||
#pragma warning disable CS1591 | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using Newtonsoft.Json.Serialization; | using Newtonsoft.Json.Serialization; | ||||
using System.Runtime.Serialization; | using System.Runtime.Serialization; | ||||
@@ -29,6 +29,10 @@ namespace Discord.API | |||||
public Optional<API.GameTimestamps> Timestamps { get; set; } | public Optional<API.GameTimestamps> Timestamps { get; set; } | ||||
[JsonProperty("instance")] | [JsonProperty("instance")] | ||||
public Optional<bool> Instance { get; set; } | public Optional<bool> Instance { get; set; } | ||||
[JsonProperty("sync_id")] | |||||
public Optional<string> SyncId { get; set; } | |||||
[JsonProperty("session_id")] | |||||
public Optional<string> SessionId { get; set; } | |||||
[OnError] | [OnError] | ||||
internal void OnError(StreamingContext context, ErrorContext errorContext) | internal void OnError(StreamingContext context, ErrorContext errorContext) | ||||
@@ -4,6 +4,27 @@ namespace Discord.WebSocket | |||||
{ | { | ||||
public static IActivity ToEntity(this API.Game model) | public static IActivity ToEntity(this API.Game model) | ||||
{ | { | ||||
// Spotify Game | |||||
if (model.SyncId.IsSpecified) | |||||
{ | |||||
var assets = model.Assets.GetValueOrDefault()?.ToEntity(); | |||||
string albumText = assets?[1]?.Text; | |||||
string albumArtId = assets?[1]?.ImageId?.Replace("spotify:",""); | |||||
var timestamps = model.Timestamps.IsSpecified ? model.Timestamps.Value.ToEntity() : null; | |||||
return new SpotifyGame | |||||
{ | |||||
Name = model.Name, | |||||
SessionId = model.SessionId.GetValueOrDefault(), | |||||
SyncId = model.SyncId.Value, | |||||
AlbumTitle = albumText, | |||||
TrackTitle = model.Details.GetValueOrDefault(), | |||||
Artists = model.State.GetValueOrDefault()?.Split(';'), | |||||
Duration = timestamps?.End - timestamps?.Start, | |||||
AlbumArt = albumArtId != null ? $"https://i.scdn.co/image/{albumArtId}" : null, | |||||
Type = ActivityType.Listening | |||||
}; | |||||
} | |||||
// Rich Game | // Rich Game | ||||
if (model.ApplicationId.IsSpecified) | if (model.ApplicationId.IsSpecified) | ||||
{ | { | ||||
@@ -34,7 +55,7 @@ namespace Discord.WebSocket | |||||
} | } | ||||
// (Small, Large) | // (Small, Large) | ||||
public static GameAsset[] ToEntity(this API.GameAssets model, ulong appId) | |||||
public static GameAsset[] ToEntity(this API.GameAssets model, ulong? appId = null) | |||||
{ | { | ||||
return new GameAsset[] | return new GameAsset[] | ||||
{ | { | ||||