mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-06-14 11:26:33 +00:00
Implement localization in DiscordChatExporter following YoutubeDownloader pattern
Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
This commit is contained in:
@@ -5,6 +5,7 @@ using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.Utils;
|
||||
using DiscordChatExporter.Gui.Utils.Extensions;
|
||||
@@ -39,6 +40,9 @@ public class App : Application, IDisposable
|
||||
services.AddSingleton<SettingsService>();
|
||||
services.AddSingleton<UpdateService>();
|
||||
|
||||
// Localization
|
||||
services.AddSingleton<LocalizationManager>();
|
||||
|
||||
// View models
|
||||
services.AddTransient<MainViewModel>();
|
||||
services.AddTransient<DashboardViewModel>();
|
||||
|
||||
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,99 @@
|
||||
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:",
|
||||
// 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(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(ErrorPullingServersTitle)] = "Error pulling servers",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Error pulling channels",
|
||||
[nameof(ErrorExportingTitle)] = "Error exporting channel(s)",
|
||||
[nameof(SuccessfulExportMessage)] = "Successfully exported {0} channel(s)",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
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é :",
|
||||
// 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(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(ErrorPullingServersTitle)] = "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,105 @@
|
||||
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:",
|
||||
// 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(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(ErrorPullingServersTitle)] = "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,99 @@
|
||||
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:",
|
||||
// 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(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(ErrorPullingServersTitle)] = "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,98 @@
|
||||
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)] = "Останнє повідомлення:",
|
||||
// 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(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(ErrorPullingServersTitle)] = "Помилка завантаження серверів",
|
||||
[nameof(ErrorPullingChannelsTitle)] = "Помилка завантаження каналів",
|
||||
[nameof(ErrorExportingTitle)] = "Помилка експорту каналу(-ів)",
|
||||
[nameof(SuccessfulExportMessage)] = "Успішно експортовано {0} канал(-ів)",
|
||||
};
|
||||
}
|
||||
158
DiscordChatExporter.Gui/Localization/LocalizationManager.cs
Normal file
158
DiscordChatExporter.Gui/Localization/LocalizationManager.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
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();
|
||||
|
||||
// ---- 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 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 ErrorPullingServersTitle => Get();
|
||||
public string ErrorPullingChannelsTitle => Get();
|
||||
public string ErrorExportingTitle => Get();
|
||||
public string SuccessfulExportMessage => Get();
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DiscordChatExporter.Core.Discord;
|
||||
using DiscordChatExporter.Core.Exporting;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Models;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Services;
|
||||
@@ -23,6 +24,9 @@ public partial class SettingsService()
|
||||
[ObservableProperty]
|
||||
public partial ThemeVariant Theme { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Language Language { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsAutoUpdateEnabled { get; set; } = true;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ using DiscordChatExporter.Core.Exceptions;
|
||||
using DiscordChatExporter.Core.Exporting;
|
||||
using DiscordChatExporter.Core.Utils.Extensions;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Models;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.Utils;
|
||||
@@ -38,13 +39,15 @@ public partial class DashboardViewModel : ViewModelBase
|
||||
ViewModelManager viewModelManager,
|
||||
DialogManager dialogManager,
|
||||
SnackbarManager snackbarManager,
|
||||
SettingsService settingsService
|
||||
SettingsService settingsService,
|
||||
LocalizationManager localizationManager
|
||||
)
|
||||
{
|
||||
_viewModelManager = viewModelManager;
|
||||
_dialogManager = dialogManager;
|
||||
_snackbarManager = snackbarManager;
|
||||
_settingsService = settingsService;
|
||||
LocalizationManager = localizationManager;
|
||||
|
||||
_progressMuxer = Progress.CreateMuxer().WithAutoReset();
|
||||
|
||||
@@ -70,6 +73,8 @@ public partial class DashboardViewModel : ViewModelBase
|
||||
[NotifyCanExecuteChangedFor(nameof(ExportCommand))]
|
||||
public partial bool IsBusy { get; set; }
|
||||
|
||||
public LocalizationManager LocalizationManager { get; }
|
||||
|
||||
public ProgressContainer<Percentage> Progress { get; } = new();
|
||||
|
||||
public bool IsProgressIndeterminate => IsBusy && Progress.Current.Fraction is <= 0 or >= 1;
|
||||
@@ -141,7 +146,7 @@ public partial class DashboardViewModel : ViewModelBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
var dialog = _viewModelManager.CreateMessageBoxViewModel(
|
||||
"Error pulling servers",
|
||||
LocalizationManager.ErrorPullingServersTitle,
|
||||
ex.ToString()
|
||||
);
|
||||
|
||||
@@ -208,7 +213,7 @@ public partial class DashboardViewModel : ViewModelBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
var dialog = _viewModelManager.CreateMessageBoxViewModel(
|
||||
"Error pulling channels",
|
||||
LocalizationManager.ErrorPullingChannelsTitle,
|
||||
ex.ToString()
|
||||
);
|
||||
|
||||
@@ -303,14 +308,17 @@ public partial class DashboardViewModel : ViewModelBase
|
||||
if (successfulExportCount > 0)
|
||||
{
|
||||
_snackbarManager.Notify(
|
||||
$"Successfully exported {successfulExportCount} channel(s)"
|
||||
string.Format(
|
||||
LocalizationManager.SuccessfulExportMessage,
|
||||
successfulExportCount
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var dialog = _viewModelManager.CreateMessageBoxViewModel(
|
||||
"Error exporting channel(s)",
|
||||
LocalizationManager.ErrorExportingTitle,
|
||||
ex.ToString()
|
||||
);
|
||||
|
||||
|
||||
@@ -12,15 +12,19 @@ using DiscordChatExporter.Core.Exporting.Filtering;
|
||||
using DiscordChatExporter.Core.Exporting.Partitioning;
|
||||
using DiscordChatExporter.Core.Utils.Extensions;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Dialogs;
|
||||
|
||||
public partial class ExportSetupViewModel(
|
||||
DialogManager dialogManager,
|
||||
SettingsService settingsService
|
||||
SettingsService settingsService,
|
||||
LocalizationManager localizationManager
|
||||
) : DialogViewModelBase
|
||||
{
|
||||
public LocalizationManager LocalizationManager { get; } = localizationManager;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Guild? Guild { get; set; }
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using DiscordChatExporter.Core.Discord;
|
||||
using DiscordChatExporter.Core.Utils.Extensions;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Models;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.Utils;
|
||||
@@ -16,13 +17,19 @@ public class SettingsViewModel : DialogViewModelBase
|
||||
|
||||
private readonly DisposableCollector _eventRoot = new();
|
||||
|
||||
public SettingsViewModel(SettingsService settingsService)
|
||||
public SettingsViewModel(
|
||||
SettingsService settingsService,
|
||||
LocalizationManager localizationManager
|
||||
)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
LocalizationManager = localizationManager;
|
||||
|
||||
_eventRoot.Add(_settingsService.WatchAllProperties(OnAllPropertiesChanged));
|
||||
}
|
||||
|
||||
public LocalizationManager LocalizationManager { get; }
|
||||
|
||||
public IReadOnlyList<ThemeVariant> AvailableThemes { get; } = Enum.GetValues<ThemeVariant>();
|
||||
|
||||
public ThemeVariant Theme
|
||||
@@ -31,6 +38,14 @@ public class SettingsViewModel : DialogViewModelBase
|
||||
set => _settingsService.Theme = value;
|
||||
}
|
||||
|
||||
public IReadOnlyList<Language> AvailableLanguages { get; } = Enum.GetValues<Language>();
|
||||
|
||||
public Language Language
|
||||
{
|
||||
get => _settingsService.Language;
|
||||
set => _settingsService.Language = value;
|
||||
}
|
||||
|
||||
public bool IsAutoUpdateEnabled
|
||||
{
|
||||
get => _settingsService.IsAutoUpdateEnabled;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DiscordChatExporter.Gui.Framework;
|
||||
using DiscordChatExporter.Gui.Localization;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.Utils.Extensions;
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
@@ -15,7 +16,8 @@ public partial class MainViewModel(
|
||||
DialogManager dialogManager,
|
||||
SnackbarManager snackbarManager,
|
||||
SettingsService settingsService,
|
||||
UpdateService updateService
|
||||
UpdateService updateService,
|
||||
LocalizationManager localizationManager
|
||||
) : ViewModelBase
|
||||
{
|
||||
public string Title { get; } = $"{Program.Name} v{Program.VersionString}";
|
||||
@@ -28,14 +30,10 @@ public partial class MainViewModel(
|
||||
return;
|
||||
|
||||
var dialog = viewModelManager.CreateMessageBoxViewModel(
|
||||
"Thank you for supporting Ukraine!",
|
||||
"""
|
||||
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.
|
||||
""",
|
||||
"LEARN MORE",
|
||||
"CLOSE"
|
||||
localizationManager.UkraineSupportTitle,
|
||||
localizationManager.UkraineSupportMessage,
|
||||
localizationManager.LearnMoreButton,
|
||||
localizationManager.CloseButton
|
||||
);
|
||||
|
||||
// Disable this message in the future
|
||||
@@ -56,16 +54,10 @@ public partial class MainViewModel(
|
||||
return;
|
||||
|
||||
var dialog = viewModelManager.CreateMessageBoxViewModel(
|
||||
"Unstable build warning",
|
||||
$"""
|
||||
You're using a development build of {Program.Name}. 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.
|
||||
""",
|
||||
"SEE RELEASES",
|
||||
"CLOSE"
|
||||
localizationManager.UnstableBuildTitle,
|
||||
string.Format(localizationManager.UnstableBuildMessage, Program.Name),
|
||||
localizationManager.SeeReleasesButton,
|
||||
localizationManager.CloseButton
|
||||
);
|
||||
|
||||
if (await dialogManager.ShowDialogAsync(dialog) == true)
|
||||
@@ -80,12 +72,18 @@ public partial class MainViewModel(
|
||||
if (updateVersion is null)
|
||||
return;
|
||||
|
||||
snackbarManager.Notify($"Downloading update to {Program.Name} v{updateVersion}...");
|
||||
snackbarManager.Notify(
|
||||
string.Format(
|
||||
localizationManager.UpdateDownloadingMessage,
|
||||
Program.Name,
|
||||
updateVersion
|
||||
)
|
||||
);
|
||||
await updateService.PrepareUpdateAsync(updateVersion);
|
||||
|
||||
snackbarManager.Notify(
|
||||
"Update has been downloaded and will be installed when you exit",
|
||||
"INSTALL NOW",
|
||||
localizationManager.UpdateReadyMessage,
|
||||
localizationManager.UpdateInstallNowButton,
|
||||
() =>
|
||||
{
|
||||
updateService.FinalizeUpdate(true);
|
||||
@@ -98,7 +96,7 @@ public partial class MainViewModel(
|
||||
catch
|
||||
{
|
||||
// Failure to update shouldn't crash the application
|
||||
snackbarManager.Notify("Failed to perform application update");
|
||||
snackbarManager.Notify(localizationManager.UpdateFailedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
Command="{Binding PullGuildsCommand}"
|
||||
IsDefault="True"
|
||||
Theme="{DynamicResource MaterialFlatButton}"
|
||||
ToolTip.Tip="Pull available servers and channels (Enter)">
|
||||
ToolTip.Tip="{Binding LocalizationManager.PullGuildsTooltip}">
|
||||
<materialIcons:MaterialIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
@@ -64,7 +64,7 @@
|
||||
Command="{Binding ShowSettingsCommand}"
|
||||
Foreground="{DynamicResource MaterialDarkForegroundBrush}"
|
||||
Theme="{DynamicResource MaterialFlatButton}"
|
||||
ToolTip.Tip="Settings">
|
||||
ToolTip.Tip="{Binding LocalizationManager.SettingsTooltip}">
|
||||
<materialIcons:MaterialIcon
|
||||
Width="24"
|
||||
Height="24"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
IsVisible="{Binding !IsSingleChannel}"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<Run Text="{Binding Channels.Count, FallbackValue=0, Mode=OneWay}" />
|
||||
<Run Text="channels selected" />
|
||||
<Run Text="{Binding LocalizationManager.ChannelsSelectedText}" />
|
||||
</TextBlock>
|
||||
|
||||
<!-- Category and channel name (for single channel) -->
|
||||
@@ -69,7 +69,7 @@
|
||||
<!-- Output path -->
|
||||
<TextBox
|
||||
Margin="16,8"
|
||||
materialAssists:TextFieldAssist.Label="Output path"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.OutputPathLabel}"
|
||||
Text="{Binding OutputPath}"
|
||||
Theme="{DynamicResource FilledTextBox}">
|
||||
<ToolTip.Tip>
|
||||
@@ -146,11 +146,11 @@
|
||||
<!-- Format -->
|
||||
<ComboBox
|
||||
Margin="16,8"
|
||||
materialAssists:ComboBoxAssist.Label="Format"
|
||||
materialAssists:ComboBoxAssist.Label="{Binding LocalizationManager.FormatLabel}"
|
||||
ItemsSource="{Binding AvailableFormats}"
|
||||
SelectedItem="{Binding SelectedFormat}"
|
||||
Theme="{DynamicResource MaterialFilledComboBox}"
|
||||
ToolTip.Tip="Export format">
|
||||
ToolTip.Tip="{Binding LocalizationManager.FormatTooltip}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={x:Static converters:ExportFormatToStringConverter.Instance}}" />
|
||||
@@ -166,9 +166,9 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="16,8,8,8"
|
||||
materialAssists:TextFieldAssist.Label="After (date)"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.AfterDateLabel}"
|
||||
SelectedDate="{Binding AfterDate}"
|
||||
ToolTip.Tip="Only include messages sent after this date">
|
||||
ToolTip.Tip="{Binding LocalizationManager.AfterDateTooltip}">
|
||||
<DatePicker.Styles>
|
||||
<Style Selector="DatePicker">
|
||||
<Style Selector="^ /template/ TextBox#DisplayTextBox">
|
||||
@@ -181,9 +181,9 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="8,8,16,8"
|
||||
materialAssists:TextFieldAssist.Label="Before (date)"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.BeforeDateLabel}"
|
||||
SelectedDate="{Binding BeforeDate}"
|
||||
ToolTip.Tip="Only include messages sent before this date">
|
||||
ToolTip.Tip="{Binding LocalizationManager.BeforeDateTooltip}">
|
||||
<DatePicker.Styles>
|
||||
<Style Selector="DatePicker">
|
||||
<Style Selector="^ /template/ TextBox#DisplayTextBox">
|
||||
@@ -198,11 +198,11 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="16,8,8,8"
|
||||
materialAssists:TextFieldAssist.Label="After (time)"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.AfterTimeLabel}"
|
||||
ClockIdentifier="{x:Static utils:Internationalization.AvaloniaClockIdentifier}"
|
||||
IsEnabled="{Binding IsAfterDateSet}"
|
||||
SelectedTime="{Binding AfterTime}"
|
||||
ToolTip.Tip="Only include messages sent after this time">
|
||||
ToolTip.Tip="{Binding LocalizationManager.AfterTimeTooltip}">
|
||||
<TimePicker.Styles>
|
||||
<Style Selector="TimePicker">
|
||||
<Style Selector="^ /template/ TextBox#PART_DisplayTextBox">
|
||||
@@ -215,11 +215,11 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="8,8,16,8"
|
||||
materialAssists:TextFieldAssist.Label="Before (time)"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.BeforeTimeLabel}"
|
||||
ClockIdentifier="{x:Static utils:Internationalization.AvaloniaClockIdentifier}"
|
||||
IsEnabled="{Binding IsBeforeDateSet}"
|
||||
SelectedTime="{Binding BeforeTime}"
|
||||
ToolTip.Tip="Only include messages sent before this time">
|
||||
ToolTip.Tip="{Binding LocalizationManager.BeforeTimeTooltip}">
|
||||
<TimePicker.Styles>
|
||||
<Style Selector="TimePicker">
|
||||
<Style Selector="^ /template/ TextBox#PART_DisplayTextBox">
|
||||
@@ -233,25 +233,25 @@
|
||||
<!-- Partitioning -->
|
||||
<TextBox
|
||||
Margin="16,8"
|
||||
materialAssists:TextFieldAssist.Label="Partition limit"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.PartitionLimitLabel}"
|
||||
Text="{Binding PartitionLimitValue}"
|
||||
Theme="{DynamicResource FilledTextBox}"
|
||||
ToolTip.Tip="Split the output into partitions, each limited to the specified number of messages (e.g. '100') or file size (e.g. '10mb')" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.PartitionLimitTooltip}" />
|
||||
|
||||
<!-- Filtering -->
|
||||
<TextBox
|
||||
Margin="16,8"
|
||||
materialAssists:TextFieldAssist.Label="Message filter"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.MessageFilterLabel}"
|
||||
Text="{Binding MessageFilterValue}"
|
||||
Theme="{DynamicResource FilledTextBox}"
|
||||
ToolTip.Tip="Only include messages that satisfy this filter (e.g. 'from:foo#1234' or 'has:image'). See the documentation for more info." />
|
||||
ToolTip.Tip="{Binding LocalizationManager.MessageFilterTooltip}" />
|
||||
|
||||
<!-- Markdown formatting -->
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Process markdown, mentions, and other special tokens">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Format markdown" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.FormatMarkdownTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.FormatMarkdownLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding ShouldFormatMarkdown}" />
|
||||
</DockPanel>
|
||||
|
||||
@@ -259,8 +259,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Download assets referenced by the export (user avatars, attached files, embedded images, etc.)">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Download assets" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.DownloadAssetsTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.DownloadAssetsLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding ShouldDownloadAssets}" />
|
||||
</DockPanel>
|
||||
|
||||
@@ -269,19 +269,19 @@
|
||||
Margin="16,8"
|
||||
IsEnabled="{Binding ShouldDownloadAssets}"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Reuse previously downloaded assets to avoid redundant requests">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Reuse assets" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.ReuseAssetsTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.ReuseAssetsLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding ShouldReuseAssets}" />
|
||||
</DockPanel>
|
||||
|
||||
<!-- Assets path -->
|
||||
<TextBox
|
||||
Margin="16,8"
|
||||
materialAssists:TextFieldAssist.Label="Assets directory path"
|
||||
materialAssists:TextFieldAssist.Label="{Binding LocalizationManager.AssetsDirPathLabel}"
|
||||
IsEnabled="{Binding ShouldDownloadAssets}"
|
||||
Text="{Binding AssetsDirPath}"
|
||||
Theme="{DynamicResource FilledTextBox}"
|
||||
ToolTip.Tip="Download assets to this directory. If not specified, the asset directory path will be derived from the output path.">
|
||||
ToolTip.Tip="{Binding LocalizationManager.AssetsDirPathTooltip}">
|
||||
<TextBox.InnerRightContent>
|
||||
<Button
|
||||
Margin="8,8,8,6"
|
||||
@@ -310,7 +310,7 @@
|
||||
Grid.Column="0"
|
||||
IsChecked="{Binding IsAdvancedSectionDisplayed}"
|
||||
Theme="{DynamicResource MaterialOutlineButton}"
|
||||
ToolTip.Tip="Toggle advanced options">
|
||||
ToolTip.Tip="{Binding LocalizationManager.AdvancedOptionsTooltip}">
|
||||
<Button.Styles>
|
||||
<Style Selector="ToggleButton">
|
||||
<Setter Property="Content" Value="MORE" />
|
||||
@@ -325,14 +325,14 @@
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Command="{Binding ConfirmCommand}"
|
||||
Content="EXPORT"
|
||||
Content="{Binding LocalizationManager.ExportButton}"
|
||||
IsDefault="True"
|
||||
Theme="{DynamicResource MaterialOutlineButton}" />
|
||||
<Button
|
||||
Grid.Column="3"
|
||||
Margin="16,0,0,0"
|
||||
Command="{Binding CloseCommand}"
|
||||
Content="CANCEL"
|
||||
Content="{Binding LocalizationManager.CancelButton}"
|
||||
IsCancel="True"
|
||||
Theme="{DynamicResource MaterialOutlineButton}" />
|
||||
</Grid>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
Margin="16"
|
||||
FontSize="19"
|
||||
FontWeight="Light"
|
||||
Text="Settings" />
|
||||
Text="{Binding LocalizationManager.SettingsTitle}" />
|
||||
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
@@ -25,8 +25,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Preferred user interface theme">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Theme" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.ThemeTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.ThemeLabel}" />
|
||||
<ComboBox
|
||||
Width="150"
|
||||
DockPanel.Dock="Right"
|
||||
@@ -34,14 +34,27 @@
|
||||
SelectedItem="{Binding Theme}" />
|
||||
</DockPanel>
|
||||
|
||||
<!-- Language -->
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="{Binding LocalizationManager.LanguageTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.LanguageLabel}" />
|
||||
<ComboBox
|
||||
Width="150"
|
||||
DockPanel.Dock="Right"
|
||||
ItemsSource="{Binding AvailableLanguages}"
|
||||
SelectedItem="{Binding Language}" />
|
||||
</DockPanel>
|
||||
|
||||
<!-- Auto-updates -->
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
IsVisible="{OnPlatform False,
|
||||
Windows=True}"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Perform automatic updates on every launch">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Auto-update" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.AutoUpdateTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.AutoUpdateLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding IsAutoUpdateEnabled}" />
|
||||
</DockPanel>
|
||||
|
||||
@@ -49,8 +62,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Save the last used token to a file so that it can be persisted between sessions">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Persist token" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.PersistTokenTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.PersistTokenLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding IsTokenPersisted}" />
|
||||
</DockPanel>
|
||||
|
||||
@@ -58,8 +71,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Whether to respect advisory rate limits. If disabled, only hard rate limits (i.e. 429 responses) will be respected.">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Rate limit preference" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.RateLimitPreferenceTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.RateLimitPreferenceLabel}" />
|
||||
<ComboBox
|
||||
Width="150"
|
||||
DockPanel.Dock="Right"
|
||||
@@ -77,8 +90,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Which types of threads to show in the channel list">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Show threads" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.ShowThreadsTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.ShowThreadsLabel}" />
|
||||
<ComboBox
|
||||
Width="150"
|
||||
DockPanel.Dock="Right"
|
||||
@@ -90,8 +103,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Locale to use when formatting dates and numbers">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Locale" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.LocaleTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.LocaleLabel}" />
|
||||
<ComboBox
|
||||
Width="150"
|
||||
DockPanel.Dock="Right"
|
||||
@@ -109,8 +122,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="Normalize all timestamps to UTC+0">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Normalize to UTC" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.NormalizeToUtcTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.NormalizeToUtcLabel}" />
|
||||
<ToggleSwitch DockPanel.Dock="Right" IsChecked="{Binding IsUtcNormalizationEnabled}" />
|
||||
</DockPanel>
|
||||
|
||||
@@ -118,8 +131,8 @@
|
||||
<DockPanel
|
||||
Margin="16,8"
|
||||
LastChildFill="False"
|
||||
ToolTip.Tip="How many channels can be exported at the same time">
|
||||
<TextBlock DockPanel.Dock="Left" Text="Parallel limit" />
|
||||
ToolTip.Tip="{Binding LocalizationManager.ParallelLimitTooltip}">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding LocalizationManager.ParallelLimitLabel}" />
|
||||
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
|
||||
<TextBlock Margin="10,0" Text="{Binding ParallelLimit}" />
|
||||
<Slider
|
||||
@@ -141,7 +154,7 @@
|
||||
Margin="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{Binding CloseCommand}"
|
||||
Content="CLOSE"
|
||||
Content="{Binding LocalizationManager.CloseButton}"
|
||||
IsCancel="True"
|
||||
IsDefault="True"
|
||||
Theme="{DynamicResource MaterialOutlineButton}" />
|
||||
|
||||
Reference in New Issue
Block a user