Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement application emojis #123

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Disqord.Core/Entities/Core/Emoji/IApplicationEmoji.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Disqord.Models;

namespace Disqord;

/// <summary>
/// Represents a custom emoji (e.g. <c>&lt;:professor:667582610431803437&gt;</c>) retrieved from an application.
/// </summary>
public interface IApplicationEmoji : ICustomEmoji, IApplicationEntity, IClientEntity, INamableEntity, IJsonUpdatable<EmojiJsonModel>
{
/// <summary>
/// Gets the user that created this emoji.
/// </summary>
IUser? Creator { get; }

/// <summary>
/// Gets whether this emoji requires colons in chat.
/// </summary>
bool RequiresColons { get; }

/// <summary>
/// Gets whether this emoji is managed by an integration.
/// </summary>
bool IsManaged { get; }
QuantumToasted marked this conversation as resolved.
Show resolved Hide resolved
}
12 changes: 12 additions & 0 deletions src/Disqord.Core/Entities/Core/IApplicationEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Disqord;

/// <summary>
/// Represents a Discord entity that exists within an application.
/// </summary>
public interface IApplicationEntity
QuantumToasted marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Gets the ID of the application this entity is tied to.
/// </summary>
Snowflake ApplicationId { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Disqord.Models;
using Qommon;

namespace Disqord;

public class TransientApplicationEmoji : TransientClientEntity<EmojiJsonModel>, IApplicationEmoji
{
/// <inheritdoc />
public Snowflake Id => Model.Id!.Value;

/// <inheritdoc />
public Snowflake ApplicationId { get; }

/// <inheritdoc cref="INamableEntity.Name"/>
public string Name => Model.Name!;

/// <inheritdoc/>
public bool IsAnimated => Model.Animated.Value;

/// <inheritdoc/>
public IUser? Creator => _creator ??= Optional.ConvertOrDefault(Model.User, static (user, client) => new TransientUser(client, user), Client);

private IUser? _creator;

/// <inheritdoc/>
public bool RequiresColons => Model.RequireColons.Value;

/// <inheritdoc/>
public bool IsManaged => Model.Managed.Value;

/// <inheritdoc/>
public string Tag => ToString();

public TransientApplicationEmoji(IClient client, Snowflake applicationId, EmojiJsonModel model)
: base(client, model)
{
ApplicationId = applicationId;
}

public bool Equals(IEmoji? other)
{
return Comparers.Emoji.Equals(this, other);
}

public bool Equals(ICustomEmoji? other)
{
return Comparers.Emoji.Equals(this, other);
}

public override int GetHashCode()
{
return Comparers.Emoji.GetHashCode(this);
}

public override string ToString()
{
return this.GetString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Disqord.Serialization.Json;

namespace Disqord.Models;

public class ApplicationEmojisJsonModel : JsonModel
{
[JsonProperty("items")]
public EmojiJsonModel[] Items = null!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.IO;
using Disqord.Serialization.Json;

namespace Disqord.Rest.Api;

public class CreateApplicationEmojiJsonRestRequestContent : JsonModelRestRequestContent
{
[JsonProperty("name")]
public string Name;

[JsonProperty("image")]
public Stream Image;

public CreateApplicationEmojiJsonRestRequestContent(string name, Stream image)
{
Name = name;
Image = image;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Disqord.Serialization.Json;
using Qommon;

namespace Disqord.Rest.Api;

public class ModifyApplicationEmojiJsonRestRequestContent : JsonModelRestRequestContent
{
[JsonProperty("name")]
public Optional<string> Name;
}
40 changes: 40 additions & 0 deletions src/Disqord.Rest.Api/Methods/RestApiClientExtensions.Emoji.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@ namespace Disqord.Rest.Api;

public static partial class RestApiClientExtensions
{
public static Task<ApplicationEmojisJsonModel> FetchApplicationEmojisAsync(this IRestApiClient client,
Snowflake applicationId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var route = Format(Route.Emoji.GetApplicationEmojis, applicationId);
return client.ExecuteAsync<ApplicationEmojisJsonModel>(route, null, options, cancellationToken);
}

public static Task<EmojiJsonModel> FetchApplicationEmojiAsync(this IRestApiClient client,
Snowflake applicationId, Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var route = Format(Route.Emoji.GetApplicationEmoji, applicationId, emojiId);
return client.ExecuteAsync<EmojiJsonModel>(route, null, options, cancellationToken);
}

public static Task<EmojiJsonModel> CreateApplicationEmojiAsync(this IRestApiClient client,
Snowflake applicationId, CreateApplicationEmojiJsonRestRequestContent content,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var route = Format(Route.Emoji.CreateApplicationEmoji, applicationId);
return client.ExecuteAsync<EmojiJsonModel>(route, content, options, cancellationToken);
}

public static Task<EmojiJsonModel> ModifyApplicationEmojiAsync(this IRestApiClient client,
Snowflake applicationId, Snowflake emojiId, ModifyApplicationEmojiJsonRestRequestContent content,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var route = Format(Route.Emoji.ModifyApplicationEmoji, applicationId, emojiId);
return client.ExecuteAsync<EmojiJsonModel>(route, content, options, cancellationToken);
}

public static Task DeleteApplicationEmojiAsync(this IRestApiClient client,
Snowflake applicationId, Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var route = Format(Route.Emoji.DeleteApplicationEmoji, applicationId, emojiId);
return client.ExecuteAsync<EmojiJsonModel>(route, null, options, cancellationToken);
}

public static Task<EmojiJsonModel[]> FetchGuildEmojisAsync(this IRestApiClient client,
Snowflake guildId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
Expand Down
10 changes: 10 additions & 0 deletions src/Disqord.Rest.Api/Requests/Routing/Default/Route.Static.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ public static class Channel

public static class Emoji
{
public static readonly Route GetApplicationEmojis = Get("applications/{0:application_id}/emojis");

public static readonly Route GetApplicationEmoji = Get("applications/{0:application_id}/emojis/{1:emoji_id}");

public static readonly Route CreateApplicationEmoji = Post("applications/{0:application_id}/emojis");

public static readonly Route ModifyApplicationEmoji = Patch("applications/{0:application_id}/emojis/{1:emoji_id}");

public static readonly Route DeleteApplicationEmoji = Delete("applications/{0:application_id}/emojis/{1:emoji_id}");

public static readonly Route GetGuildEmojis = Get("guilds/{0:guild_id}/emojis");

public static readonly Route GetGuildEmoji = Get("guilds/{0:guild_id}/emojis/{1:emoji_id}");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Qommon;

namespace Disqord;

public class ModifyApplicationEmojiActionProperties
{
public Optional<string> Name { internal get; set; }

internal ModifyApplicationEmojiActionProperties()
{ }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Disqord.Rest;

public static partial class RestEntityExtensions
{
public static Task<IReadOnlyList<IApplicationEmoji>> FetchEmojisAsync(this IApplication application,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = application.GetRestClient();
return client.FetchApplicationEmojisAsync(application.Id, options, cancellationToken);
}

public static Task<IApplicationEmoji> FetchEmojiAsync(this IApplication application,
Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = application.GetRestClient();
return client.FetchApplicationEmojiAsync(application.Id, emojiId, options, cancellationToken);
}

public static Task<IApplicationEmoji> CreateEmojiAsync(this IApplication application,
string name, Stream image,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = application.GetRestClient();
return client.CreateApplicationEmojiAsync(application.Id, name, image, options, cancellationToken);
}

public static Task<IApplicationEmoji> ModifyEmojiAsync(this IApplication application,
Snowflake emojiId, Action<ModifyApplicationEmojiActionProperties> action,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = application.GetRestClient();
return client.ModifyApplicationEmojiAsync(application.Id, emojiId, action, options, cancellationToken);
}

public static Task DeleteEmojiAsync(this IApplication application,
Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = application.GetRestClient();
return client.DeleteApplicationEmojiAsync(application.Id, emojiId, options, cancellationToken);
}
}
15 changes: 15 additions & 0 deletions src/Disqord.Rest/Extensions/Entity/RestEntityExtensions.Emoji.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ namespace Disqord.Rest;

public static partial class RestEntityExtensions
{
public static Task<IApplicationEmoji> ModifyAsync(this IApplicationEmoji emoji,
Action<ModifyApplicationEmojiActionProperties> action,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = emoji.GetRestClient();
return client.ModifyApplicationEmojiAsync(emoji.ApplicationId, emoji.Id, action, options, cancellationToken);
}

public static Task DeleteAsync(this IApplicationEmoji emoji,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var client = emoji.GetRestClient();
return client.DeleteApplicationEmojiAsync(emoji.ApplicationId, emoji.Id, options, cancellationToken);
}

public static Task<IGuildEmoji> ModifyAsync(this IGuildEmoji emoji,
Action<ModifyGuildEmojiActionProperties> action,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
Expand Down
54 changes: 54 additions & 0 deletions src/Disqord.Rest/Extensions/RestClientExtensions.Emoji.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,60 @@ namespace Disqord.Rest;

public static partial class RestClientExtensions
{
public static async Task<IReadOnlyList<IApplicationEmoji>> FetchApplicationEmojisAsync(this IRestClient client,
Snowflake applicationId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var model = await client.ApiClient.FetchApplicationEmojisAsync(applicationId, options, cancellationToken).ConfigureAwait(false);
return model.Items.ToReadOnlyList((client, applicationId), static (model, state) =>
{
var (client, applicationId) = state;
return new TransientApplicationEmoji(client, applicationId, model);
});
}

public static async Task<IApplicationEmoji> FetchApplicationEmojiAsync(this IRestClient client,
Snowflake applicationId, Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var model = await client.ApiClient.FetchApplicationEmojiAsync(applicationId, emojiId, options, cancellationToken).ConfigureAwait(false);
return new TransientApplicationEmoji(client, applicationId, model);
}

public static async Task<IApplicationEmoji> CreateApplicationEmojiAsync(this IRestClient client,
Snowflake applicationId, string name, Stream image,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
var content = new CreateApplicationEmojiJsonRestRequestContent(name, image);

var model = await client.ApiClient.CreateApplicationEmojiAsync(applicationId, content, options, cancellationToken).ConfigureAwait(false);
return new TransientApplicationEmoji(client, applicationId, model);
}

public static async Task<IApplicationEmoji> ModifyApplicationEmojiAsync(this IRestClient client,
Snowflake applicationId, Snowflake emojiId, Action<ModifyApplicationEmojiActionProperties> action,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
Guard.IsNotNull(action);

var properties = new ModifyApplicationEmojiActionProperties();
action.Invoke(properties);
var content = new ModifyApplicationEmojiJsonRestRequestContent()
{
Name = properties.Name
};

var model = await client.ApiClient.ModifyApplicationEmojiAsync(applicationId, emojiId, content, options, cancellationToken).ConfigureAwait(false);
return new TransientApplicationEmoji(client, applicationId, model);
}

public static Task DeleteApplicationEmojiAsync(this IRestClient client,
Snowflake applicationId, Snowflake emojiId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
{
return client.ApiClient.DeleteApplicationEmojiAsync(applicationId, emojiId, options, cancellationToken);
}

public static async Task<IReadOnlyList<IGuildEmoji>> FetchGuildEmojisAsync(this IRestClient client,
Snowflake guildId,
IRestRequestOptions? options = null, CancellationToken cancellationToken = default)
Expand Down
Loading