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

V4: Message builder #2250

Open
wants to merge 2 commits into
base: 4.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
49 changes: 32 additions & 17 deletions src/Discord.Net.Core/DiscordConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ public class DiscordConfig
/// </returns>
public const int MaxAuditLogEntriesPerBatch = 100;

/// <summary>
/// Returns the max number of stickers that can be sent on a message.
/// </summary>
public const int MaxStickersPerMessage = 3;

/// <summary>
/// Returns the max numbe of files that can be sent on a message.
/// </summary>
public const int MaxFilesPerMessage = 10;

/// <summary>
/// Returns the max number of embeds that can be sent on a message.
/// </summary>
public const int MaxEmbedsPerMessage = 10;

/// <summary>
/// Gets or sets how a request should act in the case of an error, by default.
/// </summary>
Expand Down Expand Up @@ -165,23 +180,23 @@ public class DiscordConfig
/// </remarks>
internal bool DisplayInitialLog { get; set; } = true;

/// <summary>
/// Gets or sets whether or not rate-limits should use the system clock.
/// </summary>
/// <remarks>
/// If set to <c>false</c>, we will use the X-RateLimit-Reset-After header
/// to determine when a rate-limit expires, rather than comparing the
/// X-RateLimit-Reset timestamp to the system time.
///
/// This should only be changed to false if the system is known to have
/// a clock that is out of sync. Relying on the Reset-After header will
/// incur network lag.
///
/// Regardless of this property, we still rely on the system's wall-clock
/// to determine if a bucket is rate-limited; we do not use any monotonic
/// clock. Your system will still need a stable clock.
/// </remarks>
public bool UseSystemClock { get; set; } = true;
/// <summary>
/// Gets or sets whether or not rate-limits should use the system clock.
/// </summary>
/// <remarks>
/// If set to <c>false</c>, we will use the X-RateLimit-Reset-After header
/// to determine when a rate-limit expires, rather than comparing the
/// X-RateLimit-Reset timestamp to the system time.
///
/// This should only be changed to false if the system is known to have
/// a clock that is out of sync. Relying on the Reset-After header will
/// incur network lag.
///
/// Regardless of this property, we still rely on the system's wall-clock
/// to determine if a bucket is rate-limited; we do not use any monotonic
/// clock. Your system will still need a stable clock.
/// </remarks>
public bool UseSystemClock { get; set; } = true;

/// <summary>
/// Gets or sets whether or not the internal experation check uses the system date
Expand Down
10 changes: 10 additions & 0 deletions src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ public interface IMessageChannel : IChannel
/// </returns>
Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None);
/// <summary>
/// Sends a message to this message channel.
/// </summary>
/// <param name="message">The <see cref="Message"/> created from a <see cref="MessageBuilder"/>.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
/// </returns>
Task<IUserMessage> SendMessageAsync(Message message, RequestOptions options = null);
/// <summary>
/// Sends a file to this message channel with an optional caption.
/// </summary>
/// <example>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ internal void AddComponent(IMessageComponent component, int row)
/// <param name="maxValues">The max values of the placeholder.</param>
/// <param name="disabled">Whether or not the menu is disabled.</param>
/// <param name="row">The row to add the menu to.</param>
/// <returns></returns>
/// <returns>The current builder.</returns>
public ComponentBuilder WithSelectMenu(string customId, List<SelectMenuOptionBuilder> options,
string placeholder = null, int minValues = 1, int maxValues = 1, bool disabled = false, int row = 0)
{
Expand Down
101 changes: 101 additions & 0 deletions src/Discord.Net.Core/Entities/Messages/Builders/CodeLanguage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Represents a language in which codeblocks can be formatted.
/// </summary>
public struct CodeLanguage
{
/// <summary>
/// Gets the tag of the language.
/// </summary>
public string Tag { get; }

/// <summary>
/// Gets the name of the language. <see cref="string.Empty"/> if this <see cref="CodeLanguage"/> was constructed with no name provided.
/// </summary>
public string Name { get; } = string.Empty;

/// <summary>
/// Gets the CSharp language format.
/// </summary>
public static readonly CodeLanguage CSharp = new("cs", "csharp");

/// <summary>
/// Gets the Javascript language format.
/// </summary>
public static readonly CodeLanguage JavaScript = new("js", "javascript");

/// <summary>
/// Gets the XML language format.
/// </summary>
public static readonly CodeLanguage XML = new("xml", "xml");

/// <summary>
/// Gets the HTML language format.
/// </summary>
public static readonly CodeLanguage HTML = new("html", "html");

/// <summary>
/// Gets the CSS markdown format.
/// </summary>
public static readonly CodeLanguage CSS = new("css", "css");

/// <summary>
/// Gets a language format that represents none.
/// </summary>
public static readonly CodeLanguage None = new("", "none");

/// <summary>
/// Creates a new language format with name & tag.
/// </summary>
/// <param name="tag">The tag with which markdown will be formatted.</param>
/// <param name="name">The name of the language.</param>
public CodeLanguage(string tag, string name)
{
Tag = tag;
Name = name;
}

/// <summary>
/// Creates a new language format with a tag.
/// </summary>
/// <param name="tag">The tag with which markdown will be formatted.</param>
public CodeLanguage(string tag)
=> Tag = tag;

/// <summary>
/// Gets the tag of the language.
/// </summary>
/// <param name="language"></param>
public static implicit operator string(CodeLanguage language)
=> language.Tag;

/// <summary>
/// Gets a language based on the tag.
/// </summary>
/// <param name="tag"></param>
public static implicit operator CodeLanguage(string tag)
=> new(tag);

/// <summary>
/// Creates markdown format for this language.
/// </summary>
/// <param name="input">The input string to format.</param>
/// <returns>A markdown formatted code-block with this language.</returns>
public string ToMarkdown(string input)
=> $"```{Tag}\n{input}\n```";

/// <summary>
/// Gets the tag of the language.
/// </summary>
/// <returns><see cref="Tag"/></returns>
public override string ToString()
=> $"{Tag}";
}
}
64 changes: 64 additions & 0 deletions src/Discord.Net.Core/Entities/Messages/Builders/HeaderFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Represents the format in which a markdown header should be presented.
/// </summary>
public readonly struct HeaderFormat
{
public string Format { get; }

/// <summary>
/// The biggest header type.
/// </summary>
public static readonly HeaderFormat H1 = new("#");

/// <summary>
/// An above-average sized header.
/// </summary>
public static readonly HeaderFormat H2 = new("##");

/// <summary>
/// An average-sized header.
/// </summary>
public static readonly HeaderFormat H3 = new("###");

/// <summary>
/// A subheader.
/// </summary>
public static readonly HeaderFormat H4 = new("####");

/// <summary>
/// A smaller subheader.
/// </summary>
public static readonly HeaderFormat H5 = new("#####");

/// <summary>
/// Slightly bigger than regular bold markdown.
/// </summary>
public static readonly HeaderFormat H6 = new("######");

private HeaderFormat(string format)
=> Format = format;

/// <summary>
/// Formats this header into markdown, appending provided string.
/// </summary>
/// <param name="input">The string to turn into a header.</param>
/// <returns>A markdown formatted header title.</returns>
public string ToMarkdown(string input)
=> $"{Format} {input}";

/// <summary>
/// Gets the markdown format for this header.
/// </summary>
/// <returns>The markdown format for this header.</returns>
public override string ToString()
=> $"{Format}";
}
}
Loading