Adopt MarkdownToInlinesConverter for instruction text formatting

Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-24 09:55:08 +00:00
parent c6871af438
commit 5bbd3fa65e
9 changed files with 321 additions and 226 deletions

View File

@@ -0,0 +1,160 @@
using System;
using System.Globalization;
using System.Linq;
using Avalonia.Controls.Documents;
using Avalonia.Data.Converters;
using Avalonia.Media;
using Markdig;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
using MarkdownInline = Markdig.Syntax.Inlines.Inline;
namespace DiscordChatExporter.Gui.Converters;
public class MarkdownToInlinesConverter : IValueConverter
{
public static readonly MarkdownToInlinesConverter Instance = new();
private static readonly MarkdownPipeline MarkdownPipeline = new MarkdownPipelineBuilder()
.UseEmphasisExtras()
.Build();
private static void ProcessInline(
InlineCollection inlines,
MarkdownInline markdownInline,
FontWeight? fontWeight = null,
FontStyle? fontStyle = null,
TextDecorationCollection? textDecorations = null
)
{
switch (markdownInline)
{
case LiteralInline literal:
{
var run = new Run(literal.Content.ToString());
if (fontWeight is not null)
run.FontWeight = fontWeight.Value;
if (fontStyle is not null)
run.FontStyle = fontStyle.Value;
if (textDecorations is not null)
run.TextDecorations = textDecorations;
inlines.Add(run);
break;
}
case LineBreakInline:
{
inlines.Add(new LineBreak());
break;
}
case EmphasisInline emphasis:
{
var newWeight = fontWeight;
var newStyle = fontStyle;
var newDecorations = textDecorations;
switch (emphasis.DelimiterChar)
{
case '*' or '_' when emphasis.DelimiterCount == 2:
newWeight = FontWeight.SemiBold;
break;
case '*' or '_':
newStyle = FontStyle.Italic;
break;
case '~':
newDecorations = TextDecorations.Strikethrough;
break;
case '+':
newDecorations = TextDecorations.Underline;
break;
}
foreach (var child in emphasis)
ProcessInline(inlines, child, newWeight, newStyle, newDecorations);
break;
}
case ContainerInline container:
{
foreach (var child in container)
ProcessInline(inlines, child, fontWeight, fontStyle, textDecorations);
break;
}
}
}
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
var inlines = new InlineCollection();
if (value is not string { Length: > 0 } text)
return inlines;
var isFirst = true;
void RenderParagraph(ParagraphBlock paragraph)
{
if (!isFirst)
{
// Insert a blank line between paragraphs
inlines.Add(new LineBreak());
inlines.Add(new LineBreak());
}
isFirst = false;
foreach (var markdownInline in paragraph.Inline!)
ProcessInline(inlines, markdownInline);
}
void RenderListBlock(ListBlock list)
{
var itemOrder = 1;
if (list.IsOrdered && int.TryParse(list.OrderedStart, out var startNum))
itemOrder = startNum;
foreach (var listItem in list.OfType<ListItemBlock>())
{
if (!isFirst)
inlines.Add(new LineBreak());
isFirst = false;
var prefix = list.IsOrdered ? $"{itemOrder++}. " : $"{list.BulletType} ";
inlines.Add(new Run(prefix));
foreach (var subBlock in listItem.OfType<ParagraphBlock>())
{
if (subBlock is { Inline: not null } p)
foreach (var markdownInline in p.Inline)
ProcessInline(inlines, markdownInline);
}
}
}
foreach (var block in Markdown.Parse(text, MarkdownPipeline))
{
switch (block)
{
case ParagraphBlock { Inline: not null } paragraph:
RenderParagraph(paragraph);
break;
case ListBlock list:
RenderListBlock(list);
break;
}
}
return inlines;
}
public object? ConvertBack(
object? value,
Type targetType,
object? parameter,
CultureInfo culture
) => throw new NotSupportedException();
}

View File

@@ -37,6 +37,7 @@
<PackageReference Include="Deorcify" Version="1.1.0" PrivateAssets="all" /> <PackageReference Include="Deorcify" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="DialogHost.Avalonia" Version="0.10.4" /> <PackageReference Include="DialogHost.Avalonia" Version="0.10.4" />
<PackageReference Include="Gress" Version="2.1.1" /> <PackageReference Include="Gress" Version="2.1.1" />
<PackageReference Include="Markdig" Version="1.0.0" />
<PackageReference Include="Material.Avalonia" Version="3.9.2" /> <PackageReference Include="Material.Avalonia" Version="3.9.2" />
<PackageReference Include="Material.Icons.Avalonia" Version="2.2.0" /> <PackageReference Include="Material.Icons.Avalonia" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.2" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.2" />

View File

@@ -15,34 +15,34 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
[nameof(TokenPersonalHeader)] = "To get the token for your personal account:", [nameof(TokenPersonalHeader)] = "To get the token for your personal account:",
[nameof(TokenPersonalTosWarning)] = [nameof(TokenPersonalTosWarning)] =
"* Automating user accounts is technically against TOS —", "* Automating user accounts is technically against TOS — **use at your own risk**!",
[nameof(TokenPersonalTosRisk)] = "use at your own risk",
[nameof(TokenPersonalStep1Before)] = "1. Open Discord in your", [nameof(TokenPersonalStep1Before)] = "1. Open Discord in your",
[nameof(TokenPersonalStep1After)] = "and login", [nameof(TokenPersonalStep1After)] = "and login",
[nameof(TokenPersonalStep2)] = "2. Open any server or direct message channel", [nameof(TokenPersonalInstructions)] = """
[nameof(TokenPersonalStep3)] = "3. Press Ctrl+Shift+I to show developer tools", 2. Open any server or direct message channel
[nameof(TokenPersonalStep4)] = "4. Navigate to the Network tab", 3. Press **Ctrl+Shift+I** to show developer tools
[nameof(TokenPersonalStep5)] = "5. Press Ctrl+R to reload", 4. Navigate to the **Network** tab
[nameof(TokenPersonalStep6)] = 5. Press **Ctrl+R** to reload
"6. Switch between random channels to trigger network requests", 6. Switch between random channels to trigger network requests
[nameof(TokenPersonalStep7)] = "7. Search for a request that starts with messages", 7. Search for a request that starts with **messages**
[nameof(TokenPersonalStep8)] = "8. Select the Headers tab on the right", 8. Select the **Headers** tab on the right
[nameof(TokenPersonalStep9)] = "9. Scroll down to the Request Headers section", 9. Scroll down to the **Request Headers** section
[nameof(TokenPersonalStep10)] = "10. Copy the value of the authorization header", 10. Copy the value of the **authorization** header
""",
[nameof(TokenWebBrowserLinkText)] = "web browser", [nameof(TokenWebBrowserLinkText)] = "web browser",
// Token instructions (bot) // Token instructions (bot)
[nameof(TokenBotHeader)] = "To get the token for your bot:", [nameof(TokenBotHeader)] = "To get the token for your bot:",
[nameof(TokenBotIntro)] = [nameof(TokenBotIntro)] =
"The token is generated during bot creation. If you lost it, generate a new one:", "The token is generated during bot creation. If you lost it, generate a new one:",
[nameof(TokenBotStep1)] = "1. Open Discord", [nameof(TokenBotStep1)] = "1. Open Discord",
[nameof(TokenBotStep2)] = "2. Open your application's settings", [nameof(TokenBotInstructions)] = """
[nameof(TokenBotStep3)] = "3. Navigate to the Bot section on the left", 2. Open your application's settings
[nameof(TokenBotStep4)] = "4. Under Token click Reset Token", 3. Navigate to the **Bot** section on the left
[nameof(TokenBotStep5)] = "5. Click Yes, do it! and authenticate to confirm", 4. Under **Token** click **Reset Token**
[nameof(TokenBotStep6)] = 5. Click **Yes, do it!** and authenticate to confirm
"* Integrations using the previous token will stop working until updated", * Integrations using the previous token will stop working until updated
[nameof(TokenBotStep7Before)] = "* Your bot needs to have the", * Your bot needs to have the **Message Content Intent** enabled to read messages
[nameof(TokenBotStep7After)] = "enabled to read messages", """,
[nameof(TokenDeveloperPortalLinkText)] = "developer portal", [nameof(TokenDeveloperPortalLinkText)] = "developer portal",
[nameof(TokenDocumentationLinkText)] = "documentation", [nameof(TokenDocumentationLinkText)] = "documentation",
[nameof(TokenHelpText)] = "If you have questions or issues, please refer to the", [nameof(TokenHelpText)] = "If you have questions or issues, please refer to the",

View File

@@ -17,35 +17,34 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
[nameof(TokenPersonalHeader)] = "Obtenir le token pour votre compte personnel :", [nameof(TokenPersonalHeader)] = "Obtenir le token pour votre compte personnel :",
[nameof(TokenPersonalTosWarning)] = [nameof(TokenPersonalTosWarning)] =
"* L'automatisation des comptes est techniquement contraire aux CGU —", "* L'automatisation des comptes est techniquement contraire aux CGU — **à vos risques et périls**!",
[nameof(TokenPersonalTosRisk)] = "à vos risques et périls",
[nameof(TokenPersonalStep1Before)] = "1. Ouvrez Discord dans votre", [nameof(TokenPersonalStep1Before)] = "1. Ouvrez Discord dans votre",
[nameof(TokenPersonalStep1After)] = "et connectez-vous", [nameof(TokenPersonalStep1After)] = "et connectez-vous",
[nameof(TokenPersonalStep2)] = [nameof(TokenPersonalInstructions)] = """
"2. Ouvrez n'importe quel serveur ou canal de message direct", 2. Ouvrez n'importe quel serveur ou canal de message direct
[nameof(TokenPersonalStep3)] = 3. Appuyez sur **Ctrl+Shift+I** pour afficher les outils de développement
"3. Appuyez sur Ctrl+Shift+I pour afficher les outils de développement", 4. Naviguez vers l'onglet **Network**
[nameof(TokenPersonalStep4)] = "4. Naviguez vers l'onglet Network", 5. Appuyez sur **Ctrl+R** pour recharger
[nameof(TokenPersonalStep5)] = "5. Appuyez sur Ctrl+R pour recharger", 6. Changez de canal pour déclencher des requêtes réseau
[nameof(TokenPersonalStep6)] = "6. Changez de canal pour déclencher des requêtes réseau", 7. Cherchez une requête commençant par **messages**
[nameof(TokenPersonalStep7)] = "7. Cherchez une requête commençant par messages", 8. Sélectionnez l'onglet **Headers** à droite
[nameof(TokenPersonalStep8)] = "8. Sélectionnez l'onglet Headers à droite", 9. Faites défiler jusqu'à la section **Request Headers**
[nameof(TokenPersonalStep9)] = "9. Faites défiler jusqu'à la section Request Headers", 10. Copiez la valeur de l'en-tête **authorization**
[nameof(TokenPersonalStep10)] = "10. Copiez la valeur de l'en-tête authorization", """,
[nameof(TokenWebBrowserLinkText)] = "navigateur web", [nameof(TokenWebBrowserLinkText)] = "navigateur web",
// Token instructions (bot) // Token instructions (bot)
[nameof(TokenBotHeader)] = "Obtenir le token pour votre bot :", [nameof(TokenBotHeader)] = "Obtenir le token pour votre bot :",
[nameof(TokenBotIntro)] = [nameof(TokenBotIntro)] =
"Le token est généré lors de la création du bot. Si vous l'avez perdu, générez-en un nouveau :", "Le token est généré lors de la création du bot. Si vous l'avez perdu, générez-en un nouveau :",
[nameof(TokenBotStep1)] = "1. Ouvrez Discord", [nameof(TokenBotStep1)] = "1. Ouvrez Discord",
[nameof(TokenBotStep2)] = "2. Ouvrez les paramètres de votre application", [nameof(TokenBotInstructions)] = """
[nameof(TokenBotStep3)] = "3. Naviguez vers la section Bot à gauche", 2. Ouvrez les paramètres de votre application
[nameof(TokenBotStep4)] = "4. Sous Token, cliquez sur Reset Token", 3. Naviguez vers la section **Bot** à gauche
[nameof(TokenBotStep5)] = "5. Cliquez sur Yes, do it! et confirmez", 4. Sous **Token**, cliquez sur **Reset Token**
[nameof(TokenBotStep6)] = 5. Cliquez sur **Yes, do it!** et confirmez
"* Les intégrations utilisant l'ancien token cesseront de fonctionner jusquleur mise à jour", * Les intégrations utilisant l'ancien token cesseront de fonctionner jusqu'à leur mise à jour
[nameof(TokenBotStep7Before)] = "* Votre bot doit avoir l'option", * Votre bot doit avoir l'option **Message Content Intent** activée pour lire les messages
[nameof(TokenBotStep7After)] = "activée pour lire les messages", """,
[nameof(TokenDeveloperPortalLinkText)] = "portail développeur", [nameof(TokenDeveloperPortalLinkText)] = "portail développeur",
[nameof(TokenDocumentationLinkText)] = "documentation", [nameof(TokenDocumentationLinkText)] = "documentation",
[nameof(TokenHelpText)] = "Pour les questions ou problèmes, veuillez consulter la", [nameof(TokenHelpText)] = "Pour les questions ou problèmes, veuillez consulter la",

View File

@@ -17,36 +17,34 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
[nameof(TokenPersonalHeader)] = "Token für Ihr persönliches Konto abrufen:", [nameof(TokenPersonalHeader)] = "Token für Ihr persönliches Konto abrufen:",
[nameof(TokenPersonalTosWarning)] = [nameof(TokenPersonalTosWarning)] =
"* Das Automatisieren von Benutzerkonten verstößt technisch gegen die AGB —", "* Das Automatisieren von Benutzerkonten verstößt technisch gegen die AGB — **auf eigene Gefahr**!",
[nameof(TokenPersonalTosRisk)] = "auf eigene Gefahr",
[nameof(TokenPersonalStep1Before)] = "1. Öffnen Sie Discord in Ihrem", [nameof(TokenPersonalStep1Before)] = "1. Öffnen Sie Discord in Ihrem",
[nameof(TokenPersonalStep1After)] = "und melden Sie sich an", [nameof(TokenPersonalStep1After)] = "und melden Sie sich an",
[nameof(TokenPersonalStep2)] = [nameof(TokenPersonalInstructions)] = """
"2. Öffnen Sie einen Server oder einen direkten Nachrichtenkanal", 2. Öffnen Sie einen Server oder einen direkten Nachrichtenkanal
[nameof(TokenPersonalStep3)] = 3. Drücken Sie **Ctrl+Shift+I**, um die Entwicklertools anzuzeigen
"3. Drücken Sie Ctrl+Shift+I, um die Entwicklertools anzuzeigen", 4. Navigieren Sie zum Reiter **Network**
[nameof(TokenPersonalStep4)] = "4. Navigieren Sie zum Reiter Network", 5. Drücken Sie **Ctrl+R** zum Neuladen
[nameof(TokenPersonalStep5)] = "5. Drücken Sie Ctrl+R zum Neuladen", 6. Wechseln Sie zwischen Kanälen, um Netzwerkanfragen auszulösen
[nameof(TokenPersonalStep6)] = 7. Suchen Sie nach einer Anfrage, die mit **messages** beginnt
"6. Wechseln Sie zwischen Kanälen, um Netzwerkanfragen auszulösen", 8. Wählen Sie den Reiter **Headers** auf der rechten Seite
[nameof(TokenPersonalStep7)] = "7. Suchen Sie nach einer Anfrage, die mit messages beginnt", 9. Scrollen Sie nach unten zum Abschnitt **Request Headers**
[nameof(TokenPersonalStep8)] = "8. Wählen Sie den Reiter Headers auf der rechten Seite", 10. Kopieren Sie den Wert des Headers **authorization**
[nameof(TokenPersonalStep9)] = "9. Scrollen Sie nach unten zum Abschnitt Request Headers", """,
[nameof(TokenPersonalStep10)] = "10. Kopieren Sie den Wert des Headers authorization",
[nameof(TokenWebBrowserLinkText)] = "Webbrowser", [nameof(TokenWebBrowserLinkText)] = "Webbrowser",
// Token instructions (bot) // Token instructions (bot)
[nameof(TokenBotHeader)] = "Token für Ihren Bot abrufen:", [nameof(TokenBotHeader)] = "Token für Ihren Bot abrufen:",
[nameof(TokenBotIntro)] = [nameof(TokenBotIntro)] =
"Der Token wird bei der Bot-Erstellung generiert. Falls er verloren gegangen ist, generieren Sie einen neuen:", "Der Token wird bei der Bot-Erstellung generiert. Falls er verloren gegangen ist, generieren Sie einen neuen:",
[nameof(TokenBotStep1)] = "1. Öffnen Sie Discord", [nameof(TokenBotStep1)] = "1. Öffnen Sie Discord",
[nameof(TokenBotStep2)] = "2. Öffnen Sie die Einstellungen Ihrer Anwendung", [nameof(TokenBotInstructions)] = """
[nameof(TokenBotStep3)] = "3. Navigieren Sie zum Abschnitt Bot auf der linken Seite", 2. Öffnen Sie die Einstellungen Ihrer Anwendung
[nameof(TokenBotStep4)] = "4. Klicken Sie unter Token auf Reset Token", 3. Navigieren Sie zum Abschnitt **Bot** auf der linken Seite
[nameof(TokenBotStep5)] = "5. Klicken Sie auf Yes, do it! und bestätigen Sie", 4. Klicken Sie unter **Token** auf **Reset Token**
[nameof(TokenBotStep6)] = 5. Klicken Sie auf **Yes, do it!** und bestätigen Sie
"* Integrationen, die den alten Token verwenden, hören auf zu funktionieren, bis sie aktualisiert werden", * Integrationen, die den alten Token verwenden, hören auf zu funktionieren, bis sie aktualisiert werden
[nameof(TokenBotStep7Before)] = "* Ihr Bot benötigt die aktivierte", * Ihr Bot benötigt die aktivierte **Message Content Intent**, um Nachrichten zu lesen
[nameof(TokenBotStep7After)] = "um Nachrichten zu lesen", """,
[nameof(TokenDeveloperPortalLinkText)] = "Entwicklerportal", [nameof(TokenDeveloperPortalLinkText)] = "Entwicklerportal",
[nameof(TokenDocumentationLinkText)] = "Dokumentation", [nameof(TokenDocumentationLinkText)] = "Dokumentation",
[nameof(TokenHelpText)] = "Bei Fragen oder Problemen lesen Sie die", [nameof(TokenHelpText)] = "Bei Fragen oder Problemen lesen Sie die",

View File

@@ -15,35 +15,34 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
[nameof(TokenPersonalHeader)] = "Cómo obtener el token para tu cuenta personal:", [nameof(TokenPersonalHeader)] = "Cómo obtener el token para tu cuenta personal:",
[nameof(TokenPersonalTosWarning)] = [nameof(TokenPersonalTosWarning)] =
"* Automatizar cuentas de usuario técnicamente va en contra de los ToS —", "* Automatizar cuentas de usuario técnicamente va en contra de los ToS — **bajo tu propio riesgo**!",
[nameof(TokenPersonalTosRisk)] = "bajo tu propio riesgo",
[nameof(TokenPersonalStep1Before)] = "1. Abre Discord en tu", [nameof(TokenPersonalStep1Before)] = "1. Abre Discord en tu",
[nameof(TokenPersonalStep1After)] = "e inicia sesión", [nameof(TokenPersonalStep1After)] = "e inicia sesión",
[nameof(TokenPersonalStep2)] = "2. Abre cualquier servidor o canal de mensaje directo", [nameof(TokenPersonalInstructions)] = """
[nameof(TokenPersonalStep3)] = 2. Abre cualquier servidor o canal de mensaje directo
"3. Presiona Ctrl+Shift+I para mostrar las herramientas de desarrollo", 3. Presiona **Ctrl+Shift+I** para mostrar las herramientas de desarrollo
[nameof(TokenPersonalStep4)] = "4. Navega a la pestaña Network", 4. Navega a la pestaña **Network**
[nameof(TokenPersonalStep5)] = "5. Presiona Ctrl+R para recargar", 5. Presiona **Ctrl+R** para recargar
[nameof(TokenPersonalStep6)] = 6. Cambia entre canales para activar solicitudes de red
"6. Cambia entre canales para activar solicitudes de red", 7. Busca una solicitud que comience con **messages**
[nameof(TokenPersonalStep7)] = "7. Busca una solicitud que comience con messages", 8. Selecciona la pestaña **Headers** a la derecha
[nameof(TokenPersonalStep8)] = "8. Selecciona la pestaña Headers a la derecha", 9. Desplázate hasta la sección **Request Headers**
[nameof(TokenPersonalStep9)] = "9. Desplázate hasta la sección Request Headers", 10. Copia el valor del encabezado **authorization**
[nameof(TokenPersonalStep10)] = "10. Copia el valor del encabezado authorization", """,
[nameof(TokenWebBrowserLinkText)] = "navegador web", [nameof(TokenWebBrowserLinkText)] = "navegador web",
// Token instructions (bot) // Token instructions (bot)
[nameof(TokenBotHeader)] = "Cómo obtener el token para tu bot:", [nameof(TokenBotHeader)] = "Cómo obtener el token para tu bot:",
[nameof(TokenBotIntro)] = [nameof(TokenBotIntro)] =
"El token se genera al crear el bot. Si lo perdiste, genera uno nuevo:", "El token se genera al crear el bot. Si lo perdiste, genera uno nuevo:",
[nameof(TokenBotStep1)] = "1. Abre Discord", [nameof(TokenBotStep1)] = "1. Abre Discord",
[nameof(TokenBotStep2)] = "2. Abre la configuración de tu aplicación", [nameof(TokenBotInstructions)] = """
[nameof(TokenBotStep3)] = "3. Navega a la sección Bot en el lado izquierdo", 2. Abre la configuración de tu aplicación
[nameof(TokenBotStep4)] = "4. En Token, haz clic en Reset Token", 3. Navega a la sección **Bot** en el lado izquierdo
[nameof(TokenBotStep5)] = "5. Haz clic en Yes, do it! y autentica para confirmar", 4. En **Token**, haz clic en **Reset Token**
[nameof(TokenBotStep6)] = 5. Haz clic en **Yes, do it!** y autentica para confirmar
"* Las integraciones que usen el token anterior dejarán de funcionar hasta que se actualicen", * Las integraciones que usen el token anterior dejarán de funcionar hasta que se actualicen
[nameof(TokenBotStep7Before)] = "* Tu bot necesita tener habilitado", * Tu bot necesita tener habilitado **Message Content Intent** para leer mensajes
[nameof(TokenBotStep7After)] = "para leer mensajes", """,
[nameof(TokenDeveloperPortalLinkText)] = "portal de desarrolladores", [nameof(TokenDeveloperPortalLinkText)] = "portal de desarrolladores",
[nameof(TokenDocumentationLinkText)] = "documentación", [nameof(TokenDocumentationLinkText)] = "documentación",
[nameof(TokenHelpText)] = "Si tienes preguntas o problemas, consulta la", [nameof(TokenHelpText)] = "Si tienes preguntas o problemas, consulta la",

View File

@@ -15,36 +15,34 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
[nameof(TokenPersonalHeader)] = "Як отримати токен для персонального акаунту:", [nameof(TokenPersonalHeader)] = "Як отримати токен для персонального акаунту:",
[nameof(TokenPersonalTosWarning)] = [nameof(TokenPersonalTosWarning)] =
"* Автоматизація облікових записів технічно порушує Умови обслуговування —", "* Автоматизація облікових записів технічно порушує Умови обслуговування — **на власний ризик**!",
[nameof(TokenPersonalTosRisk)] = "на власний ризик",
[nameof(TokenPersonalStep1Before)] = "1. Відкрийте Discord у вашому", [nameof(TokenPersonalStep1Before)] = "1. Відкрийте Discord у вашому",
[nameof(TokenPersonalStep1After)] = "та увійдіть", [nameof(TokenPersonalStep1After)] = "та увійдіть",
[nameof(TokenPersonalStep2)] = [nameof(TokenPersonalInstructions)] = """
"2. Відкрийте будь-який сервер або канал особистих повідомлень", 2. Відкрийте будь-який сервер або канал особистих повідомлень
[nameof(TokenPersonalStep3)] = 3. Натисніть **Ctrl+Shift+I**, щоб відкрити інструменти розробника
"3. Натисніть Ctrl+Shift+I, щоб відкрити інструменти розробника", 4. Перейдіть на вкладку **Network**
[nameof(TokenPersonalStep4)] = "4. Перейдіть на вкладку Network", 5. Натисніть **Ctrl+R** для перезавантаження
[nameof(TokenPersonalStep5)] = "5. Натисніть Ctrl+R для перезавантаження", 6. Перемикайтеся між каналами, щоб викликати мережеві запити
[nameof(TokenPersonalStep6)] = 7. Знайдіть запит, що починається з **messages**
"6. Перемикайтеся між каналами, щоб викликати мережеві запити", 8. Виберіть вкладку **Headers** праворуч
[nameof(TokenPersonalStep7)] = "7. Знайдіть запит, що починається з messages", 9. Прокрутіть до розділу **Request Headers**
[nameof(TokenPersonalStep8)] = "8. Виберіть вкладку Headers праворуч", 10. Скопіюйте значення заголовка **authorization**
[nameof(TokenPersonalStep9)] = "9. Прокрутіть до розділу Request Headers", """,
[nameof(TokenPersonalStep10)] = "10. Скопіюйте значення заголовка authorization",
[nameof(TokenWebBrowserLinkText)] = "веб-браузер", [nameof(TokenWebBrowserLinkText)] = "веб-браузер",
// Token instructions (bot) // Token instructions (bot)
[nameof(TokenBotHeader)] = "Як отримати токен для бота:", [nameof(TokenBotHeader)] = "Як отримати токен для бота:",
[nameof(TokenBotIntro)] = [nameof(TokenBotIntro)] =
"Токен генерується під час створення бота. Якщо ви його втратили, згенеруйте новий:", "Токен генерується під час створення бота. Якщо ви його втратили, згенеруйте новий:",
[nameof(TokenBotStep1)] = "1. Відкрийте Discord", [nameof(TokenBotStep1)] = "1. Відкрийте Discord",
[nameof(TokenBotStep2)] = "2. Відкрийте налаштування вашого застосунку", [nameof(TokenBotInstructions)] = """
[nameof(TokenBotStep3)] = "3. Перейдіть до розділу Bot ліворуч", 2. Відкрийте налаштування вашого застосунку
[nameof(TokenBotStep4)] = "4. В розділі Token натисніть Reset Token", 3. Перейдіть до розділу **Bot** ліворуч
[nameof(TokenBotStep5)] = "5. Натисніть Yes, do it! та підтвердьте", 4. В розділі **Token** натисніть **Reset Token**
[nameof(TokenBotStep6)] = 5. Натисніть **Yes, do it!** та підтвердьте
"* Інтеграції, що використовують попередній токен, перестануть працювати", * Інтеграції, що використовують попередній токен, перестануть працювати
[nameof(TokenBotStep7Before)] = "* Ваш бот повинен мати включений", * Ваш бот повинен мати включений **Message Content Intent** для читання повідомлень
[nameof(TokenBotStep7After)] = "для читання повідомлень", """,
[nameof(TokenDeveloperPortalLinkText)] = "портал розробника", [nameof(TokenDeveloperPortalLinkText)] = "портал розробника",
[nameof(TokenDocumentationLinkText)] = "документацію", [nameof(TokenDocumentationLinkText)] = "документацію",
[nameof(TokenHelpText)] = "Якщо у вас є запитання або проблеми, зверніться до", [nameof(TokenHelpText)] = "Якщо у вас є запитання або проблеми, зверніться до",

View File

@@ -87,31 +87,16 @@ public partial class LocalizationManager
// Token instructions (personal account) // Token instructions (personal account)
public string TokenPersonalHeader => Get(); public string TokenPersonalHeader => Get();
public string TokenPersonalTosWarning => Get(); public string TokenPersonalTosWarning => Get();
public string TokenPersonalTosRisk => Get();
public string TokenPersonalStep1Before => Get(); public string TokenPersonalStep1Before => Get();
public string TokenPersonalStep1After => Get(); public string TokenPersonalStep1After => Get();
public string TokenPersonalStep2 => Get(); public string TokenPersonalInstructions => Get();
public string TokenPersonalStep3 => Get();
public string TokenPersonalStep4 => Get();
public string TokenPersonalStep5 => Get();
public string TokenPersonalStep6 => Get();
public string TokenPersonalStep7 => Get();
public string TokenPersonalStep8 => Get();
public string TokenPersonalStep9 => Get();
public string TokenPersonalStep10 => Get();
public string TokenWebBrowserLinkText => Get(); public string TokenWebBrowserLinkText => Get();
// Token instructions (bot) // Token instructions (bot)
public string TokenBotHeader => Get(); public string TokenBotHeader => Get();
public string TokenBotIntro => Get(); public string TokenBotIntro => Get();
public string TokenBotStep1 => Get(); public string TokenBotStep1 => Get();
public string TokenBotStep2 => Get(); public string TokenBotInstructions => Get();
public string TokenBotStep3 => Get();
public string TokenBotStep4 => Get();
public string TokenBotStep5 => Get();
public string TokenBotStep6 => Get();
public string TokenBotStep7Before => Get();
public string TokenBotStep7After => Get();
public string TokenDeveloperPortalLinkText => Get(); public string TokenDeveloperPortalLinkText => Get();
public string TokenDocumentationLinkText => Get(); public string TokenDocumentationLinkText => Get();
public string TokenHelpText => Get(); public string TokenHelpText => Get();

View File

@@ -219,119 +219,74 @@
<!-- Placeholder / usage instructions --> <!-- Placeholder / usage instructions -->
<Panel IsVisible="{Binding !AvailableGuilds.Count}"> <Panel IsVisible="{Binding !AvailableGuilds.Count}">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<TextBlock <StackPanel Margin="32,16" Spacing="0">
Margin="32,16" <StackPanel.Styles>
FontSize="14" <Style Selector="TextBlock">
FontWeight="Light" <Setter Property="FontSize" Value="14" />
LineHeight="23"> <Setter Property="FontWeight" Value="Light" />
<Setter Property="LineHeight" Value="23" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</StackPanel.Styles>
<!-- User token --> <!-- User token -->
<InlineUIContainer> <TextBlock>
<materialIcons:MaterialIcon <InlineUIContainer>
Width="18" <materialIcons:MaterialIcon
Height="18" Width="18"
Margin="0,-2,0,0" Height="18"
Foreground="{DynamicResource PrimaryHueMidBrush}" Margin="0,-2,0,0"
Kind="Account" /> Foreground="{DynamicResource PrimaryHueMidBrush}"
</InlineUIContainer> Kind="Account" />
<Run BaselineAlignment="Center" Text="" /> </InlineUIContainer>
<Run <Run Text=" " />
BaselineAlignment="Center" <Run
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Text="{Binding LocalizationManager.TokenPersonalHeader}" /> Text="{Binding LocalizationManager.TokenPersonalHeader}" />
<LineBreak /> </TextBlock>
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalTosWarning}" /> <TextBlock Inlines="{Binding LocalizationManager.TokenPersonalTosWarning, Converter={x:Static converters:MarkdownToInlinesConverter.Instance}}" />
<Run
BaselineAlignment="Center"
FontWeight="SemiBold"
Text="{Binding LocalizationManager.TokenPersonalTosRisk}" /><Run Text="!" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep1Before}" /> <TextBlock>
<controls:HyperLink Command="{Binding OpenDiscordCommand}" Text="{Binding LocalizationManager.TokenWebBrowserLinkText}" /> <Run Text="{Binding LocalizationManager.TokenPersonalStep1Before}" />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep1After}" /> <controls:HyperLink Command="{Binding OpenDiscordCommand}" Text="{Binding LocalizationManager.TokenWebBrowserLinkText}" />
<LineBreak /> <Run Text="{Binding LocalizationManager.TokenPersonalStep1After}" />
</TextBlock>
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep2}" /> <TextBlock Inlines="{Binding LocalizationManager.TokenPersonalInstructions, Converter={x:Static converters:MarkdownToInlinesConverter.Instance}}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep3}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep4}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep5}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep6}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep7}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep8}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep9}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenPersonalStep10}" />
<LineBreak />
<LineBreak />
<!-- Bot token --> <!-- Bot token -->
<InlineUIContainer> <TextBlock Margin="0,12,0,0">
<materialIcons:MaterialIcon <InlineUIContainer>
Width="18" <materialIcons:MaterialIcon
Height="18" Width="18"
Margin="0,-2,0,0" Height="18"
Foreground="{DynamicResource PrimaryHueMidBrush}" Margin="0,-2,0,0"
Kind="Robot" /> Foreground="{DynamicResource PrimaryHueMidBrush}"
</InlineUIContainer> Kind="Robot" />
<Run BaselineAlignment="Center" Text="" /> </InlineUIContainer>
<Run <Run Text=" " />
BaselineAlignment="Center" <Run
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Text="{Binding LocalizationManager.TokenBotHeader}" /> Text="{Binding LocalizationManager.TokenBotHeader}" />
<LineBreak /> </TextBlock>
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotIntro}" /> <TextBlock Text="{Binding LocalizationManager.TokenBotIntro}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep1}" /> <TextBlock>
<controls:HyperLink Command="{Binding OpenDiscordDeveloperPortalCommand}" Text="{Binding LocalizationManager.TokenDeveloperPortalLinkText}" /> <Run Text="{Binding LocalizationManager.TokenBotStep1}" />
<LineBreak /> <controls:HyperLink Command="{Binding OpenDiscordDeveloperPortalCommand}" Text="{Binding LocalizationManager.TokenDeveloperPortalLinkText}" />
</TextBlock>
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep2}" /> <TextBlock Inlines="{Binding LocalizationManager.TokenBotInstructions, Converter={x:Static converters:MarkdownToInlinesConverter.Instance}}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep3}" /> <TextBlock Margin="0,12,0,0">
<LineBreak /> <Run Text="{Binding LocalizationManager.TokenHelpText}" />
<controls:HyperLink Command="{Binding ShowHelpCommand}" Text="{Binding LocalizationManager.TokenDocumentationLinkText}" />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep4}" /> </TextBlock>
<LineBreak /> </StackPanel>
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep5}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep6}" />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep7Before}" />
<Run
BaselineAlignment="Center"
FontWeight="SemiBold"
Text="Message Content Intent" />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenBotStep7After}" />
<LineBreak />
<LineBreak />
<Run BaselineAlignment="Center" Text="{Binding LocalizationManager.TokenHelpText}" />
<controls:HyperLink Command="{Binding ShowHelpCommand}" Text="{Binding LocalizationManager.TokenDocumentationLinkText}" />
</TextBlock>
</ScrollViewer> </ScrollViewer>
</Panel> </Panel>