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; } }