diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 2c0452e4f..d5af6c845 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -1,95 +1,95 @@
name: "Documentation"
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
name: Build documentation
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
path: DisCatSharp
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.0.202
- name: Restore packages
working-directory: DisCatSharp
run: dotnet restore
- name: Build library
working-directory: DisCatSharp
run: dotnet build -c Release
- name: Test library
working-directory: DisCatSharp
run: dotnet test -c Release
continue-on-error: true
- name: Build Docs
working-directory: DisCatSharp
shell: pwsh
run: ./rebuild-docs.ps1 -DocsPath "./DisCatSharp.Docs" -Output ".." -PackageName "dcs-docs"
- name: Upload packed docs
uses: actions/upload-artifact@v3
with:
name: dcs-docs.zip
path: dcs-docs.zip
retention-days: 30
documentation:
runs-on: windows-latest
name: Upload documentation
needs: build
steps:
- name: Checkout docs repository
uses: actions/checkout@v3
with:
repository: Aiko-IT-Systems/DisCatSharp.Docs
path: DisCatSharp.Docs
token: ${{ secrets.NYUW_TOKEN_GH }}
- name: Download packed docs
uses: actions/download-artifact@v3
with:
name: dcs-docs.zip
- name: Purge old docs
working-directory: DisCatSharp.Docs
shell: pwsh
run: Get-ChildItem -Exclude .git* | Remove-Item -Recurse -Force
- name: Extract new docs
shell: pwsh
run: Expand-Archive -Path dcs-docs.zip DisCatSharp.Docs/
- name: Commit and push changes
uses: EndBug/add-and-commit@main
with:
cwd: DisCatSharp.Docs
default_author: user_info
author_name: DisCatSharp
author_email: team@aitsys.dev
committer_name: NyuwBot
committer_email: nyuw@aitsys.dev
commit: --signoff
message: 'Docs update for commit ${{ github.repository }} (${{ github.sha }})'
publish-main:
runs-on: ubuntu-latest
name: Publish documentation on main server
needs: documentation
steps:
- name: Get SSH Agent
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: ${{ secrets.AITSYS_SSH }}
- name: Publish on server
continue-on-error: true
- run: ssh -o StrictHostKeyChecking=no -T root@80.153.182.68 -f 'cd /var/www/dcs/docs && git pull -f'
+ run: ssh -o StrictHostKeyChecking=no -T root@80.153.182.68 -f 'cd /var/www/dcs.aitsys.dev/docs && git pull -f'
publish-backup:
runs-on: ubuntu-latest
name: Publish documentation on backup server
needs: documentation
steps:
- name: Get SSH Agent
uses: webfactory/ssh-agent@v0.5.4
with:
ssh-private-key: ${{ secrets.AITSYS_SSH }}
- name: Publish on server
continue-on-error: true
run: ssh -o StrictHostKeyChecking=no -T root@207.180.240.241 -f 'cd /var/www/dcsdocs && git pull -f'
diff --git a/DisCatSharp.Common/Types/LinqMethods.cs b/DisCatSharp.Common/Types/LinqMethods.cs
index 43c0e2069..9e9d8c02e 100644
--- a/DisCatSharp.Common/Types/LinqMethods.cs
+++ b/DisCatSharp.Common/Types/LinqMethods.cs
@@ -1,78 +1,75 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DisCatSharp.Common;
///
/// Various Methods for Linq
///
public static class LinqMethods
{
///
/// Safely tries to get the first match out of a list.
///
/// Value type of list.
/// The list to use.
/// The predicate.
/// The value to get if succeeded
/// Whether a value was found.
-#nullable enable
public static bool GetFirstValueWhere(this List? list, Func predicate, out TSource? value)
{
- if (list == null || !list.Any())
+ if (list.EmptyOrNull())
{
value = default;
return false;
}
value = list.Where(predicate).FirstOrDefault();
return value is not null;
}
-#nullable disable
///
/// Safely tries to extract the value of the first match where target key is found, otherwise null.
///
/// Key type of dictionary.
/// Value type of dictionary.
/// The dictionary to use.
/// The key to search for.
/// The value to get if succeeded.
/// Whether a value was found through the key.
-#nullable enable
- public static bool GetFirstValueByKey(this Dictionary? dict, TKey? key, out TValue? value)
+ public static bool GetFirstValueByKey(this Dictionary? dict, TKey? key, out TValue? value)
+ where TKey : notnull
{
if (dict == null)
{
value = default;
return false;
}
return dict.TryGetValue(key, out value);
}
-#nullable disable
}
diff --git a/DisCatSharp.Common/Utilities/EnsureObjectStates.cs b/DisCatSharp.Common/Utilities/EnsureObjectStates.cs
index 4573c9441..0e71821a7 100644
--- a/DisCatSharp.Common/Utilities/EnsureObjectStates.cs
+++ b/DisCatSharp.Common/Utilities/EnsureObjectStates.cs
@@ -1,78 +1,70 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using System.Linq;
namespace DisCatSharp.Common;
///
/// Ensures that certain objects have the target state.
///
public static class EnsureObjectStates
{
///
/// Checks whether the dictionary is null or empty.
///
/// Any key type.
/// Any value type.
/// The dictionary to check on.
/// True if satisfied, false otherwise.
-#nullable enable
- public static bool EmptyOrNull(this Dictionary? dictionary)
- => dictionary == null || !dictionary.Any() || dictionary.Keys == null || !dictionary.Keys.Any();
-#nullable disable
+ public static bool EmptyOrNull(this Dictionary? dictionary) where T1 : notnull
+ => dictionary == null || !dictionary.Any() || !dictionary.Keys.Any();
///
/// Checks whether the dictionary is not null and not empty.
///
/// Any key type.
/// Any value type.
/// The dictionary to check on.
/// True if satisfied, false otherwise.
-#nullable enable
- public static bool NotEmptyAndNotNull(this Dictionary? dictionary)
- => dictionary != null && dictionary.Any() && dictionary.Keys != null && dictionary.Keys.Any();
-#nullable disable
+ public static bool NotEmptyAndNotNull(this Dictionary? dictionary) where T1 : notnull
+ => dictionary != null && dictionary.Any() && dictionary.Keys.Any();
///
/// Checks whether the list is null or empty.
///
/// Any value type.
/// The list to check on.
/// True if satisfied, false otherwise.
-#nullable enable
public static bool EmptyOrNull(this List? list)
=> list == null || !list.Any();
-#nullable disable
///
/// Checks whether the list is not null and not empty.
///
/// Any value type.
/// The list to check on.
/// True if satisfied, false otherwise.
-#nullable enable
public static bool NotEmptyAndNotNull(this List? list)
=> list != null && list.Any();
-#nullable disable
}
diff --git a/DisCatSharp/Entities/Interaction/DiscordInteractionModalBuilder.cs b/DisCatSharp/Entities/Interaction/DiscordInteractionModalBuilder.cs
index 5dde3d4b5..403d16848 100644
--- a/DisCatSharp/Entities/Interaction/DiscordInteractionModalBuilder.cs
+++ b/DisCatSharp/Entities/Interaction/DiscordInteractionModalBuilder.cs
@@ -1,157 +1,161 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DisCatSharp.Entities;
///
/// Constructs an interaction modal response.
///
public sealed class DiscordInteractionModalBuilder
{
///
/// Title of modal.
///
public string Title
{
get => this._title;
set
{
if (value != null && value.Length > 128)
throw new ArgumentException("Title length cannot exceed 128 characters.", nameof(value));
this._title = value;
}
}
private string _title;
///
/// Custom id of modal.
///
public string CustomId { get; set; }
///
/// Components to send on this interaction response.
///
public IReadOnlyList ModalComponents => this._components;
private readonly List _components = new();
///
/// Constructs a new empty interaction modal builder.
///
- public DiscordInteractionModalBuilder() { }
+ public DiscordInteractionModalBuilder(string title = null, string customId = null)
+ {
+ this.Title = title ?? "Title";
+ this.CustomId = customId ?? Guid.NewGuid().ToString();
+ }
public DiscordInteractionModalBuilder WithTitle(string title)
{
this.Title = title;
return this;
}
public DiscordInteractionModalBuilder WithCustomId(string customId)
{
this.CustomId = customId;
return this;
}
///
/// Appends a collection of components to the builder. Each call will append to a new row.
///
/// The components to append. Up to five.
/// The current builder to chain calls with.
/// Thrown when passing more than 5 components.
public DiscordInteractionModalBuilder AddModalComponents(params DiscordTextComponent[] components)
=> this.AddModalComponents((IEnumerable)components);
///
/// Appends a text component to the builder.
///
/// The component to append.
/// The current builder to chain calls with.
public DiscordInteractionModalBuilder AddTextComponent(DiscordTextComponent component)
{
List comp = new(1)
{
component
};
return this.AddModalComponents(comp);
}
///
/// Appends several rows of components to the message
///
/// The rows of components to add, holding up to five each.
///
public DiscordInteractionModalBuilder AddModalComponents(IEnumerable components)
{
var ara = components.ToArray();
if (ara.Length + this._components.Count > 5)
throw new ArgumentException("ActionRow count exceeds maximum of five.");
foreach (var ar in ara)
this._components.Add(ar);
return this;
}
///
/// Appends a collection of components to the builder. Each call will append to a new row.
/// If you add a you can only add one.
///
/// The components to append. Up to five.
/// The current builder to chain calls with.
/// Thrown when passing more than 5 components.
public DiscordInteractionModalBuilder AddModalComponents(IEnumerable components)
{
var compArr = components.ToArray();
var count = compArr.Length;
if (count > 5)
throw new ArgumentException("Cannot add more than 5 components per action row!");
if (components.Where(c => c.Type == Enums.ComponentType.InputText).Any() && count < 1)
throw new ArgumentException("Cannot add more than 1 text components per action row!");
var arc = new DiscordActionRowComponent(compArr);
this._components.Add(arc);
return this;
}
///
/// Clears all message components on this builder.
///
public void ClearComponents()
=> this._components.Clear();
///
/// Allows for clearing the Interaction Response Builder so that it can be used again to send a new response.
///
public void Clear()
{
this._components.Clear();
this.Title = null;
this.CustomId = null;
}
}