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:
Copilot
2026-02-24 20:49:32 +02:00
committed by GitHub
parent 18086aa209
commit 12d98e9ab0
20 changed files with 1346 additions and 311 deletions

View File

@@ -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;
@@ -102,9 +107,6 @@ public partial class DashboardViewModel : ViewModelBase
private async Task ShowSettingsAsync() =>
await _dialogManager.ShowDialogAsync(_viewModelManager.CreateSettingsViewModel());
[RelayCommand]
private void ShowHelp() => Process.StartShellExecute(Program.ProjectDocumentationUrl);
private bool CanPullGuilds() => !IsBusy && !string.IsNullOrWhiteSpace(Token);
[RelayCommand(CanExecute = nameof(CanPullGuilds))]
@@ -141,7 +143,7 @@ public partial class DashboardViewModel : ViewModelBase
catch (Exception ex)
{
var dialog = _viewModelManager.CreateMessageBoxViewModel(
"Error pulling servers",
LocalizationManager.ErrorPullingGuildsTitle,
ex.ToString()
);
@@ -208,7 +210,7 @@ public partial class DashboardViewModel : ViewModelBase
catch (Exception ex)
{
var dialog = _viewModelManager.CreateMessageBoxViewModel(
"Error pulling channels",
LocalizationManager.ErrorPullingChannelsTitle,
ex.ToString()
);
@@ -303,14 +305,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()
);
@@ -322,13 +327,6 @@ public partial class DashboardViewModel : ViewModelBase
}
}
[RelayCommand]
private void OpenDiscord() => Process.StartShellExecute("https://discord.com/app");
[RelayCommand]
private void OpenDiscordDeveloperPortal() =>
Process.StartShellExecute("https://discord.com/developers/applications");
protected override void Dispose(bool disposing)
{
if (disposing)

View File

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

View File

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

View File

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