docs: Main docs update (#1304)

* Remove template in favor of official samples

* Fixed a variable name copy pasta mistake

line 35 was _database.GetData() instead of DBService.GetData()

* Experimental theme change

* Change paragraph, code, heading fonts
* Widen viewport

* Update DocFX.Plugins.LastModified v1.2.3

* Exclude Discord.API in docs

* Add remarks for SocketReaction properties

* Add examples for BaseSocketClient.Events

* Add additional clarification for some methods

* Move IUser and IGuildChannel examples

* Clarify several guides samples with notes

- Reword TypeReader comment to avoid giving the idea that the sample itself is "obsolete"
- Remove CommandException logging comment regarding C#7.0 as the version is now the standard across VS2017 and up
- Remove suggestion about handling result in command handler since it is now advised to use CommandExecuted instead
+ Add additional comment to clarify ctor for DI setup

* Add/migrate code examples

* Incorporate material design theme

License @ https://github.com/ovasquez

* Update installation and nightly guide

* Fix improper indentations made obvious by the widen viewport
* Fix minor grammar issues
+ Add installation for nightly build using dotnet CLI

* Fix nav level indentation

* Revise "Your First Bot" article

* Merge some paragraphs to avoid clutter while keeping readability
* Reword the use of command framework
+ Add additional warning/note about environment variable

* Add additional indent level

* Fix indentation text warping

* Remove connections sample

* Update logging sample

Remove redundant part of the sample

* Remove mention of RPC

* Remove misleading section about commands

- Remove command sample from complete snippet
* Revise "Your First Bot" command paragraphs
* Change wording to hint devs that additional command parser packages may be available, as more and more begin to crop up

* Update themes

* Add XML docs contribution guidelines


Update guidelines

* Update CommandExecuted remarks

* Fix precondition remarks typo
no one saw that ok

* Fix permission sample in docfx

* Fix IMessageChannel samples

* Update docs/_template/light-dark-theme/styles/docfx.vendor.minify.css

Co-Authored-By: Still34 <341464@gmail.com>

* Update docs/_template/light-dark-theme/styles/material.css

Co-Authored-By: Still34 <341464@gmail.com>

* Update docs/_template/light-dark-theme/styles/material.css

Co-Authored-By: Still34 <341464@gmail.com>
This commit is contained in:
Still Hsu
2019-05-14 06:29:47 +08:00
committed by Christopher F
parent 5ea3e113b8
commit 4309550ca0
64 changed files with 986 additions and 345 deletions

View File

@@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Discord.Net.Examples.Core.Entities.Channels
{
[PublicAPI]
internal class GuildChannelExamples
{
#region AddPermissionOverwriteAsyncRole
public async Task MuteRoleAsync(IRole role, IGuildChannel channel)
{
if (role == null) throw new ArgumentNullException(nameof(role));
if (channel == null) throw new ArgumentNullException(nameof(channel));
// Fetches the previous overwrite and bail if one is found
var previousOverwrite = channel.GetPermissionOverwrite(role);
if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
throw new InvalidOperationException($"Role {role.Name} had already been muted in this channel.");
// Creates a new OverwritePermissions with send message set to deny and pass it into the method
await channel.AddPermissionOverwriteAsync(role, new OverwritePermissions(sendMessages: PermValue.Deny));
}
#endregion
#region AddPermissionOverwriteAsyncUser
public async Task MuteUserAsync(IGuildUser user, IGuildChannel channel)
{
if (user == null) throw new ArgumentNullException(nameof(user));
if (channel == null) throw new ArgumentNullException(nameof(channel));
// Fetches the previous overwrite and bail if one is found
var previousOverwrite = channel.GetPermissionOverwrite(user);
if (previousOverwrite.HasValue && previousOverwrite.Value.SendMessages == PermValue.Deny)
throw new InvalidOperationException($"User {user.Username} had already been muted in this channel.");
// Creates a new OverwritePermissions with send message set to deny and pass it into the method
await channel.AddPermissionOverwriteAsync(user, new OverwritePermissions(sendMessages: PermValue.Deny));
}
#endregion
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Discord.Net.Examples.Core.Entities.Channels
{
[PublicAPI]
internal class MessageChannelExamples
{
#region GetMessagesAsync.FromId.BeginningMessages
public async Task PrintFirstMessages(IMessageChannel channel, int messageCount)
{
// Although the library does attempt to divide the messageCount by 100
// to comply to Discord's maximum message limit per request, sending
// too many could still cause the queue to clog up.
// The purpose of this exception is to discourage users from sending
// too many requests at once.
if (messageCount > 1000)
throw new InvalidOperationException("Too many messages requested.");
// Setting fromMessageId to 0 will make Discord
// default to the first message in channel.
var messages = await channel.GetMessagesAsync(
0, Direction.After, messageCount)
.FlattenAsync();
// Print message content
foreach (var message in messages)
Console.WriteLine($"{message.Author} posted '{message.Content}' at {message.CreatedAt}.");
}
#endregion
public async Task GetMessagesExampleBody(IMessageChannel channel)
{
#pragma warning disable IDISP001
#pragma warning disable IDISP014
// We're just declaring this for the sample below.
// Ideally, you want to get or create your HttpClient
// from IHttpClientFactory.
// You get a bonus for reading the example source though!
var httpClient = new HttpClient();
#pragma warning restore IDISP014
#pragma warning restore IDISP001
// Another dummy method
Task LongRunningAsync()
{
return Task.Delay(0);
}
#region GetMessagesAsync.FromLimit.Standard
var messages = await channel.GetMessagesAsync(300).FlattenAsync();
var userMessages = messages.Where(x => x.Author.Id == 53905483156684800);
#endregion
#region GetMessagesAsync.FromMessage
var oldMessage = await channel.SendMessageAsync("boi");
var messagesFromMsg = await channel.GetMessagesAsync(oldMessage, Direction.Before, 5).FlattenAsync();
#endregion
#region GetMessagesAsync.FromId.FromMessage
await channel.GetMessagesAsync(442012544660537354, Direction.Before, 5).FlattenAsync();
#endregion
#region SendMessageAsync
var message = await channel.SendMessageAsync(DateTimeOffset.UtcNow.ToString("R"));
await Task.Delay(TimeSpan.FromSeconds(5))
.ContinueWith(x => message.DeleteAsync());
#endregion
#region SendFileAsync.FilePath
await channel.SendFileAsync("wumpus.txt", "good discord boi");
#endregion
#region SendFileAsync.FilePath.EmbeddedImage
await channel.SendFileAsync("b1nzy.jpg",
embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
#endregion
#region SendFileAsync.FileStream.EmbeddedImage
using (var b1nzyStream = await httpClient.GetStreamAsync("https://example.com/b1nzy"))
await channel.SendFileAsync(b1nzyStream, "b1nzy.jpg",
embed: new EmbedBuilder {ImageUrl = "attachment://b1nzy.jpg"}.Build());
#endregion
#region EnterTypingState
using (channel.EnterTypingState()) await LongRunningAsync();
#endregion
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Discord.Net.Examples.Core.Entities.Guilds
{
[PublicAPI]
internal class GuildExamples
{
#region CreateTextChannelAsync
public async Task CreateTextChannelUnderWumpus(IGuild guild, string name)
{
var categories = await guild.GetCategoriesAsync();
var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
if (targetCategory == null) return;
await guild.CreateTextChannelAsync(name, x =>
{
x.CategoryId = targetCategory.Id;
x.Topic = $"This channel was created at {DateTimeOffset.UtcNow}.";
});
}
#endregion
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Net;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Discord.Net.Examples.Core.Entities.Users
{
[PublicAPI]
internal class UserExamples
{
#region GetAvatarUrl
public async Task GetAvatarAsync(IUser user, ITextChannel textChannel)
{
var userAvatarUrl = user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl();
await textChannel.SendMessageAsync(userAvatarUrl);
}
#endregion
#region GetOrCreateDMChannelAsync
public async Task MessageUserAsync(IUser user)
{
var channel = await user.GetOrCreateDMChannelAsync();
try
{
await channel.SendMessageAsync("Awesome stuff!");
}
catch (Discord.Net.HttpException ex) when (ex.HttpCode == HttpStatusCode.Forbidden)
{
Console.WriteLine($"Boo, I cannot message {user}.");
}
}
#endregion
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Core\Entities\Guilds\IGuild.Examples.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Core\Entities\Guilds\IGuild.Examples.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" />
<ProjectReference Include="..\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj" />
<PackageReference Include="JetBrains.Annotations" Version="2018.3.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,117 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Discord.WebSocket;
using JetBrains.Annotations;
namespace Discord.Net.Examples.WebSocket
{
[PublicAPI]
internal class BaseSocketClientExamples
{
#region ReactionAdded
public void HookReactionAdded(BaseSocketClient client)
=> client.ReactionAdded += HandleReactionAddedAsync;
public async Task HandleReactionAddedAsync(Cacheable<IUserMessage, ulong> cachedMessage,
ISocketMessageChannel originChannel, SocketReaction reaction)
{
var message = await cachedMessage.GetOrDownloadAsync();
if (message != null && reaction.User.IsSpecified)
Console.WriteLine($"{reaction.User.Value} just added a reaction '{reaction.Emote}' " +
$"to {message.Author}'s message ({message.Id}).");
}
#endregion
#region ChannelCreated
public void HookChannelCreated(BaseSocketClient client)
=> client.ChannelCreated += HandleChannelCreated;
public Task HandleChannelCreated(SocketChannel channel)
{
if (channel is SocketGuildChannel guildChannel)
Console.WriteLine($"A new channel '{guildChannel.Name}'({guildChannel.Id}, {guildChannel.GetType()})"
+ $"has been created at {guildChannel.CreatedAt}.");
return Task.CompletedTask;
}
#endregion
#region ChannelDestroyed
public void HookChannelDestroyed(BaseSocketClient client)
=> client.ChannelDestroyed += HandleChannelDestroyed;
public Task HandleChannelDestroyed(SocketChannel channel)
{
if (channel is SocketGuildChannel guildChannel)
Console.WriteLine(
$"A new channel '{guildChannel.Name}'({guildChannel.Id}, {guildChannel.GetType()}) has been deleted.");
return Task.CompletedTask;
}
#endregion
#region ChannelUpdated
public void HookChannelUpdated(BaseSocketClient client)
=> client.ChannelUpdated += HandleChannelRename;
public Task HandleChannelRename(SocketChannel beforeChannel, SocketChannel afterChannel)
{
if (beforeChannel is SocketGuildChannel beforeGuildChannel &&
afterChannel is SocketGuildChannel afterGuildChannel)
if (beforeGuildChannel.Name != afterGuildChannel.Name)
Console.WriteLine(
$"A channel ({beforeChannel.Id}) is renamed from {beforeGuildChannel.Name} to {afterGuildChannel.Name}.");
return Task.CompletedTask;
}
#endregion
#region MessageReceived
private readonly ulong[] _targetUserIds = {168693960628371456, 53905483156684800};
public void HookMessageReceived(BaseSocketClient client)
=> client.MessageReceived += HandleMessageReceived;
public Task HandleMessageReceived(SocketMessage message)
{
// check if the message is a user message as opposed to a system message (e.g. Clyde, pins, etc.)
if (!(message is SocketUserMessage userMessage)) return Task.CompletedTask;
// check if the message origin is a guild message channel
if (!(userMessage.Channel is SocketTextChannel textChannel)) return Task.CompletedTask;
// check if the target user was mentioned
var targetUsers = userMessage.MentionedUsers.Where(x => _targetUserIds.Contains(x.Id));
foreach (var targetUser in targetUsers)
Console.WriteLine(
$"{targetUser} was mentioned in the message '{message.Content}' by {message.Author} in {textChannel.Name}.");
return Task.CompletedTask;
}
#endregion
#region MessageDeleted
public void HookMessageDeleted(BaseSocketClient client)
=> client.MessageDeleted += HandleMessageDelete;
public Task HandleMessageDelete(Cacheable<IMessage, ulong> cachedMessage, ISocketMessageChannel channel)
{
// check if the message exists in cache; if not, we cannot report what was removed
if (!cachedMessage.HasValue) return Task.CompletedTask;
var message = cachedMessage.Value;
Console.WriteLine(
$"A message ({message.Id}) from {message.Author} was removed from the channel {channel.Name} ({channel.Id}):"
+ Environment.NewLine
+ message.Content);
return Task.CompletedTask;
}
#endregion
}
}