mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-02-26 11:13:47 +00:00
More refactoring
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Behaviors
|
||||
{
|
||||
public class ChannelMultiSelectionListBoxBehavior : MultiSelectionListBoxBehavior<Channel>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Behaviors
|
||||
{
|
||||
public class ChannelViewModelMultiSelectionListBoxBehavior : MultiSelectionListBoxBehavior<ChannelViewModel>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using Stylet;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Components
|
||||
{
|
||||
public partial class ChannelViewModel : PropertyChangedBase
|
||||
{
|
||||
public Channel? Model { get; set; }
|
||||
|
||||
public string? Category { get; set; }
|
||||
}
|
||||
|
||||
public partial class ChannelViewModel
|
||||
{
|
||||
public static implicit operator Channel?(ChannelViewModel? viewModel) => viewModel?.Model;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using Stylet;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Components
|
||||
{
|
||||
public partial class GuildViewModel : PropertyChangedBase
|
||||
{
|
||||
public Guild? Model { get; set; }
|
||||
|
||||
public IReadOnlyList<ChannelViewModel>? Channels { get; set; }
|
||||
}
|
||||
|
||||
public partial class GuildViewModel
|
||||
{
|
||||
public static implicit operator Guild?(GuildViewModel? viewModel) => viewModel?.Model;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using DiscordChatExporter.Domain.Exporting;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
using DiscordChatExporter.Gui.ViewModels.Framework;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
||||
@@ -13,9 +13,9 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
||||
private readonly DialogManager _dialogManager;
|
||||
private readonly SettingsService _settingsService;
|
||||
|
||||
public GuildViewModel? Guild { get; set; }
|
||||
public Guild? Guild { get; set; }
|
||||
|
||||
public IReadOnlyList<ChannelViewModel>? Channels { get; set; }
|
||||
public IReadOnlyList<Channel>? Channels { get; set; }
|
||||
|
||||
public bool IsSingleChannel => Channels == null || Channels.Count == 1;
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
||||
var channel = Channels.Single();
|
||||
|
||||
// Generate default file name
|
||||
var defaultFileName = ChannelExporter.GetDefaultExportFileName(Guild!, channel!, SelectedFormat, After, Before);
|
||||
var defaultFileName = ChannelExporter.GetDefaultExportFileName(Guild!, channel, SelectedFormat, After, Before);
|
||||
|
||||
// Generate filter
|
||||
var ext = SelectedFormat.GetFileExtension();
|
||||
|
||||
@@ -1,33 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
using DiscordChatExporter.Gui.ViewModels.Dialogs;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Framework
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static ChannelViewModel CreateChannelViewModel(this IViewModelFactory factory, Channel model, string? category = null)
|
||||
{
|
||||
var viewModel = factory.CreateChannelViewModel();
|
||||
viewModel.Model = model;
|
||||
viewModel.Category = category;
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public static GuildViewModel CreateGuildViewModel(this IViewModelFactory factory, Guild model,
|
||||
IReadOnlyList<ChannelViewModel> channels)
|
||||
{
|
||||
var viewModel = factory.CreateGuildViewModel();
|
||||
viewModel.Model = model;
|
||||
viewModel.Channels = channels;
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public static ExportSetupViewModel CreateExportSetupViewModel(this IViewModelFactory factory,
|
||||
GuildViewModel guild, IReadOnlyList<ChannelViewModel> channels)
|
||||
Guild guild, IReadOnlyList<Channel> channels)
|
||||
{
|
||||
var viewModel = factory.CreateExportSetupViewModel();
|
||||
viewModel.Guild = guild;
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
using DiscordChatExporter.Gui.ViewModels.Dialogs;
|
||||
using DiscordChatExporter.Gui.ViewModels.Dialogs;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Framework
|
||||
{
|
||||
// Used to instantiate new view models while making use of dependency injection
|
||||
public interface IViewModelFactory
|
||||
{
|
||||
ChannelViewModel CreateChannelViewModel();
|
||||
|
||||
GuildViewModel CreateGuildViewModel();
|
||||
|
||||
ExportSetupViewModel CreateExportSetupViewModel();
|
||||
|
||||
SettingsViewModel CreateSettingsViewModel();
|
||||
|
||||
@@ -9,7 +9,6 @@ using DiscordChatExporter.Domain.Exceptions;
|
||||
using DiscordChatExporter.Domain.Exporting;
|
||||
using DiscordChatExporter.Domain.Utilities;
|
||||
using DiscordChatExporter.Gui.Services;
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
using DiscordChatExporter.Gui.ViewModels.Framework;
|
||||
using Gress;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
@@ -37,11 +36,17 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||
|
||||
public string? TokenValue { get; set; }
|
||||
|
||||
public IReadOnlyList<GuildViewModel>? AvailableGuilds { get; private set; }
|
||||
private IReadOnlyDictionary<Guild, IReadOnlyList<Channel>>? GuildChannelMap { get; set; }
|
||||
|
||||
public GuildViewModel? SelectedGuild { get; set; }
|
||||
public IReadOnlyList<Guild>? AvailableGuilds => GuildChannelMap?.Keys.ToArray();
|
||||
|
||||
public IReadOnlyList<ChannelViewModel>? SelectedChannels { get; set; }
|
||||
public Guild? SelectedGuild { get; set; }
|
||||
|
||||
public IReadOnlyList<Channel>? AvailableChannels => SelectedGuild != null
|
||||
? GuildChannelMap?[SelectedGuild]
|
||||
: null;
|
||||
|
||||
public IReadOnlyList<Channel>? SelectedChannels { get; set; }
|
||||
|
||||
public RootViewModel(
|
||||
IViewModelFactory viewModelFactory,
|
||||
@@ -142,71 +147,18 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||
|
||||
var discord = new DiscordClient(token);
|
||||
|
||||
var availableGuilds = new List<GuildViewModel>();
|
||||
|
||||
// Direct messages
|
||||
{
|
||||
var guild = Guild.DirectMessages;
|
||||
var channels = await discord.GetDirectMessageChannelsAsync();
|
||||
|
||||
// Create channel view models
|
||||
var channelViewModels = new List<ChannelViewModel>();
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
// Get fake category
|
||||
var category = channel.Type == ChannelType.DirectTextChat ? "Private" : "Group";
|
||||
|
||||
// Create channel view model
|
||||
var channelViewModel = _viewModelFactory.CreateChannelViewModel(channel, category);
|
||||
|
||||
// Add to list
|
||||
channelViewModels.Add(channelViewModel);
|
||||
}
|
||||
|
||||
// Create guild view model
|
||||
var guildViewModel = _viewModelFactory.CreateGuildViewModel(guild,
|
||||
channelViewModels.OrderBy(c => c.Category)
|
||||
.ThenBy(c => c.Model!.Name)
|
||||
.ToArray());
|
||||
|
||||
// Add to list
|
||||
availableGuilds.Add(guildViewModel);
|
||||
}
|
||||
|
||||
// Guilds
|
||||
var guilds = await discord.GetUserGuildsAsync();
|
||||
foreach (var guild in guilds)
|
||||
var guildChannelMap = new Dictionary<Guild, IReadOnlyList<Channel>>();
|
||||
await foreach (var guild in discord.GetUserGuildsAsync())
|
||||
{
|
||||
var channels = await discord.GetGuildChannelsAsync(guild.Id);
|
||||
var categoryChannels = channels.Where(c => c.Type == ChannelType.GuildCategory).ToArray();
|
||||
var exportableChannels = channels.Where(c => c.IsTextChannel).ToArray();
|
||||
|
||||
// Create channel view models
|
||||
var channelViewModels = new List<ChannelViewModel>();
|
||||
foreach (var channel in exportableChannels)
|
||||
{
|
||||
// Get category
|
||||
var category = categoryChannels.FirstOrDefault(c => c.Id == channel.ParentId)?.Name;
|
||||
|
||||
// Create channel view model
|
||||
var channelViewModel = _viewModelFactory.CreateChannelViewModel(channel, category);
|
||||
|
||||
// Add to list
|
||||
channelViewModels.Add(channelViewModel);
|
||||
}
|
||||
|
||||
// Create guild view model
|
||||
var guildViewModel = _viewModelFactory.CreateGuildViewModel(guild,
|
||||
channelViewModels.OrderBy(c => c.Category)
|
||||
.ThenBy(c => c.Model!.Name)
|
||||
.ToArray());
|
||||
|
||||
// Add to list
|
||||
availableGuilds.Add(guildViewModel);
|
||||
guildChannelMap[guild] = channels
|
||||
.OrderBy(c => c.Category)
|
||||
.ThenBy(c => c.Name)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
AvailableGuilds = availableGuilds;
|
||||
SelectedGuild = AvailableGuilds.FirstOrDefault();
|
||||
GuildChannelMap = guildChannelMap;
|
||||
SelectedGuild = guildChannelMap.Keys.FirstOrDefault();
|
||||
}
|
||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
Width="32"
|
||||
Height="32">
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush ImageSource="{Binding Guild.Model.IconUrl}" />
|
||||
<ImageBrush ImageSource="{Binding Guild.IconUrl}" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
<Run Text="/" />
|
||||
<Run
|
||||
Foreground="{DynamicResource PrimaryTextBrush}"
|
||||
Text="{Binding Channels[0].Model.Name, Mode=OneWay}"
|
||||
ToolTip="{Binding Channels[0].Model.Name, Mode=OneWay}" />
|
||||
Text="{Binding Channels[0].Name, Mode=OneWay}"
|
||||
ToolTip="{Binding Channels[0].Name, Mode=OneWay}" />
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
Margin="-8"
|
||||
Background="Transparent"
|
||||
Cursor="Hand"
|
||||
ToolTip="{Binding Model.Name}">
|
||||
ToolTip="{Binding Name}">
|
||||
<!-- Guild icon placeholder -->
|
||||
<Ellipse
|
||||
Width="48"
|
||||
@@ -240,7 +240,7 @@
|
||||
Height="48"
|
||||
Margin="12,4,12,4">
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush ImageSource="{Binding Model.IconUrl}" />
|
||||
<ImageBrush ImageSource="{Binding IconUrl}" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
</Grid>
|
||||
@@ -253,11 +253,11 @@
|
||||
<Border Grid.Column="1">
|
||||
<ListBox
|
||||
HorizontalContentAlignment="Stretch"
|
||||
ItemsSource="{Binding SelectedGuild.Channels}"
|
||||
ItemsSource="{Binding AvailableChannels}"
|
||||
SelectionMode="Extended"
|
||||
TextSearch.TextPath="Model.Name">
|
||||
<i:Interaction.Behaviors>
|
||||
<behaviors:ChannelViewModelMultiSelectionListBoxBehavior SelectedItems="{Binding SelectedChannels}" />
|
||||
<behaviors:ChannelMultiSelectionListBoxBehavior SelectedItems="{Binding SelectedChannels}" />
|
||||
</i:Interaction.Behaviors>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
@@ -286,7 +286,7 @@
|
||||
FontSize="14">
|
||||
<Run Foreground="{DynamicResource SecondaryTextBrush}" Text="{Binding Category, Mode=OneWay}" />
|
||||
<Run Text="/" />
|
||||
<Run Foreground="{DynamicResource PrimaryTextBrush}" Text="{Binding Model.Name, Mode=OneWay}" />
|
||||
<Run Foreground="{DynamicResource PrimaryTextBrush}" Text="{Binding Name, Mode=OneWay}" />
|
||||
</TextBlock>
|
||||
|
||||
<!-- Is selected checkmark -->
|
||||
|
||||
Reference in New Issue
Block a user