Replace the date format option with a locale option (#1130)

This commit is contained in:
Oleksii Holub
2023-09-07 14:34:08 +03:00
committed by GitHub
parent 53b11d6c49
commit 59344cedbe
22 changed files with 288 additions and 273 deletions

View File

@@ -0,0 +1,21 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace DiscordChatExporter.Gui.Converters;
[ValueConversion(typeof(string), typeof(string))]
public class LocaleToDisplayNameConverter : IValueConverter
{
public static LocaleToDisplayNameConverter Instance { get; } = new();
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value is string locale ? CultureInfo.GetCultureInfo(locale).DisplayName : null;
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture
) => throw new NotSupportedException();
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.IO;
using Cogwheel;
using DiscordChatExporter.Core.Exporting;
@@ -19,7 +20,9 @@ public partial class SettingsService : SettingsBase
public ThreadInclusionMode ThreadInclusionMode { get; set; } = ThreadInclusionMode.None;
public string DateFormat { get; set; } = "MM/dd/yyyy h:mm tt";
public string Locale { get; set; } = CultureInfo.CurrentCulture.Name;
public bool IsUtcNormalizationEnabled { get; set; }
public int ParallelLimit { get; set; } = 1;

View File

@@ -78,6 +78,11 @@ public class DashboardViewModel : PropertyChangedBase
// due to the channels being asynchronously loaded.
AvailableChannels = null;
SelectedChannels = null;
// Pull channels for the selected guild
// (ideally this should be called inside `PullGuilds()`,
// but Stylet doesn't support async commands)
PullChannels();
}
);
}
@@ -88,14 +93,14 @@ public class DashboardViewModel : PropertyChangedBase
Token = _settingsService.LastToken;
}
public async ValueTask ShowSettingsAsync() =>
public async void ShowSettings() =>
await _dialogManager.ShowDialogAsync(_viewModelFactory.CreateSettingsViewModel());
public void ShowHelp() => ProcessEx.StartShellExecute(App.DocumentationUrl);
public bool CanPullGuildsAsync => !IsBusy && !string.IsNullOrWhiteSpace(Token);
public bool CanPullGuilds => !IsBusy && !string.IsNullOrWhiteSpace(Token);
public async ValueTask PullGuildsAsync()
public async void PullGuilds()
{
IsBusy = true;
var progress = _progressMuxer.CreateInput();
@@ -118,9 +123,6 @@ public class DashboardViewModel : PropertyChangedBase
AvailableGuilds = guilds;
SelectedGuild = guilds.FirstOrDefault();
// Pull channels for the selected guild
await PullChannelsAsync();
}
catch (DiscordChatExporterException ex) when (!ex.IsFatal)
{
@@ -142,10 +144,9 @@ public class DashboardViewModel : PropertyChangedBase
}
}
public bool CanPullChannelsAsync =>
!IsBusy && _discord is not null && SelectedGuild is not null;
public bool CanPullChannels => !IsBusy && _discord is not null && SelectedGuild is not null;
public async ValueTask PullChannelsAsync()
public async void PullChannels()
{
IsBusy = true;
var progress = _progressMuxer.CreateInput();
@@ -206,13 +207,13 @@ public class DashboardViewModel : PropertyChangedBase
}
}
public bool CanExportAsync =>
public bool CanExport =>
!IsBusy
&& _discord is not null
&& SelectedGuild is not null
&& SelectedChannels?.Any() is true;
public async ValueTask ExportAsync()
public async void Export()
{
IsBusy = true;
@@ -267,7 +268,8 @@ public class DashboardViewModel : PropertyChangedBase
dialog.ShouldFormatMarkdown,
dialog.ShouldDownloadAssets,
dialog.ShouldReuseAssets,
_settingsService.DateFormat
_settingsService.Locale,
_settingsService.IsUtcNormalizationEnabled
);
await exporter.ExportChannelAsync(request, progress, cancellationToken);

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using DiscordChatExporter.Gui.Models;
using DiscordChatExporter.Gui.Services;
using DiscordChatExporter.Gui.ViewModels.Framework;
@@ -37,10 +39,52 @@ public class SettingsViewModel : DialogScreen
set => _settingsService.ThreadInclusionMode = value;
}
public string DateFormat
public IReadOnlyList<string> AvailableLocales { get; } = new[]
{
// Current locale
CultureInfo.CurrentCulture.Name,
// Locales supported by the Discord app
"da-DK",
"de-DE",
"en-GB",
"en-US",
"es-ES",
"fr-FR",
"hr-HR",
"it-IT",
"lt-LT",
"hu-HU",
"nl-NL",
"no-NO",
"pl-PL",
"pt-BR",
"ro-RO",
"fi-FI",
"sv-SE",
"vi-VN",
"tr-TR",
"cs-CZ",
"el-GR",
"bg-BG",
"ru-RU",
"uk-UA",
"th-TH",
"zh-CN",
"ja-JP",
"zh-TW",
"ko-KR"
}.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
public string Locale
{
get => _settingsService.DateFormat;
set => _settingsService.DateFormat = value;
get => _settingsService.Locale;
set => _settingsService.Locale = value;
}
public bool IsUtcNormalizationEnabled
{
get => _settingsService.IsUtcNormalizationEnabled;
set => _settingsService.IsUtcNormalizationEnabled = value;
}
public int ParallelLimit

View File

@@ -105,7 +105,7 @@
Grid.Column="2"
Margin="0,6,6,6"
Padding="4"
Command="{s:Action PullGuildsAsync}"
Command="{s:Action PullGuilds}"
IsDefault="True"
Style="{DynamicResource MaterialDesignFlatButton}"
ToolTip="Pull available guilds and channels (Enter)">
@@ -122,7 +122,7 @@
Grid.Column="1"
Margin="6"
Padding="4"
Command="{s:Action ShowSettingsAsync}"
Command="{s:Action ShowSettings}"
Foreground="{DynamicResource MaterialDesignDarkForeground}"
Style="{DynamicResource MaterialDesignFlatButton}"
ToolTip="Settings">
@@ -274,7 +274,7 @@
Margin="-8"
Background="Transparent"
Cursor="Hand"
MouseLeftButtonUp="{s:Action PullChannelsAsync}"
MouseLeftButtonUp="{s:Action PullChannels}"
ToolTip="{Binding Name}">
<!-- Guild icon placeholder -->
<Ellipse
@@ -350,7 +350,7 @@
<DataTemplate DataType="{x:Type data:Channel}">
<Grid Margin="-8" Background="Transparent">
<Grid.InputBindings>
<MouseBinding Command="{s:Action ExportAsync}" MouseAction="LeftDoubleClick" />
<MouseBinding Command="{s:Action Export}" MouseAction="LeftDoubleClick" />
</Grid.InputBindings>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -412,9 +412,9 @@
Margin="32,24"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Command="{s:Action ExportAsync}"
Command="{s:Action Export}"
Style="{DynamicResource MaterialDesignFloatingActionAccentButton}"
Visibility="{Binding CanExportAsync, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
Visibility="{Binding CanExport, Converter={x:Static s:BoolToVisibilityConverter.Instance}}">
<materialDesign:PackIcon
Width="32"
Height="32"

View File

@@ -2,6 +2,7 @@
x:Class="DiscordChatExporter.Gui.Views.Dialogs.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:DiscordChatExporter.Gui.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -93,27 +94,51 @@
DockPanel.Dock="Left"
Text="Show threads" />
<ComboBox
Width="150"
VerticalAlignment="Center"
DockPanel.Dock="Right"
ItemsSource="{Binding AvailableThreadInclusions}"
SelectedItem="{Binding ThreadInclusionMode}" />
</DockPanel>
<!-- Date format -->
<!-- Locale -->
<DockPanel
Margin="16,8"
Background="Transparent"
LastChildFill="False"
ToolTip="Format used when writing dates (uses .NET date formatting rules)">
ToolTip="Locale to use when formatting dates and numbers">
<TextBlock
VerticalAlignment="Center"
DockPanel.Dock="Left"
Text="Date format" />
<TextBox
Text="Locale" />
<ComboBox
Width="150"
VerticalAlignment="Center"
DockPanel.Dock="Right"
Text="{Binding DateFormat}" />
ItemsSource="{Binding AvailableLocales}"
SelectedItem="{Binding Locale}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static converters:LocaleToDisplayNameConverter.Instance}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DockPanel>
<!-- UTC normalization -->
<DockPanel
Margin="16,8"
Background="Transparent"
LastChildFill="False"
ToolTip="Normalize all timestamps to UTC+0">
<TextBlock
VerticalAlignment="Center"
DockPanel.Dock="Left"
Text="Normalize to UTC" />
<ToggleButton
VerticalAlignment="Center"
DockPanel.Dock="Right"
IsChecked="{Binding IsUtcNormalizationEnabled}" />
</DockPanel>
<!-- Parallel limit -->
@@ -139,9 +164,13 @@
<Slider
Width="150"
VerticalAlignment="Center"
IsSnapToTickEnabled="True"
LargeChange="1"
Maximum="10"
Minimum="1"
SmallChange="1"
Style="{DynamicResource MaterialDesignThinSlider}"
TickFrequency="1"
Value="{Binding ParallelLimit}" />
</StackPanel>
</DockPanel>