mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-07-08 15:14:37 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 949abc2582 | |||
| 3b3423dd9b | |||
| 8380e88744 | |||
| f1bc5a2266 | |||
| dc35f25293 | |||
| 0e3969ca2d | |||
| 91b7486f45 |
@@ -99,7 +99,7 @@ jobs:
|
|||||||
# GUI assets aren't suffixed, unlike the CLI assets
|
# GUI assets aren't suffixed, unlike the CLI assets
|
||||||
asset: DiscordChatExporter
|
asset: DiscordChatExporter
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ startsWith(matrix.rid, 'win-') && 'windows-latest' || startsWith(matrix.rid, 'osx-') && 'macos-latest' || 'ubuntu-latest' }}
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -197,7 +197,7 @@ jobs:
|
|||||||
path: ${{ matrix.app }}/
|
path: ${{ matrix.app }}/
|
||||||
|
|
||||||
- name: Set permissions
|
- name: Set permissions
|
||||||
if: ${{ !startsWith(matrix.rid, 'win') }}
|
if: ${{ !startsWith(matrix.rid, 'win-') }}
|
||||||
run: chmod +x ${{ matrix.app }}/${{ matrix.asset }}
|
run: chmod +x ${{ matrix.app }}/${{ matrix.asset }}
|
||||||
|
|
||||||
- name: Create package
|
- name: Create package
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<ILLinkTreatWarningsAsErrors>false</ILLinkTreatWarningsAsErrors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||||
<PackageReference Include="xunit" Version="2.8.0" />
|
<PackageReference Include="xunit" Version="2.8.0" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" PrivateAssets="all" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<ApplicationIcon>..\favicon.ico</ApplicationIcon>
|
<ApplicationIcon>..\favicon.ico</ApplicationIcon>
|
||||||
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CliFx" Version="2.3.5" />
|
<PackageReference Include="CliFx" Version="2.3.5" />
|
||||||
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2" PrivateAssets="all" />
|
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2" PrivateAssets="all" />
|
||||||
|
|||||||
@@ -1,3 +1,41 @@
|
|||||||
using CliFx;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CliFx;
|
||||||
|
using DiscordChatExporter.Cli.Commands;
|
||||||
|
using DiscordChatExporter.Cli.Commands.Converters;
|
||||||
|
using DiscordChatExporter.Core.Exporting.Filtering;
|
||||||
|
using DiscordChatExporter.Core.Exporting.Partitioning;
|
||||||
|
|
||||||
return await new CliApplicationBuilder().AddCommandsFromThisAssembly().Build().RunAsync(args);
|
namespace DiscordChatExporter.Cli;
|
||||||
|
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
// Explicit references because CliFx relies on reflection and we're publishing with trimming enabled
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportAllCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportChannelsCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportDirectMessagesCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ExportGuildCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetChannelsCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetDirectChannelsCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GetGuildsCommand))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(GuideCommand))]
|
||||||
|
[DynamicDependency(
|
||||||
|
DynamicallyAccessedMemberTypes.All,
|
||||||
|
typeof(ThreadInclusionModeBindingConverter)
|
||||||
|
)]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(TruthyBooleanBindingConverter))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(PartitionLimit))]
|
||||||
|
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(MessageFilter))]
|
||||||
|
public static async Task<int> Main(string[] args) =>
|
||||||
|
await new CliApplicationBuilder()
|
||||||
|
.AddCommand<ExportAllCommand>()
|
||||||
|
.AddCommand<ExportChannelsCommand>()
|
||||||
|
.AddCommand<ExportDirectMessagesCommand>()
|
||||||
|
.AddCommand<ExportGuildCommand>()
|
||||||
|
.AddCommand<GetChannelsCommand>()
|
||||||
|
.AddCommand<GetDirectChannelsCommand>()
|
||||||
|
.AddCommand<GetGuildsCommand>()
|
||||||
|
.AddCommand<GuideCommand>()
|
||||||
|
.Build()
|
||||||
|
.RunAsync(args);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<PackageReference Include="RazorBlade" Version="0.6.0" />
|
<PackageReference Include="RazorBlade" Version="0.6.0" />
|
||||||
<PackageReference Include="Superpower" Version="3.0.0" />
|
<PackageReference Include="Superpower" Version="3.0.0" />
|
||||||
<PackageReference Include="WebMarkupMin.Core" Version="2.16.0" />
|
<PackageReference Include="WebMarkupMin.Core" Version="2.16.0" />
|
||||||
<PackageReference Include="YoutubeExplode" Version="6.3.14" />
|
<PackageReference Include="YoutubeExplode" Version="6.3.16" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<AssemblyName>DiscordChatExporter</AssemblyName>
|
<AssemblyName>DiscordChatExporter</AssemblyName>
|
||||||
<ApplicationIcon>..\favicon.ico</ApplicationIcon>
|
<ApplicationIcon>..\favicon.ico</ApplicationIcon>
|
||||||
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -15,7 +17,7 @@
|
|||||||
<PackageReference Include="Avalonia" Version="11.0.10" />
|
<PackageReference Include="Avalonia" Version="11.0.10" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
|
||||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.10" Condition="'$(Configuration)' == 'Debug'" />
|
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.10" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
<PackageReference Include="Cogwheel" Version="2.0.4" />
|
<PackageReference Include="Cogwheel" Version="2.1.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2" PrivateAssets="all" />
|
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2" PrivateAssets="all" />
|
||||||
<PackageReference Include="Deorcify" Version="1.0.2" PrivateAssets="all" />
|
<PackageReference Include="Deorcify" Version="1.0.2" PrivateAssets="all" />
|
||||||
@@ -24,7 +26,7 @@
|
|||||||
<PackageReference Include="Material.Avalonia" Version="3.6.0" />
|
<PackageReference Include="Material.Avalonia" Version="3.6.0" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" Version="2.1.9" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="2.1.9" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||||
<PackageReference Include="Onova" Version="2.6.11" />
|
<PackageReference Include="Onova" Version="2.6.12" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
using System;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
|
using DiscordChatExporter.Gui.ViewModels;
|
||||||
|
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||||
|
using DiscordChatExporter.Gui.ViewModels.Dialogs;
|
||||||
|
using DiscordChatExporter.Gui.Views;
|
||||||
|
using DiscordChatExporter.Gui.Views.Components;
|
||||||
|
using DiscordChatExporter.Gui.Views.Dialogs;
|
||||||
|
|
||||||
namespace DiscordChatExporter.Gui.Framework;
|
namespace DiscordChatExporter.Gui.Framework;
|
||||||
|
|
||||||
public partial class ViewManager
|
public partial class ViewManager
|
||||||
{
|
{
|
||||||
|
private Control? TryCreateView(ViewModelBase viewModel) =>
|
||||||
|
viewModel switch
|
||||||
|
{
|
||||||
|
MainViewModel => new MainView(),
|
||||||
|
DashboardViewModel => new DashboardView(),
|
||||||
|
ExportSetupViewModel => new ExportSetupView(),
|
||||||
|
MessageBoxViewModel => new MessageBoxView(),
|
||||||
|
SettingsViewModel => new SettingsView(),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
public Control? TryBindView(ViewModelBase viewModel)
|
public Control? TryBindView(ViewModelBase viewModel)
|
||||||
{
|
{
|
||||||
var name = viewModel
|
var view = TryCreateView(viewModel);
|
||||||
.GetType()
|
if (view is null)
|
||||||
.FullName?.Replace("ViewModel", "View", StringComparison.Ordinal);
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var type = Type.GetType(name);
|
|
||||||
if (type is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (Activator.CreateInstance(type) is not Control view)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
view.DataContext ??= viewModel;
|
view.DataContext ??= viewModel;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Cogwheel;
|
using Cogwheel;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using DiscordChatExporter.Core.Exporting;
|
using DiscordChatExporter.Core.Exporting;
|
||||||
@@ -8,57 +9,126 @@ using DiscordChatExporter.Gui.Models;
|
|||||||
|
|
||||||
namespace DiscordChatExporter.Gui.Services;
|
namespace DiscordChatExporter.Gui.Services;
|
||||||
|
|
||||||
|
// Can't use [ObservableProperty] here because System.Text.Json's source generator doesn't see
|
||||||
|
// the generated properties.
|
||||||
[INotifyPropertyChanged]
|
[INotifyPropertyChanged]
|
||||||
public partial class SettingsService()
|
public partial class SettingsService()
|
||||||
: SettingsBase(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.dat"))
|
: SettingsBase(
|
||||||
|
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.dat"),
|
||||||
|
SerializerContext.Default
|
||||||
|
)
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isUkraineSupportMessageEnabled = true;
|
private bool _isUkraineSupportMessageEnabled = true;
|
||||||
|
public bool IsUkraineSupportMessageEnabled
|
||||||
|
{
|
||||||
|
get => _isUkraineSupportMessageEnabled;
|
||||||
|
set => SetProperty(ref _isUkraineSupportMessageEnabled, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ThemeVariant _theme;
|
private ThemeVariant _theme;
|
||||||
|
public ThemeVariant Theme
|
||||||
|
{
|
||||||
|
get => _theme;
|
||||||
|
set => SetProperty(ref _theme, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isAutoUpdateEnabled = true;
|
private bool _isAutoUpdateEnabled = true;
|
||||||
|
public bool IsAutoUpdateEnabled
|
||||||
|
{
|
||||||
|
get => _isAutoUpdateEnabled;
|
||||||
|
set => SetProperty(ref _isAutoUpdateEnabled, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isTokenPersisted = true;
|
private bool _isTokenPersisted = true;
|
||||||
|
public bool IsTokenPersisted
|
||||||
|
{
|
||||||
|
get => _isTokenPersisted;
|
||||||
|
set => SetProperty(ref _isTokenPersisted, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ThreadInclusionMode _threadInclusionMode;
|
private ThreadInclusionMode _threadInclusionMode;
|
||||||
|
public ThreadInclusionMode ThreadInclusionMode
|
||||||
|
{
|
||||||
|
get => _threadInclusionMode;
|
||||||
|
set => SetProperty(ref _threadInclusionMode, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _locale;
|
private string? _locale;
|
||||||
|
public string? Locale
|
||||||
|
{
|
||||||
|
get => _locale;
|
||||||
|
set => SetProperty(ref _locale, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _isUtcNormalizationEnabled;
|
private bool _isUtcNormalizationEnabled;
|
||||||
|
public bool IsUtcNormalizationEnabled
|
||||||
|
{
|
||||||
|
get => _isUtcNormalizationEnabled;
|
||||||
|
set => SetProperty(ref _isUtcNormalizationEnabled, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private int _parallelLimit = 1;
|
private int _parallelLimit = 1;
|
||||||
|
public int ParallelLimit
|
||||||
|
{
|
||||||
|
get => _parallelLimit;
|
||||||
|
set => SetProperty(ref _parallelLimit, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _lastToken;
|
private string? _lastToken;
|
||||||
|
public string? LastToken
|
||||||
|
{
|
||||||
|
get => _lastToken;
|
||||||
|
set => SetProperty(ref _lastToken, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private ExportFormat _lastExportFormat = ExportFormat.HtmlDark;
|
private ExportFormat _lastExportFormat = ExportFormat.HtmlDark;
|
||||||
|
public ExportFormat LastExportFormat
|
||||||
|
{
|
||||||
|
get => _lastExportFormat;
|
||||||
|
set => SetProperty(ref _lastExportFormat, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _lastPartitionLimitValue;
|
private string? _lastPartitionLimitValue;
|
||||||
|
public string? LastPartitionLimitValue
|
||||||
|
{
|
||||||
|
get => _lastPartitionLimitValue;
|
||||||
|
set => SetProperty(ref _lastPartitionLimitValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _lastMessageFilterValue;
|
private string? _lastMessageFilterValue;
|
||||||
|
public string? LastMessageFilterValue
|
||||||
|
{
|
||||||
|
get => _lastMessageFilterValue;
|
||||||
|
set => SetProperty(ref _lastMessageFilterValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _lastShouldFormatMarkdown = true;
|
private bool _lastShouldFormatMarkdown = true;
|
||||||
|
public bool LastShouldFormatMarkdown
|
||||||
|
{
|
||||||
|
get => _lastShouldFormatMarkdown;
|
||||||
|
set => SetProperty(ref _lastShouldFormatMarkdown, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _lastShouldDownloadAssets;
|
private bool _lastShouldDownloadAssets;
|
||||||
|
public bool LastShouldDownloadAssets
|
||||||
|
{
|
||||||
|
get => _lastShouldDownloadAssets;
|
||||||
|
set => SetProperty(ref _lastShouldDownloadAssets, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _lastShouldReuseAssets;
|
private bool _lastShouldReuseAssets;
|
||||||
|
public bool LastShouldReuseAssets
|
||||||
|
{
|
||||||
|
get => _lastShouldReuseAssets;
|
||||||
|
set => SetProperty(ref _lastShouldReuseAssets, value);
|
||||||
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string? _lastAssetsDirPath;
|
private string? _lastAssetsDirPath;
|
||||||
|
public string? LastAssetsDirPath
|
||||||
|
{
|
||||||
|
get => _lastAssetsDirPath;
|
||||||
|
set => SetProperty(ref _lastAssetsDirPath, value);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Save()
|
public override void Save()
|
||||||
{
|
{
|
||||||
@@ -72,3 +142,9 @@ public partial class SettingsService()
|
|||||||
LastToken = lastToken;
|
LastToken = lastToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public partial class SettingsService
|
||||||
|
{
|
||||||
|
[JsonSerializable(typeof(SettingsService))]
|
||||||
|
private partial class SerializerContext : JsonSerializerContext;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,18 +9,20 @@ namespace DiscordChatExporter.Gui.Services;
|
|||||||
|
|
||||||
public class UpdateService(SettingsService settingsService) : IDisposable
|
public class UpdateService(SettingsService settingsService) : IDisposable
|
||||||
{
|
{
|
||||||
private readonly IUpdateManager _updateManager = new UpdateManager(
|
private readonly IUpdateManager? _updateManager = OperatingSystem.IsWindows()
|
||||||
new GithubPackageResolver(
|
? new UpdateManager(
|
||||||
"Tyrrrz",
|
new GithubPackageResolver(
|
||||||
"DiscordChatExporter",
|
"Tyrrrz",
|
||||||
// Examples:
|
"DiscordChatExporter",
|
||||||
// DiscordChatExporter.win-arm64.zip
|
// Examples:
|
||||||
// DiscordChatExporter.win-x64.zip
|
// DiscordChatExporter.win-arm64.zip
|
||||||
// DiscordChatExporter.linux-x64.zip
|
// DiscordChatExporter.win-x64.zip
|
||||||
$"DiscordChatExporter.{RuntimeInformation.RuntimeIdentifier}.zip"
|
// DiscordChatExporter.linux-x64.zip
|
||||||
),
|
$"DiscordChatExporter.{RuntimeInformation.RuntimeIdentifier}.zip"
|
||||||
new ZipPackageExtractor()
|
),
|
||||||
);
|
new ZipPackageExtractor()
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
private Version? _updateVersion;
|
private Version? _updateVersion;
|
||||||
private bool _updatePrepared;
|
private bool _updatePrepared;
|
||||||
@@ -28,6 +30,9 @@ public class UpdateService(SettingsService settingsService) : IDisposable
|
|||||||
|
|
||||||
public async ValueTask<Version?> CheckForUpdatesAsync()
|
public async ValueTask<Version?> CheckForUpdatesAsync()
|
||||||
{
|
{
|
||||||
|
if (_updateManager is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
if (!settingsService.IsAutoUpdateEnabled)
|
if (!settingsService.IsAutoUpdateEnabled)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -37,6 +42,9 @@ public class UpdateService(SettingsService settingsService) : IDisposable
|
|||||||
|
|
||||||
public async ValueTask PrepareUpdateAsync(Version version)
|
public async ValueTask PrepareUpdateAsync(Version version)
|
||||||
{
|
{
|
||||||
|
if (_updateManager is null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!settingsService.IsAutoUpdateEnabled)
|
if (!settingsService.IsAutoUpdateEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -57,11 +65,10 @@ public class UpdateService(SettingsService settingsService) : IDisposable
|
|||||||
|
|
||||||
public void FinalizeUpdate(bool needRestart)
|
public void FinalizeUpdate(bool needRestart)
|
||||||
{
|
{
|
||||||
if (!settingsService.IsAutoUpdateEnabled)
|
if (_updateManager is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Onova only works on Windows currently
|
if (!settingsService.IsAutoUpdateEnabled)
|
||||||
if (!OperatingSystem.IsWindows())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_updateVersion is null || !_updatePrepared || _updaterLaunched)
|
if (_updateVersion is null || !_updatePrepared || _updaterLaunched)
|
||||||
@@ -82,5 +89,5 @@ public class UpdateService(SettingsService settingsService) : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() => _updateManager.Dispose();
|
public void Dispose() => _updateManager?.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,8 @@
|
|||||||
xmlns:materialIcons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
xmlns:materialIcons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
xmlns:materialStyles="clr-namespace:Material.Styles.Controls;assembly=Material.Styles"
|
xmlns:materialStyles="clr-namespace:Material.Styles.Controls;assembly=Material.Styles"
|
||||||
x:Name="UserControl"
|
x:Name="UserControl"
|
||||||
|
x:DataType="components:DashboardViewModel"
|
||||||
Loaded="UserControl_OnLoaded">
|
Loaded="UserControl_OnLoaded">
|
||||||
<Design.DataContext>
|
|
||||||
<components:DashboardViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<StackPanel
|
<StackPanel
|
||||||
@@ -95,126 +92,6 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</Style>
|
</Style>
|
||||||
</Panel.Styles>
|
</Panel.Styles>
|
||||||
<!-- Placeholder / usage instructions -->
|
|
||||||
<Panel IsVisible="{Binding !AvailableGuilds.Count}">
|
|
||||||
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
|
||||||
<TextBlock
|
|
||||||
Margin="32,16"
|
|
||||||
FontSize="14"
|
|
||||||
FontWeight="Light"
|
|
||||||
LineHeight="23">
|
|
||||||
<!-- User token -->
|
|
||||||
<InlineUIContainer>
|
|
||||||
<materialIcons:MaterialIcon
|
|
||||||
Width="18"
|
|
||||||
Height="18"
|
|
||||||
Margin="0,-2,0,0"
|
|
||||||
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
|
||||||
Kind="Account" />
|
|
||||||
</InlineUIContainer>
|
|
||||||
<Run Text="" />
|
|
||||||
<Run
|
|
||||||
FontSize="16"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Text="To get the token for your personal account:" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="* Automating user accounts is technically against TOS —" />
|
|
||||||
<Run FontWeight="SemiBold" Text="use at your own risk" /><Run Text="!" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="1. Open Discord in your" />
|
|
||||||
<controls:HyperLink Command="{Binding OpenDiscordCommand}" Text="web browser" />
|
|
||||||
<Run Text="and login" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="2. Open any server or direct message channel" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="3. Press" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Ctrl+Shift+I" />
|
|
||||||
<Run Text="to show developer tools" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="4. Navigate to the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Network" />
|
|
||||||
<Run Text="tab" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="5. Press" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Ctrl+R" />
|
|
||||||
<Run Text="to reload" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="6. Switch between random channels to trigger network requests" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="7. Search for a request that starts with" />
|
|
||||||
<Run FontWeight="SemiBold" Text="messages" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="8. Select the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Headers" />
|
|
||||||
<Run Text="tab on the right" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="9. Scroll down to the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Request Headers" />
|
|
||||||
<Run Text="section" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="10. Copy the value of the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="authorization" />
|
|
||||||
<Run Text="header" />
|
|
||||||
<LineBreak />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<!-- Bot token -->
|
|
||||||
<InlineUIContainer>
|
|
||||||
<materialIcons:MaterialIcon
|
|
||||||
Width="18"
|
|
||||||
Height="18"
|
|
||||||
Margin="0,-2,0,0"
|
|
||||||
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
|
||||||
Kind="Robot" />
|
|
||||||
</InlineUIContainer>
|
|
||||||
<Run Text="" />
|
|
||||||
<Run
|
|
||||||
FontSize="16"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
Text="To get the token for your bot:" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="1. Open Discord" />
|
|
||||||
<controls:HyperLink Command="{Binding OpenDiscordDeveloperPortalCommand}" Text="developer portal" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="2. Open your application's settings" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="3. Navigate to the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Bot" />
|
|
||||||
<Run Text="section on the left" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="4. Under" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Token" />
|
|
||||||
<Run Text="click" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Copy" />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="* Your bot needs to have the" />
|
|
||||||
<Run FontWeight="SemiBold" Text="Message Content Intent" />
|
|
||||||
<Run Text="enabled to read messages" />
|
|
||||||
<LineBreak />
|
|
||||||
<LineBreak />
|
|
||||||
|
|
||||||
<Run Text="If you have questions or issues, please refer to the" />
|
|
||||||
<controls:HyperLink Command="{Binding ShowHelpCommand}" Text="documentation" />
|
|
||||||
</TextBlock>
|
|
||||||
</ScrollViewer>
|
|
||||||
</Panel>
|
|
||||||
|
|
||||||
<!-- Guilds and channels -->
|
<!-- Guilds and channels -->
|
||||||
<Grid ColumnDefinitions="Auto,*" IsVisible="{Binding !!AvailableGuilds.Count}">
|
<Grid ColumnDefinitions="Auto,*" IsVisible="{Binding !!AvailableGuilds.Count}">
|
||||||
<!-- Guilds -->
|
<!-- Guilds -->
|
||||||
@@ -339,6 +216,126 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Placeholder / usage instructions -->
|
||||||
|
<Panel IsVisible="{Binding !AvailableGuilds.Count}">
|
||||||
|
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||||
|
<TextBlock
|
||||||
|
Margin="32,16"
|
||||||
|
FontSize="14"
|
||||||
|
FontWeight="Light"
|
||||||
|
LineHeight="23">
|
||||||
|
<!-- User token -->
|
||||||
|
<InlineUIContainer>
|
||||||
|
<materialIcons:MaterialIcon
|
||||||
|
Width="18"
|
||||||
|
Height="18"
|
||||||
|
Margin="0,-2,0,0"
|
||||||
|
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
||||||
|
Kind="Account" />
|
||||||
|
</InlineUIContainer>
|
||||||
|
<Run Text="" />
|
||||||
|
<Run
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Text="To get the token for your personal account:" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="* Automating user accounts is technically against TOS —" />
|
||||||
|
<Run FontWeight="SemiBold" Text="use at your own risk" /><Run Text="!" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="1. Open Discord in your" />
|
||||||
|
<controls:HyperLink Command="{Binding OpenDiscordCommand}" Text="web browser" />
|
||||||
|
<Run Text="and login" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="2. Open any server or direct message channel" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="3. Press" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Ctrl+Shift+I" />
|
||||||
|
<Run Text="to show developer tools" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="4. Navigate to the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Network" />
|
||||||
|
<Run Text="tab" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="5. Press" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Ctrl+R" />
|
||||||
|
<Run Text="to reload" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="6. Switch between random channels to trigger network requests" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="7. Search for a request that starts with" />
|
||||||
|
<Run FontWeight="SemiBold" Text="messages" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="8. Select the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Headers" />
|
||||||
|
<Run Text="tab on the right" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="9. Scroll down to the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Request Headers" />
|
||||||
|
<Run Text="section" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="10. Copy the value of the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="authorization" />
|
||||||
|
<Run Text="header" />
|
||||||
|
<LineBreak />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<!-- Bot token -->
|
||||||
|
<InlineUIContainer>
|
||||||
|
<materialIcons:MaterialIcon
|
||||||
|
Width="18"
|
||||||
|
Height="18"
|
||||||
|
Margin="0,-2,0,0"
|
||||||
|
Foreground="{DynamicResource PrimaryHueMidBrush}"
|
||||||
|
Kind="Robot" />
|
||||||
|
</InlineUIContainer>
|
||||||
|
<Run Text="" />
|
||||||
|
<Run
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Text="To get the token for your bot:" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="1. Open Discord" />
|
||||||
|
<controls:HyperLink Command="{Binding OpenDiscordDeveloperPortalCommand}" Text="developer portal" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="2. Open your application's settings" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="3. Navigate to the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Bot" />
|
||||||
|
<Run Text="section on the left" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="4. Under" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Token" />
|
||||||
|
<Run Text="click" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Copy" />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="* Your bot needs to have the" />
|
||||||
|
<Run FontWeight="SemiBold" Text="Message Content Intent" />
|
||||||
|
<Run Text="enabled to read messages" />
|
||||||
|
<LineBreak />
|
||||||
|
<LineBreak />
|
||||||
|
|
||||||
|
<Run Text="If you have questions or issues, please refer to the" />
|
||||||
|
<controls:HyperLink Command="{Binding ShowHelpCommand}" Text="documentation" />
|
||||||
|
</TextBlock>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Panel>
|
||||||
|
|
||||||
<!-- Export button -->
|
<!-- Export button -->
|
||||||
<Button
|
<Button
|
||||||
Width="56"
|
Width="56"
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
<UserControl
|
<UserControl
|
||||||
x:Class="DiscordChatExporter.Gui.Views.Controls.HyperLink"
|
x:Class="DiscordChatExporter.Gui.Views.Controls.HyperLink"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="clr-namespace:DiscordChatExporter.Gui.Views.Controls">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
x:Name="TextBlock"
|
x:Name="TextBlock"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
Foreground="{DynamicResource MaterialSecondaryDarkBrush}"
|
Foreground="{DynamicResource MaterialSecondaryDarkBrush}"
|
||||||
PointerReleased="TextBlock_OnPointerReleased"
|
PointerReleased="TextBlock_OnPointerReleased"
|
||||||
Text="{Binding $parent[UserControl].Text, Mode=OneWay}">
|
Text="{Binding $parent[controls:HyperLink].Text, Mode=OneWay}">
|
||||||
<TextBlock.Styles>
|
<TextBlock.Styles>
|
||||||
<Style Selector="TextBlock">
|
<Style Selector="TextBlock">
|
||||||
<Style Selector="^:pointerover">
|
<Style Selector="^:pointerover">
|
||||||
|
|||||||
@@ -10,11 +10,8 @@
|
|||||||
xmlns:utils="clr-namespace:DiscordChatExporter.Gui.Utils"
|
xmlns:utils="clr-namespace:DiscordChatExporter.Gui.Utils"
|
||||||
x:Name="UserControl"
|
x:Name="UserControl"
|
||||||
Width="380"
|
Width="380"
|
||||||
|
x:DataType="dialogs:ExportSetupViewModel"
|
||||||
Loaded="UserControl_OnLoaded">
|
Loaded="UserControl_OnLoaded">
|
||||||
<Design.DataContext>
|
|
||||||
<dialogs:ExportSetupViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<Grid RowDefinitions="Auto,*,Auto">
|
<Grid RowDefinitions="Auto,*,Auto">
|
||||||
<!-- Guild/channel info -->
|
<!-- Guild/channel info -->
|
||||||
<Grid
|
<Grid
|
||||||
@@ -40,7 +37,7 @@
|
|||||||
FontWeight="Light"
|
FontWeight="Light"
|
||||||
IsVisible="{Binding !IsSingleChannel}"
|
IsVisible="{Binding !IsSingleChannel}"
|
||||||
TextTrimming="CharacterEllipsis">
|
TextTrimming="CharacterEllipsis">
|
||||||
<Run Text="{Binding Channels.Count, Mode=OneWay}" />
|
<Run Text="{Binding Channels.Count, FallbackValue=0, Mode=OneWay}" />
|
||||||
<Run Text="channels selected" />
|
<Run Text="channels selected" />
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,8 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
|
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
|
||||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||||
Width="500">
|
Width="500"
|
||||||
<Design.DataContext>
|
x:DataType="dialogs:MessageBoxViewModel">
|
||||||
<dialogs:MessageBoxViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<Grid RowDefinitions="Auto,*,Auto">
|
<Grid RowDefinitions="Auto,*,Auto">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<TextBlock
|
<TextBlock
|
||||||
|
|||||||
@@ -4,11 +4,8 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:converters="clr-namespace:DiscordChatExporter.Gui.Converters"
|
xmlns:converters="clr-namespace:DiscordChatExporter.Gui.Converters"
|
||||||
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
|
xmlns:dialogs="clr-namespace:DiscordChatExporter.Gui.ViewModels.Dialogs"
|
||||||
Width="380">
|
Width="380"
|
||||||
<Design.DataContext>
|
x:DataType="dialogs:SettingsViewModel">
|
||||||
<dialogs:SettingsViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<Grid RowDefinitions="Auto,*,Auto">
|
<Grid RowDefinitions="Auto,*,Auto">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
|
|||||||
@@ -10,13 +10,10 @@
|
|||||||
Height="625"
|
Height="625"
|
||||||
MinWidth="600"
|
MinWidth="600"
|
||||||
MinHeight="400"
|
MinHeight="400"
|
||||||
|
x:DataType="viewModels:MainViewModel"
|
||||||
Icon="/favicon.ico"
|
Icon="/favicon.ico"
|
||||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||||
WindowStartupLocation="CenterScreen">
|
WindowStartupLocation="CenterScreen">
|
||||||
<Design.DataContext>
|
|
||||||
<viewModels:MainViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
|
|
||||||
<dialogHostAvalonia:DialogHost
|
<dialogHostAvalonia:DialogHost
|
||||||
x:Name="DialogHost"
|
x:Name="DialogHost"
|
||||||
CloseOnClickAway="False"
|
CloseOnClickAway="False"
|
||||||
|
|||||||
Reference in New Issue
Block a user