Format stuff

pull/1312/head
Tyrrrz 4 weeks ago
parent e8192b2b53
commit 09e0b3f133

@ -56,7 +56,7 @@ public static class ExportWrapper
ExportFormat = format,
OutputPath = filePath,
Locale = "en-US",
IsUtcNormalizationEnabled = true
IsUtcNormalizationEnabled = true,
}.ExecuteAsync(console);
}

@ -30,7 +30,7 @@ public class DateRangeSpecs
ChannelIds = [ChannelIds.DateRangeTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
After = Snowflake.FromDate(after)
After = Snowflake.FromDate(after),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -50,7 +50,7 @@ public class DateRangeSpecs
new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero),
new DateTimeOffset(2021, 09, 08, 14, 26, 35, TimeSpan.Zero)
new DateTimeOffset(2021, 09, 08, 14, 26, 35, TimeSpan.Zero),
],
o =>
o.Using<DateTimeOffset>(ctx =>
@ -74,7 +74,7 @@ public class DateRangeSpecs
ChannelIds = [ChannelIds.DateRangeTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
Before = Snowflake.FromDate(before)
Before = Snowflake.FromDate(before),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -92,7 +92,7 @@ public class DateRangeSpecs
[
new DateTimeOffset(2021, 07, 19, 13, 34, 18, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 19, 15, 58, 48, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 19, 17, 23, 58, TimeSpan.Zero)
new DateTimeOffset(2021, 07, 19, 17, 23, 58, TimeSpan.Zero),
],
o =>
o.Using<DateTimeOffset>(ctx =>
@ -118,7 +118,7 @@ public class DateRangeSpecs
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
Before = Snowflake.FromDate(before),
After = Snowflake.FromDate(after)
After = Snowflake.FromDate(after),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -137,7 +137,7 @@ public class DateRangeSpecs
new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero),
new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero)
new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero),
],
o =>
o.Using<DateTimeOffset>(ctx =>

@ -29,7 +29,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("some text")
MessageFilter = MessageFilter.Parse("some text"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -54,7 +54,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("from:Tyrrrz")
MessageFilter = MessageFilter.Parse("from:Tyrrrz"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -79,7 +79,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("has:image")
MessageFilter = MessageFilter.Parse("has:image"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -104,7 +104,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("has:pin")
MessageFilter = MessageFilter.Parse("has:pin"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -129,7 +129,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("has:invite")
MessageFilter = MessageFilter.Parse("has:invite"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -154,7 +154,7 @@ public class FilterSpecs
ChannelIds = [ChannelIds.FilterTestCases],
ExportFormat = ExportFormat.Json,
OutputPath = file.Path,
MessageFilter = MessageFilter.Parse("mentions:Tyrrrz")
MessageFilter = MessageFilter.Parse("mentions:Tyrrrz"),
}.ExecuteAsync(new FakeConsole());
// Assert

@ -28,7 +28,7 @@ public class HtmlGroupingSpecs
Token = Secrets.DiscordToken,
ChannelIds = [ChannelIds.GroupingTestCases],
ExportFormat = ExportFormat.HtmlDark,
OutputPath = file.Path
OutputPath = file.Path,
}.ExecuteAsync(new FakeConsole());
// Assert

@ -27,7 +27,7 @@ public class PartitioningSpecs
ChannelIds = [ChannelIds.DateRangeTestCases],
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
PartitionLimit = PartitionLimit.Parse("3")
PartitionLimit = PartitionLimit.Parse("3"),
}.ExecuteAsync(new FakeConsole());
// Assert
@ -48,7 +48,7 @@ public class PartitioningSpecs
ChannelIds = [ChannelIds.DateRangeTestCases],
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
PartitionLimit = PartitionLimit.Parse("1kb")
PartitionLimit = PartitionLimit.Parse("1kb"),
}.ExecuteAsync(new FakeConsole());
// Assert

@ -27,7 +27,7 @@ public class SelfContainedSpecs
ChannelIds = [ChannelIds.SelfContainedTestCases],
ExportFormat = ExportFormat.HtmlDark,
OutputPath = filePath,
ShouldDownloadAssets = true
ShouldDownloadAssets = true,
}.ExecuteAsync(new FakeConsole());
// Assert

@ -196,7 +196,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
new ParallelOptions
{
MaxDegreeOfParallelism = Math.Max(1, ParallelLimit),
CancellationToken = cancellationToken
CancellationToken = cancellationToken,
},
async (channel, innerCancellationToken) =>
{

@ -4,5 +4,5 @@ public enum ThreadInclusionMode
{
None,
Active,
All
All,
}

@ -13,7 +13,7 @@ internal static class ConsoleExtensions
{
Ansi = AnsiSupport.Detect,
ColorSystem = ColorSystemSupport.Detect,
Out = new AnsiConsoleOutput(console.Output)
Out = new AnsiConsoleOutput(console.Output),
}
);

@ -16,5 +16,5 @@ public enum ApplicationFlags
Embedded = 131072,
GatewayMessageContent = 262144,
GatewayMessageContentLimited = 524288,
ApplicationCommandBadge = 8388608
ApplicationCommandBadge = 8388608,
}

@ -14,5 +14,5 @@ public enum ChannelKind
GuildPrivateThread = 12,
GuildStageVoice = 13,
GuildDirectory = 14,
GuildForum = 15
GuildForum = 15,
}

@ -7,5 +7,5 @@ public enum EmbedKind
Image,
Video,
Gifv,
Link
Link,
}

@ -3548,7 +3548,7 @@ internal static class EmojiIndex
["🇸🇯"] = "flag_sj",
["🇹🇦"] = "flag_ta",
["🇺🇲"] = "flag_um",
["🇺🇳"] = "united_nations"
["🇺🇳"] = "united_nations",
};
private static Dictionary<string, string> _fromCodes =
@ -8880,7 +8880,7 @@ internal static class EmojiIndex
["flag_sj"] = "🇸🇯",
["flag_ta"] = "🇹🇦",
["flag_um"] = "🇺🇲",
["united_nations"] = "🇺🇳"
["united_nations"] = "🇺🇳",
};
public static string? TryGetCode(string name) => _toCodes.GetValueOrDefault(name);

@ -14,5 +14,5 @@ public enum MessageFlags
Urgent = 16,
HasThread = 32,
Ephemeral = 64,
Loading = 128
Loading = 128,
}

@ -12,5 +12,5 @@ public enum MessageKind
ChannelPinnedMessage = 6,
GuildMemberJoin = 7,
ThreadCreated = 18,
Reply = 19
Reply = 19,
}

@ -28,7 +28,7 @@ public partial record Sticker
StickerFormat.Apng => "png",
StickerFormat.Lottie => "json",
StickerFormat.Gif => "gif",
_ => throw new InvalidOperationException($"Unknown sticker format '{format}'.")
_ => throw new InvalidOperationException($"Unknown sticker format '{format}'."),
}
);

@ -5,5 +5,5 @@ public enum StickerFormat
Png = 1,
Apng = 2,
Lottie = 3,
Gif = 4
Gif = 4,
}

@ -133,25 +133,21 @@ public class DiscordClient(string token)
{
throw response.StatusCode switch
{
HttpStatusCode.Unauthorized
=> throw new DiscordChatExporterException(
"Authentication token is invalid.",
true
),
HttpStatusCode.Unauthorized => throw new DiscordChatExporterException(
"Authentication token is invalid.",
true
),
HttpStatusCode.Forbidden
=> throw new DiscordChatExporterException(
$"Request to '{url}' failed: forbidden."
),
HttpStatusCode.Forbidden => throw new DiscordChatExporterException(
$"Request to '{url}' failed: forbidden."
),
HttpStatusCode.NotFound
=> throw new DiscordChatExporterException(
$"Request to '{url}' failed: not found."
),
HttpStatusCode.NotFound => throw new DiscordChatExporterException(
$"Request to '{url}' failed: not found."
),
_
=> throw new DiscordChatExporterException(
$"""
_ => throw new DiscordChatExporterException(
$"""
Request to '{url}' failed: {response
.StatusCode.ToString()
.ToSpaceSeparatedWords()
@ -160,8 +156,8 @@ public class DiscordClient(string token)
cancellationToken
)}
""",
true
)
true
),
};
}

@ -3,5 +3,5 @@
public enum TokenKind
{
User,
Bot
Bot,
}

@ -8,7 +8,7 @@ public enum ExportFormat
HtmlDark,
HtmlLight,
Csv,
Json
Json,
}
public static class ExportFormatExtensions
@ -21,7 +21,7 @@ public static class ExportFormatExtensions
ExportFormat.HtmlLight => "html",
ExportFormat.Csv => "csv",
ExportFormat.Json => "json",
_ => throw new ArgumentOutOfRangeException(nameof(format))
_ => throw new ArgumentOutOfRangeException(nameof(format)),
};
public static string GetDisplayName(this ExportFormat format) =>
@ -32,6 +32,6 @@ public static class ExportFormatExtensions
ExportFormat.HtmlLight => "HTML (Light)",
ExportFormat.Csv => "CSV",
ExportFormat.Json => "JSON",
_ => throw new ArgumentOutOfRangeException(nameof(format))
_ => throw new ArgumentOutOfRangeException(nameof(format)),
};
}

@ -172,24 +172,21 @@ public partial class ExportRequest
"%C" => channel.Name,
"%p" => channel.Position?.ToString(CultureInfo.InvariantCulture) ?? "0",
"%P"
=> channel.Parent?.Position?.ToString(CultureInfo.InvariantCulture)
?? "0",
"%a"
=> after?.ToDate().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
?? "",
"%b"
=> before?.ToDate().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
?? "",
"%d"
=> DateTimeOffset.Now.ToString(
"yyyy-MM-dd",
CultureInfo.InvariantCulture
),
"%P" => channel.Parent?.Position?.ToString(CultureInfo.InvariantCulture)
?? "0",
"%a" => after?.ToDate().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
?? "",
"%b" => before
?.ToDate()
.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) ?? "",
"%d" => DateTimeOffset.Now.ToString(
"yyyy-MM-dd",
CultureInfo.InvariantCulture
),
"%%" => "%",
_ => m.Value
_ => m.Value,
}
)
);

@ -3,5 +3,5 @@
internal enum BinaryExpressionKind
{
Or,
And
And,
}

@ -14,6 +14,6 @@ internal class BinaryExpressionMessageFilter(
{
BinaryExpressionKind.Or => first.IsMatch(message) || second.IsMatch(message),
BinaryExpressionKind.And => first.IsMatch(message) && second.IsMatch(message),
_ => throw new InvalidOperationException($"Unknown binary expression kind '{kind}'.")
_ => throw new InvalidOperationException($"Unknown binary expression kind '{kind}'."),
};
}

@ -17,15 +17,13 @@ internal class HasMessageFilter(MessageContentMatchKind kind) : MessageFilter
MessageContentMatchKind.Image => message.Attachments.Any(file => file.IsImage),
MessageContentMatchKind.Sound => message.Attachments.Any(file => file.IsAudio),
MessageContentMatchKind.Pin => message.IsPinned,
MessageContentMatchKind.Invite
=> MarkdownParser
.ExtractLinks(message.Content)
.Select(l => l.Url)
.Select(Invite.TryGetCodeFromUrl)
.Any(c => !string.IsNullOrWhiteSpace(c)),
_
=> throw new InvalidOperationException(
$"Unknown message content match kind '{kind}'."
)
MessageContentMatchKind.Invite => MarkdownParser
.ExtractLinks(message.Content)
.Select(l => l.Url)
.Select(Invite.TryGetCodeFromUrl)
.Any(c => !string.IsNullOrWhiteSpace(c)),
_ => throw new InvalidOperationException(
$"Unknown message content match kind '{kind}'."
),
};
}

@ -9,5 +9,5 @@ internal enum MessageContentMatchKind
Image,
Sound,
Pin,
Invite
Invite,
}

@ -125,7 +125,7 @@ internal static class FilterGrammar
op switch
{
'|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or),
_ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And)
_ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And),
}
);

@ -34,58 +34,51 @@ internal partial class HtmlMarkdownVisitor(
{
var (openingTag, closingTag) = formatting.Kind switch
{
FormattingKind.Bold
=> (
// lang=html
"<strong>",
// lang=html
"</strong>"
),
FormattingKind.Italic
=> (
// lang=html
"<em>",
// lang=html
"</em>"
),
FormattingKind.Underline
=> (
// lang=html
"<u>",
// lang=html
"</u>"
),
FormattingKind.Strikethrough
=> (
// lang=html
"<s>",
// lang=html
"</s>"
),
FormattingKind.Spoiler
=> (
// lang=html
"""<span class="chatlog__markdown-spoiler chatlog__markdown-spoiler--hidden" onclick="showSpoiler(event, this)">""",
// lang=html
"""</span>"""
),
FormattingKind.Quote
=> (
// lang=html
"""<div class="chatlog__markdown-quote"><div class="chatlog__markdown-quote-border"></div><div class="chatlog__markdown-quote-content">""",
// lang=html
"""</div></div>"""
),
_
=> throw new InvalidOperationException(
$"Unknown formatting kind '{formatting.Kind}'."
)
FormattingKind.Bold => (
// lang=html
"<strong>",
// lang=html
"</strong>"
),
FormattingKind.Italic => (
// lang=html
"<em>",
// lang=html
"</em>"
),
FormattingKind.Underline => (
// lang=html
"<u>",
// lang=html
"</u>"
),
FormattingKind.Strikethrough => (
// lang=html
"<s>",
// lang=html
"</s>"
),
FormattingKind.Spoiler => (
// lang=html
"""<span class="chatlog__markdown-spoiler chatlog__markdown-spoiler--hidden" onclick="showSpoiler(event, this)">""",
// lang=html
"""</span>"""
),
FormattingKind.Quote => (
// lang=html
"""<div class="chatlog__markdown-quote"><div class="chatlog__markdown-quote-border"></div><div class="chatlog__markdown-quote-content">""",
// lang=html
"""</div></div>"""
),
_ => throw new InvalidOperationException(
$"Unknown formatting kind '{formatting.Kind}'."
),
};
buffer.Append(openingTag);

@ -90,7 +90,7 @@ internal class HtmlMessageWriter(Stream stream, ExportContext context, string th
await new MessageGroupTemplate
{
Context = Context,
Messages = messages
Messages = messages,
}.RenderAsync(cancellationToken)
)
);
@ -131,7 +131,7 @@ internal class HtmlMessageWriter(Stream stream, ExportContext context, string th
await new PostambleTemplate
{
Context = Context,
MessagesWritten = MessagesWritten
MessagesWritten = MessagesWritten,
}.RenderAsync(cancellationToken)
)
);

@ -25,7 +25,7 @@ internal class JsonMessageWriter(Stream stream, ExportContext context)
Indented = true,
// Validation errors may mask actual failures
// https://github.com/Tyrrrz/DiscordChatExporter/issues/413
SkipValidation = true
SkipValidation = true,
}
);

@ -100,13 +100,15 @@ internal partial class MessageExporter
ExportFormat.PlainText => new PlainTextMessageWriter(File.Create(filePath), context),
ExportFormat.Csv => new CsvMessageWriter(File.Create(filePath), context),
ExportFormat.HtmlDark => new HtmlMessageWriter(File.Create(filePath), context, "Dark"),
ExportFormat.HtmlLight
=> new HtmlMessageWriter(File.Create(filePath), context, "Light"),
ExportFormat.HtmlLight => new HtmlMessageWriter(
File.Create(filePath),
context,
"Light"
),
ExportFormat.Json => new JsonMessageWriter(File.Create(filePath), context),
_
=> throw new ArgumentOutOfRangeException(
nameof(format),
$"Unknown export format '{format}'."
)
_ => throw new ArgumentOutOfRangeException(
nameof(format),
$"Unknown export format '{format}'."
),
};
}

@ -37,7 +37,7 @@ public partial class PartitionLimit
"M" => 1_000_000,
"K" => 1_000,
"" => 1,
_ => -1
_ => -1,
};
if (magnitude < 0)

@ -10,20 +10,18 @@ internal static class PlainTextMessageExtensions
public static string GetFallbackContent(this Message message) =>
message.Kind switch
{
MessageKind.RecipientAdd
=> message.MentionedUsers.Any()
? $"Added {message.MentionedUsers.First().DisplayName} to the group."
: "Added a recipient.",
MessageKind.RecipientAdd => message.MentionedUsers.Any()
? $"Added {message.MentionedUsers.First().DisplayName} to the group."
: "Added a recipient.",
MessageKind.RecipientRemove
=> message.MentionedUsers.Any()
? message.Author.Id == message.MentionedUsers.First().Id
? "Left the group."
: $"Removed {message.MentionedUsers.First().DisplayName} from the group."
: "Removed a recipient.",
MessageKind.RecipientRemove => message.MentionedUsers.Any()
? message.Author.Id == message.MentionedUsers.First().Id
? "Left the group."
: $"Removed {message.MentionedUsers.First().DisplayName} from the group."
: "Removed a recipient.",
MessageKind.Call
=> $"Started a call that lasted {
MessageKind.Call =>
$"Started a call that lasted {
message
.CallEndedTimestamp?
.Pipe(t => t - message.Timestamp)
@ -31,16 +29,15 @@ internal static class PlainTextMessageExtensions
.ToString("n0", CultureInfo.InvariantCulture) ?? "0"
} minutes.",
MessageKind.ChannelNameChange
=> !string.IsNullOrWhiteSpace(message.Content)
? $"Changed the channel name: {message.Content}"
: "Changed the channel name.",
MessageKind.ChannelNameChange => !string.IsNullOrWhiteSpace(message.Content)
? $"Changed the channel name: {message.Content}"
: "Changed the channel name.",
MessageKind.ChannelIconChange => "Changed the channel icon.",
MessageKind.ChannelPinnedMessage => "Pinned a message.",
MessageKind.ThreadCreated => "Started a thread.",
MessageKind.GuildMemberJoin => "Joined the server.",
_ => message.Content
_ => message.Content,
};
}

@ -7,5 +7,5 @@ internal enum FormattingKind
Underline,
Strikethrough,
Spoiler,
Quote
Quote,
}

@ -6,5 +6,5 @@ internal enum MentionKind
Here,
User,
Channel,
Role
Role,
}

@ -377,10 +377,9 @@ internal static partial class MarkdownParser
null => null,
// Unknown format: throw an exception to consider this timestamp invalid
// https://github.com/Tyrrrz/DiscordChatExporter/issues/1156
var f
=> throw new InvalidOperationException(
$"Unknown timestamp format '{f}'."
)
var f => throw new InvalidOperationException(
$"Unknown timestamp format '{f}'."
),
};
return new TimestampNode(instant, format);

@ -39,7 +39,7 @@ public static class Http
ShouldHandle = new PredicateBuilder().Handle<Exception>(IsRetryableException),
MaxRetryAttempts = 4,
BackoffType = DelayBackoffType.Exponential,
Delay = TimeSpan.FromSeconds(1)
Delay = TimeSpan.FromSeconds(1),
}
)
.Build();
@ -68,7 +68,7 @@ public static class Http
return ValueTask.FromResult<TimeSpan?>(
TimeSpan.FromSeconds(Math.Pow(2, args.AttemptNumber) + 1)
);
}
},
}
)
.Build();

@ -9,7 +9,7 @@ public static class PathEx
{
private static readonly HashSet<char> InvalidFileNameChars =
[
.. Path.GetInvalidFileNameChars()
.. Path.GetInvalidFileNameChars(),
];
public static string EscapeFileName(string path)

@ -61,7 +61,7 @@ public class App : Application, IDisposable
{
ThemeVariant.Light => Avalonia.Styling.ThemeVariant.Light,
ThemeVariant.Dark => Avalonia.Styling.ThemeVariant.Dark,
_ => Avalonia.Styling.ThemeVariant.Default
_ => Avalonia.Styling.ThemeVariant.Default,
};
InitializeTheme();
@ -86,7 +86,7 @@ public class App : Application, IDisposable
{
"Light" => PlatformThemeVariant.Light,
"Dark" => PlatformThemeVariant.Dark,
_ => PlatformSettings?.GetColorValues().ThemeVariant ?? PlatformThemeVariant.Light
_ => PlatformSettings?.GetColorValues().ThemeVariant ?? PlatformThemeVariant.Light,
};
this.LocateMaterialTheme<MaterialThemeBase>().CurrentTheme =

@ -56,7 +56,7 @@ public class DialogManager : IDisposable
{
FileTypeChoices = fileTypes,
SuggestedFileName = defaultFilePath,
DefaultExtension = Path.GetExtension(defaultFilePath).TrimStart('.')
DefaultExtension = Path.GetExtension(defaultFilePath).TrimStart('.'),
}
);
@ -77,7 +77,7 @@ public class DialogManager : IDisposable
new FolderPickerOpenOptions
{
AllowMultiple = false,
SuggestedStartLocation = startLocation
SuggestedStartLocation = startLocation,
}
);

@ -4,5 +4,5 @@ public enum ThemeVariant
{
System,
Light,
Dark
Dark,
}

@ -19,7 +19,7 @@ public partial class ViewManager
ExportSetupViewModel => new ExportSetupView(),
MessageBoxViewModel => new MessageBoxView(),
SettingsViewModel => new SettingsView(),
_ => null
_ => null,
};
public Control? TryBindView(ViewModelBase viewModel)

@ -4,5 +4,5 @@ public enum ThreadInclusionMode
{
None,
Active,
All
All,
}

@ -253,7 +253,7 @@ public partial class DashboardViewModel : ViewModelBase
channelProgressPairs,
new ParallelOptions
{
MaxDegreeOfParallelism = Math.Max(1, _settingsService.ParallelLimit)
MaxDegreeOfParallelism = Math.Max(1, _settingsService.ParallelLimit),
},
async (pair, cancellationToken) =>
{

@ -138,8 +138,8 @@ public partial class ExportSetupViewModel(
[
new FilePickerFileType($"{extension.ToUpperInvariant()} file")
{
Patterns = [$"*.{extension}"]
}
Patterns = [$"*.{extension}"],
},
],
defaultFileName
);

@ -85,7 +85,7 @@ public class SettingsViewModel : DialogViewModelBase
"zh-CN",
"ja-JP",
"zh-TW",
"ko-KR"
"ko-KR",
];
// This has to be non-nullable because Avalonia ComboBox doesn't allow a null value to be selected

Loading…
Cancel
Save