[Feature] Add modify current guild member support (#3196)
* refactors & add `ModifyCurrentUserAsync` * i mean, it said "remove", so I removed it
This commit is contained in:
@@ -1475,5 +1475,10 @@ namespace Discord
|
||||
/// Gets a mapping of role IDs to the number of users that have each role.
|
||||
/// </summary>
|
||||
Task<ImmutableDictionary<ulong, int>> GetRoleUserCountsAsync(RequestOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the current user in this guild.
|
||||
/// </summary>
|
||||
Task ModifyCurrentUserAsync(Action<SelfGuildUserProperties> props, RequestOptions options = null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Discord;
|
||||
|
||||
/// <summary>
|
||||
/// Represents properties used to modify the current user's guild-specific information.
|
||||
/// </summary>
|
||||
public class SelfGuildUserProperties : GuildUserProperties
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the banner image of the current user.
|
||||
/// </summary>
|
||||
public Optional<Image?> Banner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the avatar image of the current user.
|
||||
/// </summary>
|
||||
public Optional<Image?> Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user's biography text.
|
||||
/// </summary>
|
||||
public Optional<string> Bio { get; set; }
|
||||
}
|
||||
18
src/Discord.Net.Rest/API/Rest/ModifyCurrentMemberParams.cs
Normal file
18
src/Discord.Net.Rest/API/Rest/ModifyCurrentMemberParams.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Rest;
|
||||
|
||||
internal class ModifyCurrentMemberParams
|
||||
{
|
||||
[JsonProperty("nick")]
|
||||
public Optional<string> Nickname { get; set; }
|
||||
|
||||
[JsonProperty("banner")]
|
||||
public Optional<Image?> Banner { get; set; }
|
||||
|
||||
[JsonProperty("avatar")]
|
||||
public Optional<Image?> Avatar { get; set; }
|
||||
|
||||
[JsonProperty("bio")]
|
||||
public Optional<string> Bio { get; set; }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Rest
|
||||
{
|
||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
||||
internal class ModifyCurrentUserNickParams
|
||||
{
|
||||
[JsonProperty("nick")]
|
||||
public string Nickname { get; }
|
||||
|
||||
public ModifyCurrentUserNickParams(string nickname)
|
||||
{
|
||||
Nickname = nickname;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,28 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Discord.API.Rest
|
||||
{
|
||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
||||
namespace Discord.API.Rest;
|
||||
|
||||
internal class ModifyGuildMemberParams
|
||||
{
|
||||
[JsonProperty("mute")]
|
||||
public Optional<bool> Mute { get; set; }
|
||||
|
||||
[JsonProperty("deaf")]
|
||||
public Optional<bool> Deaf { get; set; }
|
||||
|
||||
[JsonProperty("nick")]
|
||||
public Optional<string> Nickname { get; set; }
|
||||
|
||||
[JsonProperty("roles")]
|
||||
public Optional<ulong[]> RoleIds { get; set; }
|
||||
|
||||
[JsonProperty("channel_id")]
|
||||
public Optional<ulong?> ChannelId { get; set; }
|
||||
|
||||
[JsonProperty("communication_disabled_until")]
|
||||
public Optional<DateTimeOffset?> TimedOutUntil { get; set; }
|
||||
|
||||
[JsonProperty("flags")]
|
||||
public Optional<GuildUserFlags> Flags { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2022,7 +2022,7 @@ namespace Discord.API
|
||||
return SendAsync("DELETE", () => $"guilds/{guildId}/members/{userId}", ids, options: options);
|
||||
}
|
||||
|
||||
public async Task ModifyGuildMemberAsync(ulong guildId, ulong userId, Rest.ModifyGuildMemberParams args, RequestOptions options = null)
|
||||
public async Task ModifyGuildMemberAsync(ulong guildId, ulong userId, ModifyGuildMemberParams args, RequestOptions options = null)
|
||||
{
|
||||
Preconditions.NotEqual(guildId, 0, nameof(guildId));
|
||||
Preconditions.NotEqual(userId, 0, nameof(userId));
|
||||
@@ -2030,17 +2030,19 @@ namespace Discord.API
|
||||
options = RequestOptions.CreateOrClone(options);
|
||||
|
||||
bool isCurrentUser = userId == CurrentUserId;
|
||||
|
||||
if (isCurrentUser && args.Nickname.IsSpecified)
|
||||
{
|
||||
var nickArgs = new Rest.ModifyCurrentUserNickParams(args.Nickname.Value ?? "");
|
||||
await ModifyMyNickAsync(guildId, nickArgs).ConfigureAwait(false);
|
||||
args.Nickname = Optional.Create<string>(); //Remove
|
||||
var nickArgs = new ModifyCurrentMemberParams
|
||||
{
|
||||
Nickname = args.Nickname
|
||||
};
|
||||
await ModifyCurrentMemberAsync(guildId, nickArgs).ConfigureAwait(false);
|
||||
args.Nickname = Optional.Create<string>(); // Remove so it's not getting updated again
|
||||
}
|
||||
if (!isCurrentUser || args.Deaf.IsSpecified || args.Mute.IsSpecified || args.RoleIds.IsSpecified)
|
||||
{
|
||||
var ids = new BucketIds(guildId: guildId);
|
||||
await SendJsonAsync("PATCH", () => $"guilds/{guildId}/members/{userId}", args, ids, options: options).ConfigureAwait(false);
|
||||
await SendJsonAsync<GuildMember>("PATCH", () => $"guilds/{guildId}/members/{userId}", args, ids, options: options).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2454,14 +2456,14 @@ namespace Discord.API
|
||||
return SendJsonAsync<User>("PATCH", () => "users/@me", args, new BucketIds(), options: options);
|
||||
}
|
||||
|
||||
public Task ModifyMyNickAsync(ulong guildId, Rest.ModifyCurrentUserNickParams args, RequestOptions options = null)
|
||||
public Task<GuildMember> ModifyCurrentMemberAsync(ulong guildId, ModifyCurrentMemberParams args, RequestOptions options = null)
|
||||
{
|
||||
Preconditions.NotNull(args, nameof(args));
|
||||
Preconditions.NotNull(args.Nickname, nameof(args.Nickname));
|
||||
|
||||
options = RequestOptions.CreateOrClone(options);
|
||||
|
||||
var ids = new BucketIds(guildId: guildId);
|
||||
return SendJsonAsync("PATCH", () => $"guilds/{guildId}/members/@me/nick", args, ids, options: options);
|
||||
return SendJsonAsync<GuildMember>("PATCH", () => $"guilds/{guildId}/members/@me", args, ids, options: options);
|
||||
}
|
||||
|
||||
public Task<Channel> CreateDMChannelAsync(CreateDMChannelParams args, RequestOptions options = null)
|
||||
|
||||
@@ -991,6 +991,15 @@ namespace Discord.Rest
|
||||
/// <inheritdoc />
|
||||
public Task<MemberSearchResult> SearchUsersAsyncV2(int limit = DiscordConfig.MaxUsersPerBatch, MemberSearchPropertiesV2 args = null, RequestOptions options = null)
|
||||
=> GuildHelper.SearchUsersAsyncV2(this, Discord, limit, args, options);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ModifyCurrentUserAsync(Action<SelfGuildUserProperties> props, RequestOptions options = null)
|
||||
{
|
||||
var args = new SelfGuildUserProperties();
|
||||
props(args);
|
||||
return UserHelper.ModifyCurrentUserAsync(this, Discord.CurrentUser, Discord, args, options);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Audit logs
|
||||
|
||||
@@ -148,7 +148,10 @@ namespace Discord.Rest
|
||||
/// <inheritdoc />
|
||||
public async Task ModifyAsync(Action<GuildUserProperties> func, RequestOptions options = null)
|
||||
{
|
||||
var args = await UserHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
|
||||
var args = new GuildUserProperties();
|
||||
func(args);
|
||||
|
||||
args = await UserHelper.ModifyAsync(Guild, this, Discord, args, options).ConfigureAwait(false);
|
||||
if (args.Deaf.IsSpecified)
|
||||
IsDeafened = args.Deaf.Value;
|
||||
if (args.Mute.IsSpecified)
|
||||
|
||||
@@ -26,16 +26,14 @@ namespace Discord.Rest
|
||||
|
||||
return client.ApiClient.ModifySelfAsync(apiArgs, options);
|
||||
}
|
||||
public static async Task<GuildUserProperties> ModifyAsync(IGuildUser user, BaseDiscordClient client, Action<GuildUserProperties> func,
|
||||
|
||||
public static async Task<GuildUserProperties> ModifyAsync(IGuild guild, IUser user, BaseDiscordClient client, GuildUserProperties args,
|
||||
RequestOptions options)
|
||||
{
|
||||
var args = new GuildUserProperties();
|
||||
func(args);
|
||||
|
||||
if (args.TimedOutUntil.IsSpecified && args.TimedOutUntil.Value.Value.Offset > (new TimeSpan(28, 0, 0, 0)))
|
||||
throw new ArgumentOutOfRangeException(nameof(args.TimedOutUntil), "Offset cannot be more than 28 days from the current date.");
|
||||
|
||||
var apiArgs = new API.Rest.ModifyGuildMemberParams
|
||||
var apiArgs = new ModifyGuildMemberParams
|
||||
{
|
||||
Deaf = args.Deaf,
|
||||
Mute = args.Mute,
|
||||
@@ -59,13 +57,33 @@ namespace Discord.Rest
|
||||
* string.Empty ("") is the only way to reset the user nick in the API,
|
||||
* a value of null does not. This is a workaround.
|
||||
*/
|
||||
if (apiArgs.Nickname.IsSpecified && apiArgs.Nickname.Value == null)
|
||||
if (apiArgs.Nickname is { IsSpecified: true, Value: null })
|
||||
apiArgs.Nickname = new Optional<string>(string.Empty);
|
||||
|
||||
await client.ApiClient.ModifyGuildMemberAsync(user.GuildId, user.Id, apiArgs, options).ConfigureAwait(false);
|
||||
await client.ApiClient.ModifyGuildMemberAsync(guild.Id, user.Id, apiArgs, options).ConfigureAwait(false);
|
||||
return args;
|
||||
}
|
||||
|
||||
public static async Task ModifyCurrentUserAsync(IGuild guild, IUser user, BaseDiscordClient client, SelfGuildUserProperties args, RequestOptions options)
|
||||
{
|
||||
if (args.Nickname.IsSpecified || args.Avatar.IsSpecified || args.Banner.IsSpecified || args.Bio.IsSpecified)
|
||||
{
|
||||
var props = new ModifyCurrentMemberParams
|
||||
{
|
||||
Nickname = args.Nickname,
|
||||
Avatar = args.Avatar.IsSpecified ? args.Avatar.Value?.ToModel() : Optional<ImageModel?>.Unspecified,
|
||||
Banner = args.Banner.IsSpecified ? args.Banner.Value?.ToModel() : Optional<ImageModel?>.Unspecified,
|
||||
Bio = args.Bio
|
||||
};
|
||||
|
||||
await client.ApiClient.ModifyCurrentMemberAsync(guild.Id, props, options).ConfigureAwait(false);
|
||||
|
||||
args.Nickname = Optional<string>.Unspecified;
|
||||
}
|
||||
|
||||
await ModifyAsync(guild, user, client, args, options);
|
||||
}
|
||||
|
||||
public static Task KickAsync(IGuildUser user, BaseDiscordClient client, string reason, RequestOptions options)
|
||||
=> client.ApiClient.RemoveGuildMemberAsync(user.GuildId, user.Id, reason, options);
|
||||
|
||||
|
||||
@@ -1343,6 +1343,15 @@ namespace Discord.WebSocket
|
||||
/// <inheritdoc />
|
||||
public Task<MemberSearchResult> SearchUsersAsyncV2(int limit = DiscordConfig.MaxUsersPerBatch, MemberSearchPropertiesV2 args = null, RequestOptions options = null)
|
||||
=> GuildHelper.SearchUsersAsyncV2(this, Discord, limit, args, options);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ModifyCurrentUserAsync(Action<SelfGuildUserProperties> props, RequestOptions options = null)
|
||||
{
|
||||
var args = new SelfGuildUserProperties();
|
||||
props(args);
|
||||
return UserHelper.ModifyCurrentUserAsync(this, Discord.CurrentUser, Discord, args, options);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Guild Events
|
||||
|
||||
@@ -241,7 +241,12 @@ namespace Discord.WebSocket
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ModifyAsync(Action<GuildUserProperties> func, RequestOptions options = null)
|
||||
=> UserHelper.ModifyAsync(this, Discord, func, options);
|
||||
{
|
||||
var args = new GuildUserProperties();
|
||||
func(args);
|
||||
return UserHelper.ModifyAsync(Guild, this, Discord, args, options);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task KickAsync(string reason = null, RequestOptions options = null)
|
||||
=> UserHelper.KickAsync(this, Discord, reason, options);
|
||||
|
||||
Reference in New Issue
Block a user