mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-04-22 22:18:24 +00:00
Add localization (#1482)
Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
11
DiscordChatExporter.Gui/Localization/Language.cs
Normal file
11
DiscordChatExporter.Gui/Localization/Language.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public enum Language
|
||||
{
|
||||
System,
|
||||
English,
|
||||
Ukrainian,
|
||||
German,
|
||||
French,
|
||||
Spanish,
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> EnglishLocalization =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
// Dashboard
|
||||
[nameof(PullGuildsTooltip)] = "Pull available servers and channels (Enter)",
|
||||
[nameof(SettingsTooltip)] = "Settings",
|
||||
[nameof(LastMessageSentTooltip)] = "Last message sent:",
|
||||
[nameof(TokenWatermark)] = "Token",
|
||||
// Token instructions (personal account)
|
||||
[nameof(TokenPersonalHeader)] = "To get the token for your personal account:",
|
||||
[nameof(TokenPersonalTosWarning)] =
|
||||
"* Automating user accounts is technically against TOS — **use at your own risk**!",
|
||||
[nameof(TokenPersonalInstructions)] = """
|
||||
1. Open Discord in your web browser and login
|
||||
2. Open any server or direct message channel
|
||||
3. Press **Ctrl+Shift+I** to show developer tools
|
||||
4. Navigate to the **Network** tab
|
||||
5. Press **Ctrl+R** to reload
|
||||
6. Switch between random channels to trigger network requests
|
||||
7. Search for a request that starts with **messages**
|
||||
8. Select the **Headers** tab on the right
|
||||
9. Scroll down to the **Request Headers** section
|
||||
10. Copy the value of the **authorization** header
|
||||
""",
|
||||
// Token instructions (bot)
|
||||
[nameof(TokenBotHeader)] = "To get the token for your bot:",
|
||||
[nameof(TokenBotInstructions)] = """
|
||||
The token is generated during bot creation. If you lost it, generate a new one:
|
||||
|
||||
1. Open Discord [developer portal](https://discord.com/developers/applications)
|
||||
2. Open your application's settings
|
||||
3. Navigate to the **Bot** section on the left
|
||||
4. Under **Token** click **Reset Token**
|
||||
5. Click **Yes, do it!** and authenticate to confirm
|
||||
* Integrations using the previous token will stop working until updated
|
||||
* Your bot needs to have the **Message Content Intent** enabled to read messages
|
||||
""",
|
||||
[nameof(TokenHelpText)] =
|
||||
"If you have questions or issues, please refer to the [documentation](https://github.com/Tyrrrz/DiscordChatExporter/tree/master/.docs)",
|
||||
// Settings
|
||||
[nameof(SettingsTitle)] = "Settings",
|
||||
[nameof(ThemeLabel)] = "Theme",
|
||||
[nameof(ThemeTooltip)] = "Preferred user interface theme",
|
||||
[nameof(LanguageLabel)] = "Language",
|
||||
[nameof(LanguageTooltip)] = "Preferred user interface language",
|
||||
[nameof(AutoUpdateLabel)] = "Auto-update",
|
||||
[nameof(AutoUpdateTooltip)] = "Perform automatic updates on every launch",
|
||||
[nameof(PersistTokenLabel)] = "Persist token",
|
||||
[nameof(PersistTokenTooltip)] =
|
||||
"Save the last used token to a file so that it can be persisted between sessions",
|
||||
[nameof(RateLimitPreferenceLabel)] = "Rate limit preference",
|
||||
[nameof(RateLimitPreferenceTooltip)] =
|
||||
"Whether to respect advisory rate limits. If disabled, only hard rate limits (i.e. 429 responses) will be respected.",
|
||||
[nameof(ShowThreadsLabel)] = "Show threads",
|
||||
[nameof(ShowThreadsTooltip)] = "Which types of threads to show in the channel list",
|
||||
[nameof(LocaleLabel)] = "Locale",
|
||||
[nameof(LocaleTooltip)] = "Locale to use when formatting dates and numbers",
|
||||
[nameof(NormalizeToUtcLabel)] = "Normalize to UTC",
|
||||
[nameof(NormalizeToUtcTooltip)] = "Normalize all timestamps to UTC+0",
|
||||
[nameof(ParallelLimitLabel)] = "Parallel limit",
|
||||
[nameof(ParallelLimitTooltip)] = "How many channels can be exported at the same time",
|
||||
// Export Setup
|
||||
[nameof(ChannelsSelectedText)] = "channels selected",
|
||||
[nameof(OutputPathLabel)] = "Output path",
|
||||
[nameof(OutputPathTooltip)] = """
|
||||
Output file or directory path.
|
||||
|
||||
If a directory is specified, file names will be generated automatically based on the channel names and export parameters.
|
||||
|
||||
Directory paths must end with a slash to avoid ambiguity.
|
||||
|
||||
Available template tokens:
|
||||
- **%g** — server ID
|
||||
- **%G** — server name
|
||||
- **%t** — category ID
|
||||
- **%T** — category name
|
||||
- **%c** — channel ID
|
||||
- **%C** — channel name
|
||||
- **%p** — channel position
|
||||
- **%P** — category position
|
||||
- **%a** — after date
|
||||
- **%b** — before date
|
||||
- **%d** — current date
|
||||
""",
|
||||
[nameof(FormatLabel)] = "Format",
|
||||
[nameof(FormatTooltip)] = "Export format",
|
||||
[nameof(AfterDateLabel)] = "After (date)",
|
||||
[nameof(AfterDateTooltip)] = "Only include messages sent after this date",
|
||||
[nameof(BeforeDateLabel)] = "Before (date)",
|
||||
[nameof(BeforeDateTooltip)] = "Only include messages sent before this date",
|
||||
[nameof(AfterTimeLabel)] = "After (time)",
|
||||
[nameof(AfterTimeTooltip)] = "Only include messages sent after this time",
|
||||
[nameof(BeforeTimeLabel)] = "Before (time)",
|
||||
[nameof(BeforeTimeTooltip)] = "Only include messages sent before this time",
|
||||
[nameof(PartitionLimitLabel)] = "Partition limit",
|
||||
[nameof(PartitionLimitTooltip)] =
|
||||
"Split the output into partitions, each limited to the specified number of messages (e.g. '100') or file size (e.g. '10mb')",
|
||||
[nameof(MessageFilterLabel)] = "Message filter",
|
||||
[nameof(MessageFilterTooltip)] =
|
||||
"Only include messages that satisfy this filter (e.g. 'from:foo#1234' or 'has:image'). See the documentation for more info.",
|
||||
[nameof(FormatMarkdownLabel)] = "Format markdown",
|
||||
[nameof(FormatMarkdownTooltip)] =
|
||||
"Process markdown, mentions, and other special tokens",
|
||||
[nameof(DownloadAssetsLabel)] = "Download assets",
|
||||
[nameof(DownloadAssetsTooltip)] =
|
||||
"Download assets referenced by the export (user avatars, attached files, embedded images, etc.)",
|
||||
[nameof(ReuseAssetsLabel)] = "Reuse assets",
|
||||
[nameof(ReuseAssetsTooltip)] =
|
||||
"Reuse previously downloaded assets to avoid redundant requests",
|
||||
[nameof(AssetsDirPathLabel)] = "Assets directory path",
|
||||
[nameof(AssetsDirPathTooltip)] =
|
||||
"Download assets to this directory. If not specified, the asset directory path will be derived from the output path.",
|
||||
[nameof(AdvancedOptionsTooltip)] = "Toggle advanced options",
|
||||
[nameof(ExportButton)] = "EXPORT",
|
||||
// Common buttons
|
||||
[nameof(CloseButton)] = "CLOSE",
|
||||
[nameof(CancelButton)] = "CANCEL",
|
||||
// Dialog messages
|
||||
[nameof(UkraineSupportTitle)] = "Thank you for supporting Ukraine!",
|
||||
[nameof(UkraineSupportMessage)] = """
|
||||
As Russia wages a genocidal war against my country, I'm grateful to everyone who continues to stand with Ukraine in our fight for freedom.
|
||||
|
||||
Click LEARN MORE to find ways that you can help.
|
||||
""",
|
||||
[nameof(LearnMoreButton)] = "LEARN MORE",
|
||||
[nameof(UnstableBuildTitle)] = "Unstable build warning",
|
||||
[nameof(UnstableBuildMessage)] = """
|
||||
You're using a development build of {0}. These builds are not thoroughly tested and may contain bugs.
|
||||
|
||||
Auto-updates are disabled for development builds.
|
||||
|
||||
Click SEE RELEASES if you want to download a stable release instead.
|
||||
""",
|
||||
[nameof(SeeReleasesButton)] = "SEE RELEASES",
|
||||
[nameof(UpdateDownloadingMessage)] = "Downloading update to {0} v{1}...",
|
||||
[nameof(UpdateReadyMessage)] =
|
||||
"Update has been downloaded and will be installed when you exit",
|
||||
[nameof(UpdateInstallNowButton)] = "INSTALL NOW",
|
||||
[nameof(UpdateFailedMessage)] = "Failed to perform application update",
|
||||
[nameof(ErrorPullingGuildsTitle)] = "Error pulling servers",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Error pulling channels",
|
||||
[nameof(ErrorExportingTitle)] = "Error exporting channel(s)",
|
||||
[nameof(SuccessfulExportMessage)] = "Successfully exported {0} channel(s)",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> FrenchLocalization = new Dictionary<
|
||||
string,
|
||||
string
|
||||
>
|
||||
{
|
||||
// Dashboard
|
||||
[nameof(PullGuildsTooltip)] = "Charger les serveurs et canaux disponibles (Entrée)",
|
||||
[nameof(SettingsTooltip)] = "Paramètres",
|
||||
[nameof(LastMessageSentTooltip)] = "Dernier message envoyé :",
|
||||
[nameof(TokenWatermark)] = "Token",
|
||||
// Token instructions (personal account)
|
||||
[nameof(TokenPersonalHeader)] = "Obtenir le token pour votre compte personnel :",
|
||||
[nameof(TokenPersonalTosWarning)] =
|
||||
"* L'automatisation des comptes est techniquement contraire aux CGU — **à vos risques et périls**!",
|
||||
[nameof(TokenPersonalInstructions)] = """
|
||||
1. Ouvrez Discord dans votre navigateur web et connectez-vous
|
||||
2. Ouvrez n'importe quel serveur ou canal de message direct
|
||||
3. Appuyez sur **Ctrl+Shift+I** pour afficher les outils de développement
|
||||
4. Naviguez vers l'onglet **Network**
|
||||
5. Appuyez sur **Ctrl+R** pour recharger
|
||||
6. Changez de canal pour déclencher des requêtes réseau
|
||||
7. Cherchez une requête commençant par **messages**
|
||||
8. Sélectionnez l'onglet **Headers** à droite
|
||||
9. Faites défiler jusqu'à la section **Request Headers**
|
||||
10. Copiez la valeur de l'en-tête **authorization**
|
||||
""",
|
||||
// Token instructions (bot)
|
||||
[nameof(TokenBotHeader)] = "Obtenir le token pour votre bot :",
|
||||
[nameof(TokenBotInstructions)] = """
|
||||
Le token est généré lors de la création du bot. Si vous l'avez perdu, générez-en un nouveau :
|
||||
|
||||
1. Ouvrez Discord [portail développeur](https://discord.com/developers/applications)
|
||||
2. Ouvrez les paramètres de votre application
|
||||
3. Naviguez vers la section **Bot** à gauche
|
||||
4. Sous **Token**, cliquez sur **Reset Token**
|
||||
5. Cliquez sur **Yes, do it!** et confirmez
|
||||
* Les intégrations utilisant l'ancien token cesseront de fonctionner jusqu'à leur mise à jour
|
||||
* Votre bot doit avoir l'option **Message Content Intent** activée pour lire les messages
|
||||
""",
|
||||
[nameof(TokenHelpText)] =
|
||||
"Pour les questions ou problèmes, veuillez consulter la [documentation](https://github.com/Tyrrrz/DiscordChatExporter/tree/master/.docs)",
|
||||
// Settings
|
||||
[nameof(SettingsTitle)] = "Paramètres",
|
||||
[nameof(ThemeLabel)] = "Thème",
|
||||
[nameof(ThemeTooltip)] = "Thème d'interface préféré",
|
||||
[nameof(LanguageLabel)] = "Langue",
|
||||
[nameof(LanguageTooltip)] = "Langue d'interface préférée",
|
||||
[nameof(AutoUpdateLabel)] = "Mise à jour automatique",
|
||||
[nameof(AutoUpdateTooltip)] = "Effectuer des mises à jour automatiques à chaque lancement",
|
||||
[nameof(PersistTokenLabel)] = "Conserver le token",
|
||||
[nameof(PersistTokenTooltip)] =
|
||||
"Enregistrer le dernier token utilisé dans un fichier pour le conserver entre les sessions",
|
||||
[nameof(RateLimitPreferenceLabel)] = "Préférence de limite de débit",
|
||||
[nameof(RateLimitPreferenceTooltip)] =
|
||||
"Indique s'il faut respecter les limites de débit recommandées. Si désactivé, seules les limites strictes (réponses 429) seront respectées.",
|
||||
[nameof(ShowThreadsLabel)] = "Afficher les fils",
|
||||
[nameof(ShowThreadsTooltip)] = "Quels types de fils afficher dans la liste des canaux",
|
||||
[nameof(LocaleLabel)] = "Locale",
|
||||
[nameof(LocaleTooltip)] = "Locale à utiliser pour le formatage des dates et des nombres",
|
||||
[nameof(NormalizeToUtcLabel)] = "Normaliser en UTC",
|
||||
[nameof(NormalizeToUtcTooltip)] = "Normaliser tous les horodatages en UTC+0",
|
||||
[nameof(ParallelLimitLabel)] = "Limite parallèle",
|
||||
[nameof(ParallelLimitTooltip)] = "Combien de canaux peuvent être exportés simultanément",
|
||||
// Export Setup
|
||||
[nameof(ChannelsSelectedText)] = "canaux sélectionnés",
|
||||
[nameof(OutputPathLabel)] = "Chemin de sortie",
|
||||
[nameof(OutputPathTooltip)] = """
|
||||
Chemin du fichier ou répertoire de sortie.
|
||||
|
||||
Si un répertoire est spécifié, les noms de fichiers seront générés automatiquement en fonction des noms de canaux et des paramètres d'exportation.
|
||||
|
||||
Les chemins de répertoire doivent se terminer par un slash pour éviter toute ambiguïté.
|
||||
|
||||
Jetons de modèle disponibles :
|
||||
- **%g** — ID du serveur
|
||||
- **%G** — nom du serveur
|
||||
- **%t** — ID de la catégorie
|
||||
- **%T** — nom de la catégorie
|
||||
- **%c** — ID du canal
|
||||
- **%C** — nom du canal
|
||||
- **%p** — position du canal
|
||||
- **%P** — position de la catégorie
|
||||
- **%a** — date après
|
||||
- **%b** — date avant
|
||||
- **%d** — date actuelle
|
||||
""",
|
||||
[nameof(FormatLabel)] = "Format",
|
||||
[nameof(FormatTooltip)] = "Format d'exportation",
|
||||
[nameof(AfterDateLabel)] = "Après (date)",
|
||||
[nameof(AfterDateTooltip)] = "Inclure uniquement les messages envoyés après cette date",
|
||||
[nameof(BeforeDateLabel)] = "Avant (date)",
|
||||
[nameof(BeforeDateTooltip)] = "Inclure uniquement les messages envoyés avant cette date",
|
||||
[nameof(AfterTimeLabel)] = "Après (heure)",
|
||||
[nameof(AfterTimeTooltip)] = "Inclure uniquement les messages envoyés après cette heure",
|
||||
[nameof(BeforeTimeLabel)] = "Avant (heure)",
|
||||
[nameof(BeforeTimeTooltip)] = "Inclure uniquement les messages envoyés avant cette heure",
|
||||
[nameof(PartitionLimitLabel)] = "Limite de partition",
|
||||
[nameof(PartitionLimitTooltip)] =
|
||||
"Diviser la sortie en partitions, chacune limitée au nombre de messages spécifié (ex. '100') ou à la taille de fichier (ex. '10mb')",
|
||||
[nameof(MessageFilterLabel)] = "Filtre de messages",
|
||||
[nameof(MessageFilterTooltip)] =
|
||||
"Inclure uniquement les messages satisfaisant ce filtre (ex. 'from:foo#1234' ou 'has:image'). Voir la documentation pour plus d'informations.",
|
||||
[nameof(FormatMarkdownLabel)] = "Formater le markdown",
|
||||
[nameof(FormatMarkdownTooltip)] =
|
||||
"Traiter le markdown, les mentions et autres tokens spéciaux",
|
||||
[nameof(DownloadAssetsLabel)] = "Télécharger les ressources",
|
||||
[nameof(DownloadAssetsTooltip)] =
|
||||
"Télécharger les ressources référencées par l'export (avatars, fichiers joints, images intégrées, etc.)",
|
||||
[nameof(ReuseAssetsLabel)] = "Réutiliser les ressources",
|
||||
[nameof(ReuseAssetsTooltip)] =
|
||||
"Réutiliser les ressources précédemment téléchargées pour éviter les requêtes redondantes",
|
||||
[nameof(AssetsDirPathLabel)] = "Chemin du dossier des ressources",
|
||||
[nameof(AssetsDirPathTooltip)] =
|
||||
"Télécharger les ressources dans ce dossier. Si non spécifié, le chemin sera dérivé du chemin de sortie.",
|
||||
[nameof(AdvancedOptionsTooltip)] = "Basculer les options avancées",
|
||||
[nameof(ExportButton)] = "EXPORTER",
|
||||
// Common buttons
|
||||
[nameof(CloseButton)] = "FERMER",
|
||||
[nameof(CancelButton)] = "ANNULER",
|
||||
// Dialog messages
|
||||
[nameof(UkraineSupportTitle)] = "Merci de soutenir l'Ukraine !",
|
||||
[nameof(UkraineSupportMessage)] = """
|
||||
Alors que la Russie mène une guerre génocidaire contre mon pays, je suis reconnaissant envers tous ceux qui continuent à soutenir l'Ukraine dans notre lutte pour la liberté.
|
||||
|
||||
Cliquez sur EN SAVOIR PLUS pour trouver des moyens d'aider.
|
||||
""",
|
||||
[nameof(LearnMoreButton)] = "EN SAVOIR PLUS",
|
||||
[nameof(UnstableBuildTitle)] = "Avertissement : version instable",
|
||||
[nameof(UnstableBuildMessage)] = """
|
||||
Vous utilisez une version de développement de {0}. Ces versions ne sont pas rigoureusement testées et peuvent contenir des bugs.
|
||||
|
||||
Les mises à jour automatiques sont désactivées pour les versions de développement.
|
||||
|
||||
Cliquez sur VOIR LES VERSIONS pour télécharger une version stable.
|
||||
""",
|
||||
[nameof(SeeReleasesButton)] = "VOIR LES VERSIONS",
|
||||
[nameof(UpdateDownloadingMessage)] = "Téléchargement de la mise à jour vers {0} v{1}...",
|
||||
[nameof(UpdateReadyMessage)] =
|
||||
"La mise à jour a été téléchargée et sera installée à la fermeture",
|
||||
[nameof(UpdateInstallNowButton)] = "INSTALLER MAINTENANT",
|
||||
[nameof(UpdateFailedMessage)] = "Échec de la mise à jour de l'application",
|
||||
[nameof(ErrorPullingGuildsTitle)] = "Erreur lors du chargement des serveurs",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Erreur lors du chargement des canaux",
|
||||
[nameof(ErrorExportingTitle)] = "Erreur lors de l'exportation des canaux",
|
||||
[nameof(SuccessfulExportMessage)] = "{0} canal(-aux) exporté(s) avec succès",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> GermanLocalization = new Dictionary<
|
||||
string,
|
||||
string
|
||||
>
|
||||
{
|
||||
// Dashboard
|
||||
[nameof(PullGuildsTooltip)] = "Verfügbare Server und Kanäle laden (Enter)",
|
||||
[nameof(SettingsTooltip)] = "Einstellungen",
|
||||
[nameof(LastMessageSentTooltip)] = "Letzte Nachricht gesendet:",
|
||||
[nameof(TokenWatermark)] = "Token",
|
||||
// Token instructions (personal account)
|
||||
[nameof(TokenPersonalHeader)] = "Token für Ihr persönliches Konto abrufen:",
|
||||
[nameof(TokenPersonalTosWarning)] =
|
||||
"* Das Automatisieren von Benutzerkonten verstößt technisch gegen die AGB — **auf eigene Gefahr**!",
|
||||
[nameof(TokenPersonalInstructions)] = """
|
||||
1. Öffnen Sie Discord in Ihrem Webbrowser und melden Sie sich an
|
||||
2. Öffnen Sie einen Server oder einen direkten Nachrichtenkanal
|
||||
3. Drücken Sie **Ctrl+Shift+I**, um die Entwicklertools anzuzeigen
|
||||
4. Navigieren Sie zum Reiter **Network**
|
||||
5. Drücken Sie **Ctrl+R** zum Neuladen
|
||||
6. Wechseln Sie zwischen Kanälen, um Netzwerkanfragen auszulösen
|
||||
7. Suchen Sie nach einer Anfrage, die mit **messages** beginnt
|
||||
8. Wählen Sie den Reiter **Headers** auf der rechten Seite
|
||||
9. Scrollen Sie nach unten zum Abschnitt **Request Headers**
|
||||
10. Kopieren Sie den Wert des Headers **authorization**
|
||||
""",
|
||||
// Token instructions (bot)
|
||||
[nameof(TokenBotHeader)] = "Token für Ihren Bot abrufen:",
|
||||
[nameof(TokenBotInstructions)] = """
|
||||
Der Token wird bei der Bot-Erstellung generiert. Falls er verloren gegangen ist, generieren Sie einen neuen:
|
||||
|
||||
1. Öffnen Sie Discord [Entwicklerportal](https://discord.com/developers/applications)
|
||||
2. Öffnen Sie die Einstellungen Ihrer Anwendung
|
||||
3. Navigieren Sie zum Abschnitt **Bot** auf der linken Seite
|
||||
4. Klicken Sie unter **Token** auf **Reset Token**
|
||||
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
|
||||
* Ihr Bot benötigt die aktivierte **Message Content Intent**, um Nachrichten zu lesen
|
||||
""",
|
||||
[nameof(TokenHelpText)] =
|
||||
"Bei Fragen oder Problemen lesen Sie die [Dokumentation](https://github.com/Tyrrrz/DiscordChatExporter/tree/master/.docs)",
|
||||
// Settings
|
||||
[nameof(SettingsTitle)] = "Einstellungen",
|
||||
[nameof(ThemeLabel)] = "Design",
|
||||
[nameof(ThemeTooltip)] = "Bevorzugtes Oberflächendesign",
|
||||
[nameof(LanguageLabel)] = "Sprache",
|
||||
[nameof(LanguageTooltip)] = "Bevorzugte Sprache der Benutzeroberfläche",
|
||||
[nameof(AutoUpdateLabel)] = "Automatische Updates",
|
||||
[nameof(AutoUpdateTooltip)] = "Automatische Updates bei jedem Start durchführen",
|
||||
[nameof(PersistTokenLabel)] = "Token speichern",
|
||||
[nameof(PersistTokenTooltip)] =
|
||||
"Den zuletzt verwendeten Token in einer Datei speichern, damit er zwischen Sitzungen erhalten bleibt",
|
||||
[nameof(RateLimitPreferenceLabel)] = "Ratenlimit-Einstellung",
|
||||
[nameof(RateLimitPreferenceTooltip)] =
|
||||
"Ob empfohlene Ratenlimits eingehalten werden sollen. Wenn deaktiviert, werden nur harte Ratenlimits (d. h. 429-Antworten) eingehalten.",
|
||||
[nameof(ShowThreadsLabel)] = "Threads anzeigen",
|
||||
[nameof(ShowThreadsTooltip)] = "Welche Thread-Typen in der Kanalliste angezeigt werden",
|
||||
[nameof(LocaleLabel)] = "Gebietsschema",
|
||||
[nameof(LocaleTooltip)] = "Gebietsschema für die Formatierung von Daten und Zahlen",
|
||||
[nameof(NormalizeToUtcLabel)] = "Auf UTC normalisieren",
|
||||
[nameof(NormalizeToUtcTooltip)] = "Alle Zeitstempel auf UTC+0 normalisieren",
|
||||
[nameof(ParallelLimitLabel)] = "Paralleles Limit",
|
||||
[nameof(ParallelLimitTooltip)] = "Wie viele Kanäle gleichzeitig exportiert werden können",
|
||||
// Export Setup
|
||||
[nameof(ChannelsSelectedText)] = "Kanäle ausgewählt",
|
||||
[nameof(OutputPathLabel)] = "Ausgabepfad",
|
||||
[nameof(OutputPathTooltip)] = """
|
||||
Ausgabedatei- oder Verzeichnispfad.
|
||||
|
||||
Wenn ein Verzeichnis angegeben wird, werden Dateinamen automatisch basierend auf den Kanalnamen und Exportparametern generiert.
|
||||
|
||||
Verzeichnispfade müssen mit einem Schrägstrich enden, um Mehrdeutigkeiten zu vermeiden.
|
||||
|
||||
Verfügbare Vorlagen-Token:
|
||||
- **%g** — Server-ID
|
||||
- **%G** — Servername
|
||||
- **%t** — Kategorie-ID
|
||||
- **%T** — Kategoriename
|
||||
- **%c** — Kanal-ID
|
||||
- **%C** — Kanalname
|
||||
- **%p** — Kanalposition
|
||||
- **%P** — Kategorieposition
|
||||
- **%a** — Datum ab
|
||||
- **%b** — Datum bis
|
||||
- **%d** — aktuelles Datum
|
||||
""",
|
||||
[nameof(FormatLabel)] = "Format",
|
||||
[nameof(FormatTooltip)] = "Exportformat",
|
||||
[nameof(AfterDateLabel)] = "Nach (Datum)",
|
||||
[nameof(AfterDateTooltip)] =
|
||||
"Nur Nachrichten einschließen, die nach diesem Datum gesendet wurden",
|
||||
[nameof(BeforeDateLabel)] = "Vor (Datum)",
|
||||
[nameof(BeforeDateTooltip)] =
|
||||
"Nur Nachrichten einschließen, die vor diesem Datum gesendet wurden",
|
||||
[nameof(AfterTimeLabel)] = "Nach (Uhrzeit)",
|
||||
[nameof(AfterTimeTooltip)] =
|
||||
"Nur Nachrichten einschließen, die nach dieser Uhrzeit gesendet wurden",
|
||||
[nameof(BeforeTimeLabel)] = "Vor (Uhrzeit)",
|
||||
[nameof(BeforeTimeTooltip)] =
|
||||
"Nur Nachrichten einschließen, die vor dieser Uhrzeit gesendet wurden",
|
||||
[nameof(PartitionLimitLabel)] = "Partitionslimit",
|
||||
[nameof(PartitionLimitTooltip)] =
|
||||
"Die Ausgabe in Partitionen aufteilen, jede begrenzt auf die angegebene Anzahl von Nachrichten (z. B. '100') oder Dateigröße (z. B. '10mb')",
|
||||
[nameof(MessageFilterLabel)] = "Nachrichtenfilter",
|
||||
[nameof(MessageFilterTooltip)] =
|
||||
"Nur Nachrichten einschließen, die diesem Filter entsprechen (z. B. 'from:foo#1234' oder 'has:image'). Weitere Informationen finden Sie in der Dokumentation.",
|
||||
[nameof(FormatMarkdownLabel)] = "Markdown formatieren",
|
||||
[nameof(FormatMarkdownTooltip)] =
|
||||
"Markdown, Erwähnungen und andere spezielle Token verarbeiten",
|
||||
[nameof(DownloadAssetsLabel)] = "Assets herunterladen",
|
||||
[nameof(DownloadAssetsTooltip)] =
|
||||
"Vom Export referenzierte Assets herunterladen (Benutzeravatare, angehängte Dateien, eingebettete Bilder usw.)",
|
||||
[nameof(ReuseAssetsLabel)] = "Assets wiederverwenden",
|
||||
[nameof(ReuseAssetsTooltip)] =
|
||||
"Zuvor heruntergeladene Assets wiederverwenden, um redundante Anfragen zu vermeiden",
|
||||
[nameof(AssetsDirPathLabel)] = "Asset-Verzeichnispfad",
|
||||
[nameof(AssetsDirPathTooltip)] =
|
||||
"Assets in dieses Verzeichnis herunterladen. Wenn nicht angegeben, wird der Asset-Verzeichnispfad vom Ausgabepfad abgeleitet.",
|
||||
[nameof(AdvancedOptionsTooltip)] = "Erweiterte Optionen umschalten",
|
||||
[nameof(ExportButton)] = "EXPORTIEREN",
|
||||
// Common buttons
|
||||
[nameof(CloseButton)] = "SCHLIESSEN",
|
||||
[nameof(CancelButton)] = "ABBRECHEN",
|
||||
// Dialog messages
|
||||
[nameof(UkraineSupportTitle)] = "Danke für Ihre Unterstützung der Ukraine!",
|
||||
[nameof(UkraineSupportMessage)] = """
|
||||
Während Russland einen Vernichtungskrieg gegen mein Land führt, bin ich jedem dankbar, der weiterhin an der Seite der Ukraine in unserem Kampf für die Freiheit steht.
|
||||
|
||||
Klicken Sie auf MEHR ERFAHREN, um Möglichkeiten der Unterstützung zu finden.
|
||||
""",
|
||||
[nameof(LearnMoreButton)] = "MEHR ERFAHREN",
|
||||
[nameof(UnstableBuildTitle)] = "Warnung: Instabile Version",
|
||||
[nameof(UnstableBuildMessage)] = """
|
||||
Sie verwenden eine Entwicklungsversion von {0}. Diese Versionen wurden nicht gründlich getestet und können Fehler enthalten.
|
||||
|
||||
Automatische Updates sind für Entwicklungsversionen deaktiviert.
|
||||
|
||||
Klicken Sie auf RELEASES ANZEIGEN, wenn Sie stattdessen eine stabile Version herunterladen möchten.
|
||||
""",
|
||||
[nameof(SeeReleasesButton)] = "RELEASES ANZEIGEN",
|
||||
[nameof(UpdateDownloadingMessage)] = "Update auf {0} v{1} wird heruntergeladen...",
|
||||
[nameof(UpdateReadyMessage)] =
|
||||
"Update wurde heruntergeladen und wird beim Beenden installiert",
|
||||
[nameof(UpdateInstallNowButton)] = "JETZT INSTALLIEREN",
|
||||
[nameof(UpdateFailedMessage)] = "Anwendungsupdate konnte nicht durchgeführt werden",
|
||||
[nameof(ErrorPullingGuildsTitle)] = "Fehler beim Laden der Server",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Fehler beim Laden der Kanäle",
|
||||
[nameof(ErrorExportingTitle)] = "Fehler beim Exportieren der Kanäle",
|
||||
[nameof(SuccessfulExportMessage)] = "{0} Kanal/-äle erfolgreich exportiert",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> SpanishLocalization =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
// Dashboard
|
||||
[nameof(PullGuildsTooltip)] = "Cargar servidores y canales disponibles (Enter)",
|
||||
[nameof(SettingsTooltip)] = "Ajustes",
|
||||
[nameof(LastMessageSentTooltip)] = "Último mensaje enviado:",
|
||||
[nameof(TokenWatermark)] = "Token",
|
||||
// Token instructions (personal account)
|
||||
[nameof(TokenPersonalHeader)] = "Cómo obtener el token para tu cuenta personal:",
|
||||
[nameof(TokenPersonalTosWarning)] =
|
||||
"* Automatizar cuentas de usuario técnicamente va en contra de los ToS — **bajo tu propio riesgo**!",
|
||||
[nameof(TokenPersonalInstructions)] = """
|
||||
1. Abre Discord en tu navegador web e inicia sesión
|
||||
2. Abre cualquier servidor o canal de mensaje directo
|
||||
3. Presiona **Ctrl+Shift+I** para mostrar las herramientas de desarrollo
|
||||
4. Navega a la pestaña **Network**
|
||||
5. Presiona **Ctrl+R** para recargar
|
||||
6. Cambia entre canales para activar solicitudes de red
|
||||
7. Busca una solicitud que comience con **messages**
|
||||
8. Selecciona la pestaña **Headers** a la derecha
|
||||
9. Desplázate hasta la sección **Request Headers**
|
||||
10. Copia el valor del encabezado **authorization**
|
||||
""",
|
||||
// Token instructions (bot)
|
||||
[nameof(TokenBotHeader)] = "Cómo obtener el token para tu bot:",
|
||||
[nameof(TokenBotInstructions)] = """
|
||||
El token se genera al crear el bot. Si lo perdiste, genera uno nuevo:
|
||||
|
||||
1. Abre Discord [portal de desarrolladores](https://discord.com/developers/applications)
|
||||
2. Abre la configuración de tu aplicación
|
||||
3. Navega a la sección **Bot** en el lado izquierdo
|
||||
4. En **Token**, haz clic en **Reset Token**
|
||||
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
|
||||
* Tu bot necesita tener habilitado **Message Content Intent** para leer mensajes
|
||||
""",
|
||||
[nameof(TokenHelpText)] =
|
||||
"Si tienes preguntas o problemas, consulta la [documentación](https://github.com/Tyrrrz/DiscordChatExporter/tree/master/.docs)",
|
||||
// Settings
|
||||
[nameof(SettingsTitle)] = "Ajustes",
|
||||
[nameof(ThemeLabel)] = "Tema",
|
||||
[nameof(ThemeTooltip)] = "Tema de interfaz preferido",
|
||||
[nameof(LanguageLabel)] = "Idioma",
|
||||
[nameof(LanguageTooltip)] = "Idioma de interfaz preferido",
|
||||
[nameof(AutoUpdateLabel)] = "Actualización automática",
|
||||
[nameof(AutoUpdateTooltip)] = "Realizar actualizaciones automáticas en cada inicio",
|
||||
[nameof(PersistTokenLabel)] = "Guardar token",
|
||||
[nameof(PersistTokenTooltip)] =
|
||||
"Guardar el último token utilizado en un archivo para conservarlo entre sesiones",
|
||||
[nameof(RateLimitPreferenceLabel)] = "Preferencia de límite de velocidad",
|
||||
[nameof(RateLimitPreferenceTooltip)] =
|
||||
"Si se deben respetar los límites de velocidad recomendados. Si está desactivado, solo se respetarán los límites estrictos (respuestas 429).",
|
||||
[nameof(ShowThreadsLabel)] = "Mostrar hilos",
|
||||
[nameof(ShowThreadsTooltip)] = "Qué tipos de hilos mostrar en la lista de canales",
|
||||
[nameof(LocaleLabel)] = "Configuración regional",
|
||||
[nameof(LocaleTooltip)] = "Configuración regional para el formato de fechas y números",
|
||||
[nameof(NormalizeToUtcLabel)] = "Normalizar a UTC",
|
||||
[nameof(NormalizeToUtcTooltip)] = "Normalizar todas las marcas de tiempo a UTC+0",
|
||||
[nameof(ParallelLimitLabel)] = "Límite paralelo",
|
||||
[nameof(ParallelLimitTooltip)] = "Cuántos canales pueden exportarse al mismo tiempo",
|
||||
// Export Setup
|
||||
[nameof(ChannelsSelectedText)] = "canales seleccionados",
|
||||
[nameof(OutputPathLabel)] = "Ruta de salida",
|
||||
[nameof(OutputPathTooltip)] = """
|
||||
Ruta del archivo o directorio de salida.
|
||||
|
||||
Si se especifica un directorio, los nombres de archivo se generarán automáticamente según los nombres de los canales y los parámetros de exportación.
|
||||
|
||||
Las rutas de directorio deben terminar con una barra diagonal para evitar ambigüedades.
|
||||
|
||||
Tokens de plantilla disponibles:
|
||||
- **%g** — ID del servidor
|
||||
- **%G** — nombre del servidor
|
||||
- **%t** — ID de categoría
|
||||
- **%T** — nombre de categoría
|
||||
- **%c** — ID del canal
|
||||
- **%C** — nombre del canal
|
||||
- **%p** — posición del canal
|
||||
- **%P** — posición de la categoría
|
||||
- **%a** — fecha desde
|
||||
- **%b** — fecha hasta
|
||||
- **%d** — fecha actual
|
||||
""",
|
||||
[nameof(FormatLabel)] = "Formato",
|
||||
[nameof(FormatTooltip)] = "Formato de exportación",
|
||||
[nameof(AfterDateLabel)] = "Después (fecha)",
|
||||
[nameof(AfterDateTooltip)] = "Solo incluir mensajes enviados después de esta fecha",
|
||||
[nameof(BeforeDateLabel)] = "Antes (fecha)",
|
||||
[nameof(BeforeDateTooltip)] = "Solo incluir mensajes enviados antes de esta fecha",
|
||||
[nameof(AfterTimeLabel)] = "Después (hora)",
|
||||
[nameof(AfterTimeTooltip)] = "Solo incluir mensajes enviados después de esta hora",
|
||||
[nameof(BeforeTimeLabel)] = "Antes (hora)",
|
||||
[nameof(BeforeTimeTooltip)] = "Solo incluir mensajes enviados antes de esta hora",
|
||||
[nameof(PartitionLimitLabel)] = "Límite de partición",
|
||||
[nameof(PartitionLimitTooltip)] =
|
||||
"Dividir la salida en particiones, cada una limitada al número de mensajes especificado (p. ej. '100') o tamaño de archivo (p. ej. '10mb')",
|
||||
[nameof(MessageFilterLabel)] = "Filtro de mensajes",
|
||||
[nameof(MessageFilterTooltip)] =
|
||||
"Solo incluir mensajes que satisfagan este filtro (p. ej. 'from:foo#1234' o 'has:image'). Consulte la documentación para más información.",
|
||||
[nameof(FormatMarkdownLabel)] = "Formatear markdown",
|
||||
[nameof(FormatMarkdownTooltip)] =
|
||||
"Procesar markdown, menciones y otros tokens especiales",
|
||||
[nameof(DownloadAssetsLabel)] = "Descargar recursos",
|
||||
[nameof(DownloadAssetsTooltip)] =
|
||||
"Descargar los recursos referenciados por la exportación (avatares, archivos adjuntos, imágenes incrustadas, etc.)",
|
||||
[nameof(ReuseAssetsLabel)] = "Reutilizar recursos",
|
||||
[nameof(ReuseAssetsTooltip)] =
|
||||
"Reutilizar recursos previamente descargados para evitar solicitudes redundantes",
|
||||
[nameof(AssetsDirPathLabel)] = "Ruta del directorio de recursos",
|
||||
[nameof(AssetsDirPathTooltip)] =
|
||||
"Descargar recursos en este directorio. Si no se especifica, la ruta se derivará de la ruta de salida.",
|
||||
[nameof(AdvancedOptionsTooltip)] = "Alternar opciones avanzadas",
|
||||
[nameof(ExportButton)] = "EXPORTAR",
|
||||
// Common buttons
|
||||
[nameof(CloseButton)] = "CERRAR",
|
||||
[nameof(CancelButton)] = "CANCELAR",
|
||||
// Dialog messages
|
||||
[nameof(UkraineSupportTitle)] = "¡Gracias por apoyar a Ucrania!",
|
||||
[nameof(UkraineSupportMessage)] = """
|
||||
Mientras Rusia libra una guerra genocida contra mi país, estoy agradecido con todos los que continúan apoyando a Ucrania en nuestra lucha por la libertad.
|
||||
|
||||
Haga clic en MÁS INFORMACIÓN para encontrar formas de ayudar.
|
||||
""",
|
||||
[nameof(LearnMoreButton)] = "MÁS INFORMACIÓN",
|
||||
[nameof(UnstableBuildTitle)] = "Advertencia de versión inestable",
|
||||
[nameof(UnstableBuildMessage)] = """
|
||||
Está usando una versión de desarrollo de {0}. Estas versiones no han sido probadas exhaustivamente y pueden contener errores.
|
||||
|
||||
Las actualizaciones automáticas están desactivadas para las versiones de desarrollo.
|
||||
|
||||
Haga clic en VER VERSIONES si desea descargar una versión estable.
|
||||
""",
|
||||
[nameof(SeeReleasesButton)] = "VER VERSIONES",
|
||||
[nameof(UpdateDownloadingMessage)] = "Descargando actualización a {0} v{1}...",
|
||||
[nameof(UpdateReadyMessage)] =
|
||||
"La actualización se ha descargado y se instalará al salir",
|
||||
[nameof(UpdateInstallNowButton)] = "INSTALAR AHORA",
|
||||
[nameof(UpdateFailedMessage)] = "Error al realizar la actualización de la aplicación",
|
||||
[nameof(ErrorPullingGuildsTitle)] = "Error al cargar servidores",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Error al cargar canales",
|
||||
[nameof(ErrorExportingTitle)] = "Error al exportar canal(es)",
|
||||
[nameof(SuccessfulExportMessage)] = "{0} canal(es) exportado(s) con éxito",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, string> UkrainianLocalization =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
// Dashboard
|
||||
[nameof(PullGuildsTooltip)] = "Завантажити доступні сервери та канали (Enter)",
|
||||
[nameof(SettingsTooltip)] = "Налаштування",
|
||||
[nameof(LastMessageSentTooltip)] = "Останнє повідомлення:",
|
||||
[nameof(TokenWatermark)] = "Токен",
|
||||
// Token instructions (personal account)
|
||||
[nameof(TokenPersonalHeader)] = "Як отримати токен для персонального акаунту:",
|
||||
[nameof(TokenPersonalTosWarning)] =
|
||||
"* Автоматизація облікових записів технічно порушує Умови обслуговування — **на власний ризик**!",
|
||||
[nameof(TokenPersonalInstructions)] = """
|
||||
1. Відкрийте Discord у вашому веб-браузері та увійдіть
|
||||
2. Відкрийте будь-який сервер або канал особистих повідомлень
|
||||
3. Натисніть **Ctrl+Shift+I**, щоб відкрити інструменти розробника
|
||||
4. Перейдіть на вкладку **Network**
|
||||
5. Натисніть **Ctrl+R** для перезавантаження
|
||||
6. Перемикайтеся між каналами, щоб викликати мережеві запити
|
||||
7. Знайдіть запит, що починається з **messages**
|
||||
8. Виберіть вкладку **Headers** праворуч
|
||||
9. Прокрутіть до розділу **Request Headers**
|
||||
10. Скопіюйте значення заголовка **authorization**
|
||||
""",
|
||||
// Token instructions (bot)
|
||||
[nameof(TokenBotHeader)] = "Як отримати токен для бота:",
|
||||
[nameof(TokenBotInstructions)] = """
|
||||
Токен генерується під час створення бота. Якщо ви його втратили, згенеруйте новий:
|
||||
|
||||
1. Відкрийте Discord [портал розробника](https://discord.com/developers/applications)
|
||||
2. Відкрийте налаштування вашого застосунку
|
||||
3. Перейдіть до розділу **Bot** ліворуч
|
||||
4. В розділі **Token** натисніть **Reset Token**
|
||||
5. Натисніть **Yes, do it!** та підтвердьте
|
||||
* Інтеграції, що використовують попередній токен, перестануть працювати
|
||||
* Ваш бот повинен мати включений **Message Content Intent** для читання повідомлень
|
||||
""",
|
||||
[nameof(TokenHelpText)] =
|
||||
"Якщо у вас є запитання або проблеми, зверніться до [документації](https://github.com/Tyrrrz/DiscordChatExporter/tree/master/.docs)",
|
||||
// Settings
|
||||
[nameof(SettingsTitle)] = "Налаштування",
|
||||
[nameof(ThemeLabel)] = "Тема",
|
||||
[nameof(ThemeTooltip)] = "Бажана тема інтерфейсу",
|
||||
[nameof(LanguageLabel)] = "Мова",
|
||||
[nameof(LanguageTooltip)] = "Бажана мова інтерфейсу",
|
||||
[nameof(AutoUpdateLabel)] = "Авто-оновлення",
|
||||
[nameof(AutoUpdateTooltip)] = "Виконувати автоматичні оновлення при кожному запуску",
|
||||
[nameof(PersistTokenLabel)] = "Зберігати токен",
|
||||
[nameof(PersistTokenTooltip)] =
|
||||
"Зберігати останній використаний токен у файлі для збереження між сеансами",
|
||||
[nameof(RateLimitPreferenceLabel)] = "Ліміт запитів",
|
||||
[nameof(RateLimitPreferenceTooltip)] =
|
||||
"Чи дотримуватись рекомендованих лімітів запитів. Якщо вимкнено, будуть дотримуватись лише жорсткі ліміти (тобто відповіді 429).",
|
||||
[nameof(ShowThreadsLabel)] = "Показувати гілки",
|
||||
[nameof(ShowThreadsTooltip)] = "Які типи гілок показувати у списку каналів",
|
||||
[nameof(LocaleLabel)] = "Локаль",
|
||||
[nameof(LocaleTooltip)] = "Локаль для форматування дат та чисел",
|
||||
[nameof(NormalizeToUtcLabel)] = "Нормалізувати до UTC",
|
||||
[nameof(NormalizeToUtcTooltip)] = "Нормалізувати всі часові мітки до UTC+0",
|
||||
[nameof(ParallelLimitLabel)] = "Ліміт паралелізації",
|
||||
[nameof(ParallelLimitTooltip)] = "Скільки каналів може експортуватись одночасно",
|
||||
// Export Setup
|
||||
[nameof(ChannelsSelectedText)] = "каналів вибрано",
|
||||
[nameof(OutputPathLabel)] = "Шлях збереження",
|
||||
[nameof(OutputPathTooltip)] = """
|
||||
Шлях до файлу або директорії виводу.
|
||||
|
||||
Якщо вказано директорію, імена файлів генеруватимуться автоматично на основі назв каналів та параметрів експорту.
|
||||
|
||||
Шляхи до директорій повинні закінчуватись слешем для уникнення неоднозначності.
|
||||
|
||||
Доступні шаблонні токени:
|
||||
- **%g** — ID сервера
|
||||
- **%G** — назва сервера
|
||||
- **%t** — ID категорії
|
||||
- **%T** — назва категорії
|
||||
- **%c** — ID каналу
|
||||
- **%C** — назва каналу
|
||||
- **%p** — позиція каналу
|
||||
- **%P** — позиція категорії
|
||||
- **%a** — дата після
|
||||
- **%b** — дата до
|
||||
- **%d** — поточна дата
|
||||
""",
|
||||
[nameof(FormatLabel)] = "Формат",
|
||||
[nameof(FormatTooltip)] = "Формат експорту",
|
||||
[nameof(AfterDateLabel)] = "Після (дата)",
|
||||
[nameof(AfterDateTooltip)] = "Включати лише повідомлення, надіслані після цієї дати",
|
||||
[nameof(BeforeDateLabel)] = "До (дата)",
|
||||
[nameof(BeforeDateTooltip)] = "Включати лише повідомлення, надіслані до цієї дати",
|
||||
[nameof(AfterTimeLabel)] = "Після (час)",
|
||||
[nameof(AfterTimeTooltip)] = "Включати лише повідомлення, надіслані після цього часу",
|
||||
[nameof(BeforeTimeLabel)] = "До (час)",
|
||||
[nameof(BeforeTimeTooltip)] = "Включати лише повідомлення, надіслані до цього часу",
|
||||
[nameof(PartitionLimitLabel)] = "Розділяти експорт",
|
||||
[nameof(PartitionLimitTooltip)] =
|
||||
"Розділити вивід на частини, кожна обмежена вказаною кількістю повідомлень (напр. '100') або розміром файлу (напр. '10mb')",
|
||||
[nameof(MessageFilterLabel)] = "Фільтр повідомлень",
|
||||
[nameof(MessageFilterTooltip)] =
|
||||
"Включати лише повідомлення, що відповідають цьому фільтру (напр. 'from:foo#1234' або 'has:image'). Дивіться документацію для більш детальної інформації.",
|
||||
[nameof(FormatMarkdownLabel)] = "Форматувати markdown",
|
||||
[nameof(FormatMarkdownTooltip)] =
|
||||
"Обробляти markdown, згадки та інші спеціальні токени",
|
||||
[nameof(DownloadAssetsLabel)] = "Завантажувати ресурси",
|
||||
[nameof(DownloadAssetsTooltip)] =
|
||||
"Завантажувати ресурси, на які посилається експорт (аватари, вкладені файли, вбудовані зображення тощо)",
|
||||
[nameof(ReuseAssetsLabel)] = "Повторно використовувати ресурси",
|
||||
[nameof(ReuseAssetsTooltip)] =
|
||||
"Повторно використовувати раніше завантажені ресурси, щоб уникнути зайвих запитів",
|
||||
[nameof(AssetsDirPathLabel)] = "Шлях до директорії ресурсів",
|
||||
[nameof(AssetsDirPathTooltip)] =
|
||||
"Завантажувати ресурси до цієї директорії. Якщо не вказано, шлях до директорії ресурсів буде визначено з шляху збереження.",
|
||||
[nameof(AdvancedOptionsTooltip)] = "Перемкнути розширені параметри",
|
||||
[nameof(ExportButton)] = "ЕКСПОРТУВАТИ",
|
||||
// Common buttons
|
||||
[nameof(CloseButton)] = "ЗАКРИТИ",
|
||||
[nameof(CancelButton)] = "СКАСУВАТИ",
|
||||
// Dialog messages
|
||||
[nameof(UkraineSupportTitle)] = "Дякуємо за підтримку України!",
|
||||
[nameof(UkraineSupportMessage)] = """
|
||||
Поки Росія веде геноцидну війну проти моєї країни, я вдячний кожному, хто продовжує підтримувати Україну у нашій боротьбі за свободу.
|
||||
|
||||
Натисніть ДІЗНАТИСЬ БІЛЬШЕ, щоб знайти способи допомогти.
|
||||
""",
|
||||
[nameof(LearnMoreButton)] = "ДІЗНАТИСЬ БІЛЬШЕ",
|
||||
[nameof(UnstableBuildTitle)] = "Попередження про нестабільну збірку",
|
||||
[nameof(UnstableBuildMessage)] = """
|
||||
Ви використовуєте збірку розробки {0}. Ці збірки не пройшли ретельного тестування та можуть містити помилки.
|
||||
|
||||
Авто-оновлення вимкнено для збірок розробки.
|
||||
|
||||
Натисніть ПЕРЕГЛЯНУТИ РЕЛІЗИ, щоб завантажити стабільний реліз.
|
||||
""",
|
||||
[nameof(SeeReleasesButton)] = "ПЕРЕГЛЯНУТИ РЕЛІЗИ",
|
||||
[nameof(UpdateDownloadingMessage)] = "Завантаження оновлення {0} v{1}...",
|
||||
[nameof(UpdateReadyMessage)] = "Оновлення завантажено та буде встановлено після виходу",
|
||||
[nameof(UpdateInstallNowButton)] = "ВСТАНОВИТИ ЗАРАЗ",
|
||||
[nameof(UpdateFailedMessage)] = "Не вдалося виконати оновлення програми",
|
||||
[nameof(ErrorPullingGuildsTitle)] = "Помилка завантаження серверів",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Помилка завантаження каналів",
|
||||
[nameof(ErrorExportingTitle)] = "Помилка експорту каналу(-ів)",
|
||||
[nameof(SuccessfulExportMessage)] = "Успішно експортовано {0} канал(-ів)",
|
||||
};
|
||||
}
|
||||
170
DiscordChatExporter.Gui/Localization/LocalizationManager.cs
Normal file
170
DiscordChatExporter.Gui/Localization/LocalizationManager.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.Utils;
|
||||
using DiscordChatExporter.Gui.Utils.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Localization;
|
||||
|
||||
public partial class LocalizationManager : ObservableObject, IDisposable
|
||||
{
|
||||
private readonly DisposableCollector _eventRoot = new();
|
||||
|
||||
public LocalizationManager(SettingsService settingsService)
|
||||
{
|
||||
_eventRoot.Add(
|
||||
settingsService.WatchProperty(
|
||||
o => o.Language,
|
||||
() => Language = settingsService.Language,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
_eventRoot.Add(
|
||||
this.WatchProperty(
|
||||
o => o.Language,
|
||||
() =>
|
||||
{
|
||||
foreach (var propertyName in EnglishLocalization.Keys)
|
||||
OnPropertyChanged(propertyName);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Language Language { get; set; } = Language.System;
|
||||
|
||||
private string Get([CallerMemberName] string? key = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
return string.Empty;
|
||||
|
||||
var localization = Language switch
|
||||
{
|
||||
Language.System =>
|
||||
CultureInfo.CurrentUICulture.ThreeLetterISOLanguageName.ToLowerInvariant() switch
|
||||
{
|
||||
"ukr" => UkrainianLocalization,
|
||||
"deu" => GermanLocalization,
|
||||
"fra" => FrenchLocalization,
|
||||
"spa" => SpanishLocalization,
|
||||
_ => EnglishLocalization,
|
||||
},
|
||||
Language.Ukrainian => UkrainianLocalization,
|
||||
Language.German => GermanLocalization,
|
||||
Language.French => FrenchLocalization,
|
||||
Language.Spanish => SpanishLocalization,
|
||||
_ => EnglishLocalization,
|
||||
};
|
||||
|
||||
if (
|
||||
localization.TryGetValue(key, out var value)
|
||||
// English is used as a fallback
|
||||
|| EnglishLocalization.TryGetValue(key, out value)
|
||||
)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return $"Missing localization for '{key}'";
|
||||
}
|
||||
|
||||
public void Dispose() => _eventRoot.Dispose();
|
||||
}
|
||||
|
||||
public partial class LocalizationManager
|
||||
{
|
||||
// ---- Dashboard ----
|
||||
|
||||
public string PullGuildsTooltip => Get();
|
||||
public string SettingsTooltip => Get();
|
||||
public string LastMessageSentTooltip => Get();
|
||||
public string TokenWatermark => Get();
|
||||
|
||||
// Token instructions (personal account)
|
||||
public string TokenPersonalHeader => Get();
|
||||
public string TokenPersonalTosWarning => Get();
|
||||
public string TokenPersonalInstructions => Get();
|
||||
|
||||
// Token instructions (bot)
|
||||
public string TokenBotHeader => Get();
|
||||
public string TokenBotInstructions => Get();
|
||||
public string TokenHelpText => Get();
|
||||
|
||||
// ---- Settings ----
|
||||
|
||||
public string SettingsTitle => Get();
|
||||
public string ThemeLabel => Get();
|
||||
public string ThemeTooltip => Get();
|
||||
public string LanguageLabel => Get();
|
||||
public string LanguageTooltip => Get();
|
||||
public string AutoUpdateLabel => Get();
|
||||
public string AutoUpdateTooltip => Get();
|
||||
public string PersistTokenLabel => Get();
|
||||
public string PersistTokenTooltip => Get();
|
||||
public string RateLimitPreferenceLabel => Get();
|
||||
public string RateLimitPreferenceTooltip => Get();
|
||||
public string ShowThreadsLabel => Get();
|
||||
public string ShowThreadsTooltip => Get();
|
||||
public string LocaleLabel => Get();
|
||||
public string LocaleTooltip => Get();
|
||||
public string NormalizeToUtcLabel => Get();
|
||||
public string NormalizeToUtcTooltip => Get();
|
||||
public string ParallelLimitLabel => Get();
|
||||
public string ParallelLimitTooltip => Get();
|
||||
|
||||
// ---- Export Setup ----
|
||||
|
||||
public string ChannelsSelectedText => Get();
|
||||
public string OutputPathLabel => Get();
|
||||
public string OutputPathTooltip => Get();
|
||||
public string FormatLabel => Get();
|
||||
public string FormatTooltip => Get();
|
||||
public string AfterDateLabel => Get();
|
||||
public string AfterDateTooltip => Get();
|
||||
public string BeforeDateLabel => Get();
|
||||
public string BeforeDateTooltip => Get();
|
||||
public string AfterTimeLabel => Get();
|
||||
public string AfterTimeTooltip => Get();
|
||||
public string BeforeTimeLabel => Get();
|
||||
public string BeforeTimeTooltip => Get();
|
||||
public string PartitionLimitLabel => Get();
|
||||
public string PartitionLimitTooltip => Get();
|
||||
public string MessageFilterLabel => Get();
|
||||
public string MessageFilterTooltip => Get();
|
||||
public string FormatMarkdownLabel => Get();
|
||||
public string FormatMarkdownTooltip => Get();
|
||||
public string DownloadAssetsLabel => Get();
|
||||
public string DownloadAssetsTooltip => Get();
|
||||
public string ReuseAssetsLabel => Get();
|
||||
public string ReuseAssetsTooltip => Get();
|
||||
public string AssetsDirPathLabel => Get();
|
||||
public string AssetsDirPathTooltip => Get();
|
||||
public string AdvancedOptionsTooltip => Get();
|
||||
public string ExportButton => Get();
|
||||
|
||||
// ---- Common buttons ----
|
||||
|
||||
public string CloseButton => Get();
|
||||
public string CancelButton => Get();
|
||||
|
||||
// ---- Dialog messages ----
|
||||
|
||||
public string UkraineSupportTitle => Get();
|
||||
public string UkraineSupportMessage => Get();
|
||||
public string LearnMoreButton => Get();
|
||||
public string UnstableBuildTitle => Get();
|
||||
public string UnstableBuildMessage => Get();
|
||||
public string SeeReleasesButton => Get();
|
||||
public string UpdateDownloadingMessage => Get();
|
||||
public string UpdateReadyMessage => Get();
|
||||
public string UpdateInstallNowButton => Get();
|
||||
public string UpdateFailedMessage => Get();
|
||||
public string ErrorPullingGuildsTitle => Get();
|
||||
public string ErrorPullingChannelsTitle => Get();
|
||||
public string ErrorExportingTitle => Get();
|
||||
public string SuccessfulExportMessage => Get();
|
||||
}
|
||||
Reference in New Issue
Block a user