Skip to content

Commit af1865c

Browse files
committed
refactor modules dependency
1 parent 932f4a6 commit af1865c

35 files changed

Lines changed: 384 additions & 307 deletions

src/Disc.NET.Client.SDK/Client.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
using System.Text;
2-
using Disc.NET.Client.SDK.Interfaces;
1+
using Disc.NET.Client.SDK.Interfaces;
32
using Disc.NET.Client.SDK.Messages;
4-
using Disc.NET.Shared.Configurations;
53
using Disc.NET.Shared.Exceptions;
64
using Disc.NET.Shared.Serializer;
5+
using System.Text;
76

87
namespace Disc.NET.Client.SDK;
98

109
public sealed class Client : ClientBase, IClient
1110
{
12-
private readonly AppConfiguration _appConfiguration;
11+
private readonly ClientConfiguration _clientConfiguration;
1312
private readonly DiscNetSerializer _serializer = DiscNetSerializer.GetInstance();
14-
public Client(AppConfiguration appConfiguration, HttpClient client) : base(appConfiguration, client)
13+
public Client(ClientConfiguration clientConfiguration, HttpClient client) : base(clientConfiguration, client)
1514
{
16-
_appConfiguration = appConfiguration;
15+
_clientConfiguration = clientConfiguration;
1716
}
1817

1918
public async Task SendMessageAsync(string channelId, ApiMessage message, CancellationToken cancellation = default)
@@ -37,13 +36,13 @@ public async Task SendMessageAsync(string channelId, ApiMessage message, Cancell
3736

3837
public async Task RegisterGlobalSlashCommandAsync(string commandJson, CancellationToken cancellation = default)
3938
{
40-
await PostAsync(commandJson, $"applications/{_appConfiguration.ApplicationId}/commands",
39+
await PostAsync(commandJson, $"applications/{_clientConfiguration.ApplicationId}/commands",
4140
cancellation);
4241
}
4342

4443
public async Task RegisterGuildSlashCommandAsync(string commandJson, string guildId, CancellationToken cancellation = default)
4544
{
46-
await PostAsync(commandJson, $"applications/{_appConfiguration.ApplicationId}/guilds/{guildId}/commands",
45+
await PostAsync(commandJson, $"applications/{_clientConfiguration.ApplicationId}/guilds/{guildId}/commands",
4746
cancellation);
4847
}
4948

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1-
using Disc.NET.Shared.Configurations;
2-
3-
namespace Disc.NET.Client.SDK
1+
namespace Disc.NET.Client.SDK
42
{
53
public abstract class ClientBase
64
{
75

86
protected readonly HttpClient HttpClient;
9-
protected AppConfiguration AppConfiguration { get; }
7+
protected ClientConfiguration ClientConfiguration { get; }
108

11-
12-
protected ClientBase(AppConfiguration appConfiguration, HttpClient client)
9+
protected ClientBase(ClientConfiguration clientConfiguration, HttpClient client)
1310
{
14-
AppConfiguration = appConfiguration;
11+
ClientConfiguration = clientConfiguration;
1512
HttpClient = client;
1613
HttpClient.BaseAddress = new Uri("https://discord.com/api/v10/");
1714
HttpClient.DefaultRequestHeaders.Authorization =
18-
new System.Net.Http.Headers.AuthenticationHeaderValue("Bot", AppConfiguration.Token);
15+
new System.Net.Http.Headers.AuthenticationHeaderValue("Bot", ClientConfiguration.Token);
1916
}
2017
}
2118
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Disc.NET.Client.SDK
2+
{
3+
public class ClientConfiguration
4+
{
5+
public string Token { get; set; }
6+
public long ApplicationId { get; set; }
7+
public ClientConfiguration(string token, long applicationId)
8+
{
9+
Token = token;
10+
ApplicationId = applicationId;
11+
}
12+
}
13+
}
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
using Disc.NET.Client.SDK.Interfaces;
2-
using Disc.NET.Shared.Configurations;
32

43
namespace Disc.NET.Client.SDK
54
{
65
public sealed class ClientSingleton
76
{
87
private static IClient? _instance;
8+
private static ClientConfiguration _clientConfiguration;
99

10-
public static IClient GetInstance(AppConfiguration appConfiguration)
10+
public static IClient GetInstance()
1111
{
12+
if (_clientConfiguration == null)
13+
{
14+
throw new InvalidOperationException("Client configuration is not set. Please call Configure method before getting the instance.");
15+
}
16+
1217
if (_instance == null)
13-
_instance = new Client(appConfiguration, new HttpClient());
18+
{
19+
_instance = new Client(_clientConfiguration, new HttpClient());
20+
}
1421

1522
return _instance;
1623
}
1724

25+
public static void Configure(string token, long applicationId)
26+
{
27+
if (_clientConfiguration == null)
28+
_clientConfiguration = new ClientConfiguration(token, applicationId);
29+
}
30+
1831
}
1932
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
namespace Disc.NET.Shared.Enums
1+
namespace Disc.NET.Client.SDK.Enums
22
{
33
[Flags]
44
public enum MessageFlag
55
{
66
Ephemeral = 1 << 6, // 64
77
}
8-
}
8+
}
Lines changed: 3 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using System.Net;
2-
using System.Text.Json.Serialization;
3-
using Disc.NET.Client.SDK.Messages.Components;
4-
using Disc.NET.Client.SDK.Messages.Embeds;
5-
using Disc.NET.Shared.Constraints;
6-
using Disc.NET.Shared.Enums;
7-
using Disc.NET.Shared.Exceptions;
1+
using Disc.NET.Client.SDK.Messages.Embeds;
82

93
namespace Disc.NET.Client.SDK.Messages;
104

@@ -13,149 +7,13 @@ public class ApiMessage
137
public string? MessageId { get; set; }
148
public string Content { get; set; } = string.Empty;
159
public List<Embed> Embeds { get; set; } = [];
10+
public long Flags { get; set; }
1611

17-
[JsonIgnore]
18-
public List<MessageFlag>? MessageFlags { get; set; }
19-
20-
public long Flags => MessageFlags?.Aggregate(0L, (current, flag) => current | (long)flag) ?? 0L;
21-
22-
[JsonIgnore]
23-
public List<IMessageComponentBuilder> MessageComponents { get; set; } = [];
24-
25-
public List<object> Components => MountComponents();
12+
public List<object> Components { get; set; } = [];
2613

2714
public int? Type { get; set; }
2815

2916
public ApiMessage? MessageReference { get; set; }
3017

31-
private List<object> MountComponents()
32-
{
33-
if (MessageComponents.Count > 5)
34-
throw new DiscNetGenericException("The message cannot contain more than 5 top-level components.");
35-
36-
var results = new List<object>();
37-
38-
NormalizeActionRows<ActionRowSelectMenuComponentBuilder>(ActionRowConstraint.MAX_SELECT_MENUS_PER_ACTION_ROW, message =>
39-
new ActionRowSelectMenuComponentBuilder().AddMenu(message.First()));
40-
41-
NormalizeActionRows<ActionRowButtonComponentBuilder>(ActionRowConstraint.MAX_BUTTONS_PER_ACTION_ROW, message =>
42-
new ActionRowButtonComponentBuilder().AddButtons(message));
43-
44-
MessageComponents.ForEach(x => results.Add(x.Build()));
45-
return results;
46-
}
47-
48-
/// <summary>
49-
/// Normalizes action rows of a specific component type to comply with Discord message constraints.
50-
///
51-
/// This method validates the maximum number of action rows per message and the maximum number
52-
/// of components allowed per action row. If an action row exceeds the allowed number of components,
53-
/// it is automatically split into multiple valid action rows.
54-
/// </summary>
55-
/// <typeparam name="T">
56-
/// The type of action row builder to process (e.g., select menu rows or button rows).
57-
/// </typeparam>
58-
/// <param name="quantityComponentPerActionRow">
59-
/// The maximum number of components allowed per action row for the given component type.
60-
/// </param>
61-
/// <param name="createBuilderFunc">
62-
/// A factory function responsible for creating a new action row builder from a list
63-
/// of message components.
64-
/// </param>
65-
/// <exception cref="DiscNetClientSdkException">
66-
/// Thrown when the message exceeds Discord constraints, such as:
67-
/// - Maximum number of action rows per message
68-
/// - Insufficient available action row slots to split invalid rows
69-
/// </exception>
70-
/// <remarks>
71-
/// This method mutates the <see cref="MessageComponents"/> collection by:
72-
/// - Removing excess components from invalid action rows
73-
/// - Adding newly created action rows to the message
74-
/// </remarks>
75-
76-
private void NormalizeActionRows<T>(int quantityComponentPerActionRow,
77-
Func<List<IMessageComponent>, IMessageComponentBuilder> createBuilderFunc)
78-
where T : IMessageComponentBuilder
79-
{
80-
var actionRows = MessageComponents.Where(x => x is T).ToList();
81-
82-
if (actionRows.Count == 0) return;
83-
int actionRowsPerMessage = ActionRowConstraint.MAX_ACTION_ROWS_PER_MESSAGE;
84-
int actionRowsCount = actionRows.Count;
85-
if (actionRowsCount > actionRowsPerMessage)
86-
{
87-
throw new DiscNetGenericException(
88-
$"The message cannot contain more than {actionRowsPerMessage} top-level components.");
89-
}
90-
91-
int availableActionRowSlots = actionRowsPerMessage - MessageComponents.Count;
92-
var invalidActionRows = actionRows.Where(x => x.Components.Count > quantityComponentPerActionRow).ToList();
93-
var containsActionRowsInvalids = invalidActionRows.Count > 0;
94-
95-
if (!containsActionRowsInvalids) return;
96-
if (availableActionRowSlots == 0 && containsActionRowsInvalids)
97-
{
98-
throw new DiscNetGenericException($"The message cannot contain more than {actionRowsPerMessage} top-level components.");
99-
}
100-
101-
int numberNecessaryToCreateNewActionRows;
102-
if (quantityComponentPerActionRow > 1)
103-
{
104-
numberNecessaryToCreateNewActionRows = invalidActionRows
105-
.Select(x => (int)Math.Ceiling((double)x.Components.Count / quantityComponentPerActionRow) - 1)
106-
.Sum();
107-
}
108-
else
109-
{
110-
numberNecessaryToCreateNewActionRows = invalidActionRows
111-
.Select(x => x.Components.Count - 1)
112-
.Sum();
113-
}
114-
115-
116-
if (numberNecessaryToCreateNewActionRows > availableActionRowSlots)
117-
{
118-
throw new DiscNetGenericException(
119-
$"The message cannot contain more than {actionRowsPerMessage} top-level components.");
120-
}
121-
122-
int newActionRowsCount = 0;
123-
foreach (var actionRow in invalidActionRows)
124-
{
125-
var messageComponents = actionRow.Components
126-
.OfType<IMessageComponent>()
127-
.ToList();
128-
129-
int index = 0;
130-
while (messageComponents.Count - index > quantityComponentPerActionRow &&
131-
newActionRowsCount < availableActionRowSlots)
132-
{
133-
IMessageComponentBuilder? newActionRow;
134-
135-
if (quantityComponentPerActionRow > 1)
136-
{
137-
var components = messageComponents
138-
.Skip(index)
139-
.Take(quantityComponentPerActionRow)
140-
.ToList();
141-
components.ForEach(x => actionRow.Components.Remove(x));
142-
index += quantityComponentPerActionRow;
143-
newActionRow = createBuilderFunc.Invoke(components);
144-
}
145-
else
146-
{
147-
var component = messageComponents[index];
148-
149-
actionRow.Components.Remove(component);
150-
index++;
151-
newActionRow = createBuilderFunc.Invoke([component]);
152-
}
153-
154-
MessageComponents.Add(newActionRow);
155-
newActionRowsCount++;
156-
}
157-
}
158-
}
159-
// Colocar os outros campos depois
16018
// https://discord.com/developers/docs/resources/message#message-object
16119
}
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
7-
namespace Disc.NET.Client.SDK.Messages.Components
1+
namespace Disc.NET.Client.SDK.Messages.Components
82
{
93
public interface IMessageComponent;
104
}

src/Disc.NET.Commands/Disc.NET.Commands.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<ItemGroup>
1010
<ProjectReference Include="..\Disc.NET.Client.SDK\Disc.NET.Client.SDK.csproj" />
11+
<ProjectReference Include="..\Disc.NET.Shared\Disc.NET.Shared.csproj" />
1112
</ItemGroup>
1213

1314
</Project>
File renamed without changes.

src/Disc.NET.Commands/ICommand.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
using Disc.NET.Commands.Contexts;
1+
using Disc.NET.Commands.Contexts;
72

83
namespace Disc.NET.Commands
94
{

0 commit comments

Comments
 (0)