mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-23 03:06:53 -04:00
Switch from DateTime to DateTimeOffset
This commit is contained in:
parent
4bfb2ec7fd
commit
6d9bc3625f
20 changed files with 122 additions and 79 deletions
|
@ -12,9 +12,11 @@ namespace DiscordChatExporter.Cli.Verbs.Options
|
|||
[Option('o', "output", Default = null, HelpText = "Output file or directory path.")]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
// HACK: CommandLineParser doesn't support DateTimeOffset
|
||||
[Option("after", Default = null, HelpText = "Limit to messages sent after this date.")]
|
||||
public DateTime? After { get; set; }
|
||||
|
||||
// HACK: CommandLineParser doesn't support DateTimeOffset
|
||||
[Option("before", Default = null, HelpText = "Limit to messages sent before this date.")]
|
||||
public DateTime? Before { get; set; }
|
||||
|
||||
|
|
|
@ -9,21 +9,21 @@ namespace DiscordChatExporter.Core.Models
|
|||
|
||||
public Channel Channel { get; }
|
||||
|
||||
public DateTime? From { get; }
|
||||
public DateTimeOffset? After { get; }
|
||||
|
||||
public DateTime? To { get; }
|
||||
public DateTimeOffset? Before { get; }
|
||||
|
||||
public IReadOnlyList<Message> Messages { get; }
|
||||
|
||||
public Mentionables Mentionables { get; }
|
||||
|
||||
public ChatLog(Guild guild, Channel channel, DateTime? from, DateTime? to,
|
||||
public ChatLog(Guild guild, Channel channel, DateTimeOffset? after, DateTimeOffset? before,
|
||||
IReadOnlyList<Message> messages, Mentionables mentionables)
|
||||
{
|
||||
Guild = guild;
|
||||
Channel = channel;
|
||||
From = from;
|
||||
To = to;
|
||||
After = after;
|
||||
Before = before;
|
||||
Messages = messages;
|
||||
Mentionables = mentionables;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace DiscordChatExporter.Core.Models
|
|||
|
||||
public string Url { get; }
|
||||
|
||||
public DateTime? Timestamp { get; }
|
||||
public DateTimeOffset? Timestamp { get; }
|
||||
|
||||
public Color Color { get; }
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace DiscordChatExporter.Core.Models
|
|||
|
||||
public EmbedFooter Footer { get; }
|
||||
|
||||
public Embed(string title, string url, DateTime? timestamp, Color color, EmbedAuthor author, string description,
|
||||
public Embed(string title, string url, DateTimeOffset? timestamp, Color color, EmbedAuthor author, string description,
|
||||
IReadOnlyList<EmbedField> fields, EmbedImage thumbnail, EmbedImage image, EmbedFooter footer)
|
||||
{
|
||||
Title = title;
|
||||
|
|
|
@ -15,9 +15,9 @@ namespace DiscordChatExporter.Core.Models
|
|||
|
||||
public User Author { get; }
|
||||
|
||||
public DateTime Timestamp { get; }
|
||||
public DateTimeOffset Timestamp { get; }
|
||||
|
||||
public DateTime? EditedTimestamp { get; }
|
||||
public DateTimeOffset? EditedTimestamp { get; }
|
||||
|
||||
public string Content { get; }
|
||||
|
||||
|
@ -29,8 +29,8 @@ namespace DiscordChatExporter.Core.Models
|
|||
|
||||
public IReadOnlyList<User> MentionedUsers { get; }
|
||||
|
||||
public Message(string id, string channelId, MessageType type, User author, DateTime timestamp,
|
||||
DateTime? editedTimestamp, string content, IReadOnlyList<Attachment> attachments,
|
||||
public Message(string id, string channelId, MessageType type, User author, DateTimeOffset timestamp,
|
||||
DateTimeOffset? editedTimestamp, string content, IReadOnlyList<Attachment> attachments,
|
||||
IReadOnlyList<Embed> embeds, IReadOnlyList<Reaction> reactions, IReadOnlyList<User> mentionedUsers)
|
||||
{
|
||||
Id = id;
|
||||
|
|
|
@ -22,7 +22,8 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
_dateFormat = dateFormat;
|
||||
}
|
||||
|
||||
private string FormatDate(DateTime date) => date.ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
private string FormatDate(DateTimeOffset date) =>
|
||||
date.ToLocalTime().ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
|
||||
private string FormatMarkdown(Node node)
|
||||
{
|
||||
|
|
|
@ -10,11 +10,11 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
{
|
||||
public User Author { get; }
|
||||
|
||||
public DateTime Timestamp { get; }
|
||||
public DateTimeOffset Timestamp { get; }
|
||||
|
||||
public IReadOnlyList<Message> Messages { get; }
|
||||
|
||||
public MessageGroup(User author, DateTime timestamp, IReadOnlyList<Message> messages)
|
||||
public MessageGroup(User author, DateTimeOffset timestamp, IReadOnlyList<Message> messages)
|
||||
{
|
||||
Author = author;
|
||||
Timestamp = timestamp;
|
||||
|
|
|
@ -29,7 +29,8 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
|
||||
private string HtmlEncode(string s) => WebUtility.HtmlEncode(s);
|
||||
|
||||
private string FormatDate(DateTime date) => date.ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
private string FormatDate(DateTimeOffset date) =>
|
||||
date.ToLocalTime().ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
|
||||
private IEnumerable<MessageGroup> GroupMessages(IEnumerable<Message> messages) =>
|
||||
messages.GroupContiguous((buffer, message) =>
|
||||
|
@ -182,7 +183,7 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
var model = new ScriptObject();
|
||||
model.SetValue("Model", _chatLog, true);
|
||||
model.Import(nameof(GroupMessages), new Func<IEnumerable<Message>, IEnumerable<MessageGroup>>(GroupMessages));
|
||||
model.Import(nameof(FormatDate), new Func<DateTime, string>(FormatDate));
|
||||
model.Import(nameof(FormatDate), new Func<DateTimeOffset, string>(FormatDate));
|
||||
model.Import(nameof(FormatMarkdown), new Func<string, string>(FormatMarkdown));
|
||||
context.PushGlobal(model);
|
||||
|
||||
|
|
|
@ -22,21 +22,22 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
_dateFormat = dateFormat;
|
||||
}
|
||||
|
||||
private string FormatDate(DateTime date) => date.ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
private string FormatDate(DateTimeOffset date) =>
|
||||
date.ToLocalTime().ToString(_dateFormat, CultureInfo.InvariantCulture);
|
||||
|
||||
private string FormatDateRange(DateTime? from, DateTime? to)
|
||||
private string FormatDateRange(DateTimeOffset? after, DateTimeOffset? before)
|
||||
{
|
||||
// Both 'from' and 'to'
|
||||
if (from.HasValue && to.HasValue)
|
||||
return $"{FormatDate(from.Value)} to {FormatDate(to.Value)}";
|
||||
// Both 'after' and 'before'
|
||||
if (after != null && before != null)
|
||||
return $"{FormatDate(after.Value)} to {FormatDate(before.Value)}";
|
||||
|
||||
// Just 'from'
|
||||
if (from.HasValue)
|
||||
return $"after {FormatDate(from.Value)}";
|
||||
// Just 'after'
|
||||
if (after != null)
|
||||
return $"after {FormatDate(after.Value)}";
|
||||
|
||||
// Just 'to'
|
||||
if (to.HasValue)
|
||||
return $"before {FormatDate(to.Value)}";
|
||||
// Just 'before'
|
||||
if (before != null)
|
||||
return $"before {FormatDate(before.Value)}";
|
||||
|
||||
// Neither
|
||||
return null;
|
||||
|
@ -113,7 +114,7 @@ namespace DiscordChatExporter.Core.Rendering
|
|||
await writer.WriteLineAsync($"Channel: {_chatLog.Channel.Name}");
|
||||
await writer.WriteLineAsync($"Topic: {_chatLog.Channel.Topic}");
|
||||
await writer.WriteLineAsync($"Messages: {_chatLog.Messages.Count:N0}");
|
||||
await writer.WriteLineAsync($"Range: {FormatDateRange(_chatLog.From, _chatLog.To)}");
|
||||
await writer.WriteLineAsync($"Range: {FormatDateRange(_chatLog.After, _chatLog.Before)}");
|
||||
await writer.WriteLineAsync('='.Repeat(62));
|
||||
await writer.WriteLineAsync();
|
||||
|
||||
|
|
|
@ -43,14 +43,14 @@
|
|||
|
||||
<div class="info__channel-message-count">{{ Model.Messages | array.size | object.format "N0" }} messages</div>
|
||||
|
||||
{{~ if Model.From || Model.To ~}}
|
||||
{{~ if Model.After || Model.Before ~}}
|
||||
<div class="info__channel-date-range">
|
||||
{{~ if Model.From && Model.To ~}}
|
||||
Between {{ Model.From | FormatDate | html.escape }} and {{ Model.To | FormatDate | html.escape }}
|
||||
{{~ else if Model.From ~}}
|
||||
After {{ Model.From | FormatDate | html.escape }}
|
||||
{{~ else if Model.To ~}}
|
||||
Before {{ Model.To | FormatDate | html.escape }}
|
||||
{{~ if Model.After && Model.Before ~}}
|
||||
Between {{ Model.After | FormatDate | html.escape }} and {{ Model.Before | FormatDate | html.escape }}
|
||||
{{~ else if Model.After ~}}
|
||||
After {{ Model.After | FormatDate | html.escape }}
|
||||
{{~ else if Model.Before ~}}
|
||||
Before {{ Model.Before | FormatDate | html.escape }}
|
||||
{{~ end ~}}
|
||||
</div>
|
||||
{{~ end ~}}
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace DiscordChatExporter.Core.Services
|
|||
var title = json["title"]?.Value<string>();
|
||||
var description = json["description"]?.Value<string>();
|
||||
var url = json["url"]?.Value<string>();
|
||||
var timestamp = json["timestamp"]?.Value<DateTime>();
|
||||
var timestamp = json["timestamp"]?.Value<DateTimeOffset>();
|
||||
|
||||
// Get color
|
||||
var color = json["color"] != null
|
||||
|
@ -164,8 +164,8 @@ namespace DiscordChatExporter.Core.Services
|
|||
// Get basic data
|
||||
var id = json["id"].Value<string>();
|
||||
var channelId = json["channel_id"].Value<string>();
|
||||
var timestamp = json["timestamp"].Value<DateTime>();
|
||||
var editedTimestamp = json["edited_timestamp"]?.Value<DateTime?>();
|
||||
var timestamp = json["timestamp"].Value<DateTimeOffset>();
|
||||
var editedTimestamp = json["edited_timestamp"]?.Value<DateTimeOffset?>();
|
||||
var content = json["content"].Value<string>();
|
||||
var type = (MessageType) json["type"].Value<int>();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
|
@ -8,6 +9,7 @@ using DiscordChatExporter.Core.Models;
|
|||
using DiscordChatExporter.Core.Services.Exceptions;
|
||||
using DiscordChatExporter.Core.Services.Internal;
|
||||
using Failsafe;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Tyrrrz.Extensions;
|
||||
|
||||
|
@ -64,7 +66,12 @@ namespace DiscordChatExporter.Core.Services
|
|||
var raw = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Parse
|
||||
return JToken.Parse(raw);
|
||||
using (var reader = new JsonTextReader(new StringReader(raw)))
|
||||
{
|
||||
reader.DateParseHandling = DateParseHandling.DateTimeOffset;
|
||||
|
||||
return JToken.Load(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -123,24 +130,24 @@ namespace DiscordChatExporter.Core.Services
|
|||
}
|
||||
|
||||
public async Task<IReadOnlyList<Message>> GetChannelMessagesAsync(AuthToken token, string channelId,
|
||||
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
|
||||
{
|
||||
var result = new List<Message>();
|
||||
|
||||
// Get the last message
|
||||
var response = await GetApiResponseAsync(token, "channels", $"{channelId}/messages",
|
||||
"limit=1", $"before={to?.ToSnowflake()}");
|
||||
"limit=1", $"before={before?.ToSnowflake()}");
|
||||
var lastMessage = response.Select(ParseMessage).FirstOrDefault();
|
||||
|
||||
// If the last message doesn't exist or it's outside of range - return
|
||||
if (lastMessage == null || lastMessage.Timestamp < from)
|
||||
if (lastMessage == null || lastMessage.Timestamp < after)
|
||||
{
|
||||
progress?.Report(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get other messages
|
||||
var offsetId = from?.ToSnowflake() ?? "0";
|
||||
var offsetId = after?.ToSnowflake() ?? "0";
|
||||
while (true)
|
||||
{
|
||||
// Get message batch
|
||||
|
@ -215,19 +222,19 @@ namespace DiscordChatExporter.Core.Services
|
|||
}
|
||||
|
||||
public async Task<ChatLog> GetChatLogAsync(AuthToken token, Guild guild, Channel channel,
|
||||
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
|
||||
{
|
||||
// Get messages
|
||||
var messages = await GetChannelMessagesAsync(token, channel.Id, from, to, progress);
|
||||
var messages = await GetChannelMessagesAsync(token, channel.Id, after, before, progress);
|
||||
|
||||
// Get mentionables
|
||||
var mentionables = await GetMentionablesAsync(token, guild.Id, messages);
|
||||
|
||||
return new ChatLog(guild, channel, from, to, messages, mentionables);
|
||||
return new ChatLog(guild, channel, after, before, messages, mentionables);
|
||||
}
|
||||
|
||||
public async Task<ChatLog> GetChatLogAsync(AuthToken token, Channel channel,
|
||||
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
|
||||
{
|
||||
// Get guild
|
||||
var guild = channel.GuildId == Guild.DirectMessages.Id
|
||||
|
@ -235,17 +242,17 @@ namespace DiscordChatExporter.Core.Services
|
|||
: await GetGuildAsync(token, channel.GuildId);
|
||||
|
||||
// Get the chat log
|
||||
return await GetChatLogAsync(token, guild, channel, from, to, progress);
|
||||
return await GetChatLogAsync(token, guild, channel, after, before, progress);
|
||||
}
|
||||
|
||||
public async Task<ChatLog> GetChatLogAsync(AuthToken token, string channelId,
|
||||
DateTime? from = null, DateTime? to = null, IProgress<double> progress = null)
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null, IProgress<double> progress = null)
|
||||
{
|
||||
// Get channel
|
||||
var channel = await GetChannelAsync(token, channelId);
|
||||
|
||||
// Get the chat log
|
||||
return await GetChatLogAsync(token, channel, from, to, progress);
|
||||
return await GetChatLogAsync(token, channel, after, before, progress);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace DiscordChatExporter.Core.Services
|
|||
{
|
||||
// Create partitions by grouping up to X contiguous messages into separate chat logs
|
||||
var partitions = chatLog.Messages.GroupContiguous(g => g.Count < partitionLimit.Value)
|
||||
.Select(g => new ChatLog(chatLog.Guild, chatLog.Channel, chatLog.From, chatLog.To, g, chatLog.Mentionables))
|
||||
.Select(g => new ChatLog(chatLog.Guild, chatLog.Channel, chatLog.After, chatLog.Before, g, chatLog.Mentionables))
|
||||
.ToArray();
|
||||
|
||||
// Split file path into components
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace DiscordChatExporter.Core.Services.Helpers
|
|||
Path.GetExtension(path) == null;
|
||||
|
||||
public static string GetDefaultExportFileName(ExportFormat format, Guild guild, Channel channel,
|
||||
DateTime? from = null, DateTime? to = null)
|
||||
DateTimeOffset? after = null, DateTimeOffset? before = null)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
|
||||
|
@ -22,24 +22,24 @@ namespace DiscordChatExporter.Core.Services.Helpers
|
|||
result.Append($"{guild.Name} - {channel.Name} [{channel.Id}]");
|
||||
|
||||
// Append date range
|
||||
if (from != null || to != null)
|
||||
if (after != null || before != null)
|
||||
{
|
||||
result.Append(" (");
|
||||
|
||||
// Both 'from' and 'to' are set
|
||||
if (from != null && to != null)
|
||||
// Both 'after' and 'before' are set
|
||||
if (after != null && before != null)
|
||||
{
|
||||
result.Append($"{from:yyyy-MM-dd} to {to:yyyy-MM-dd}");
|
||||
result.Append($"{after:yyyy-MM-dd} to {before:yyyy-MM-dd}");
|
||||
}
|
||||
// Only 'from' is set
|
||||
else if (from != null)
|
||||
// Only 'after' is set
|
||||
else if (after != null)
|
||||
{
|
||||
result.Append($"after {from:yyyy-MM-dd}");
|
||||
result.Append($"after {after:yyyy-MM-dd}");
|
||||
}
|
||||
// Only 'to' is set
|
||||
// Only 'before' is set
|
||||
else
|
||||
{
|
||||
result.Append($"before {to:yyyy-MM-dd}");
|
||||
result.Append($"before {before:yyyy-MM-dd}");
|
||||
}
|
||||
|
||||
result.Append(")");
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace DiscordChatExporter.Core.Services.Internal
|
|||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static string ToSnowflake(this DateTime dateTime)
|
||||
public static string ToSnowflake(this DateTimeOffset date)
|
||||
{
|
||||
const long epoch = 62135596800000;
|
||||
var unixTime = dateTime.ToUniversalTime().Ticks / TimeSpan.TicksPerMillisecond - epoch;
|
||||
var unixTime = date.ToUniversalTime().Ticks / TimeSpan.TicksPerMillisecond - epoch;
|
||||
var value = ((ulong) unixTime - 1420070400000UL) << 22;
|
||||
return value.ToString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Converters
|
||||
{
|
||||
[ValueConversion(typeof(DateTimeOffset), typeof(DateTime))]
|
||||
public class DateTimeOffsetToDateTimeConverter : IValueConverter
|
||||
{
|
||||
public static DateTimeOffsetToDateTimeConverter Instance { get; } = new DateTimeOffsetToDateTimeConverter();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is DateTimeOffset date)
|
||||
return date.DateTime;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is DateTime date)
|
||||
return new DateTimeOffset(date);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,8 +12,10 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var format = value as ExportFormat?;
|
||||
return format?.GetDisplayName();
|
||||
if (value is ExportFormat format)
|
||||
return format.GetDisplayName();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
<Compile Include="Behaviors\ChannelViewModelMultiSelectionListBoxBehavior.cs" />
|
||||
<Compile Include="Behaviors\MultiSelectionListBoxBehavior.cs" />
|
||||
<Compile Include="Bootstrapper.cs" />
|
||||
<Compile Include="Converters\DateTimeOffsetToDateTimeConverter.cs" />
|
||||
<Compile Include="Converters\ExportFormatToStringConverter.cs" />
|
||||
<Compile Include="ViewModels\Components\ChannelViewModel.cs" />
|
||||
<Compile Include="ViewModels\Components\GuildViewModel.cs" />
|
||||
|
|
|
@ -27,9 +27,9 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
|
||||
public ExportFormat SelectedFormat { get; set; } = ExportFormat.HtmlDark;
|
||||
|
||||
public DateTime? From { get; set; }
|
||||
public DateTimeOffset? After { get; set; }
|
||||
|
||||
public DateTime? To { get; set; }
|
||||
public DateTimeOffset? Before { get; set; }
|
||||
|
||||
public int? PartitionLimit { get; set; }
|
||||
|
||||
|
@ -54,11 +54,11 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
_settingsService.LastExportFormat = SelectedFormat;
|
||||
_settingsService.LastPartitionLimit = PartitionLimit;
|
||||
|
||||
// Clamp 'from' and 'to' values
|
||||
if (From > To)
|
||||
From = To;
|
||||
if (To < From)
|
||||
To = From;
|
||||
// Clamp 'after' and 'before' values
|
||||
if (After > Before)
|
||||
After = Before;
|
||||
if (Before < After)
|
||||
Before = After;
|
||||
|
||||
// If single channel - prompt file path
|
||||
if (IsSingleChannel)
|
||||
|
@ -67,7 +67,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
var channel = Channels.Single();
|
||||
|
||||
// Generate default file name
|
||||
var defaultFileName = ExportHelper.GetDefaultExportFileName(SelectedFormat, Guild, channel, From, To);
|
||||
var defaultFileName = ExportHelper.GetDefaultExportFileName(SelectedFormat, Guild, channel, After, Before);
|
||||
|
||||
// Generate filter
|
||||
var ext = SelectedFormat.GetFileExtension();
|
||||
|
|
|
@ -267,7 +267,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
{
|
||||
// Generate default file name
|
||||
var fileName = ExportHelper.GetDefaultExportFileName(dialog.SelectedFormat, dialog.Guild,
|
||||
channel, dialog.From, dialog.To);
|
||||
channel, dialog.After, dialog.Before);
|
||||
|
||||
// Combine paths
|
||||
filePath = Path.Combine(filePath, fileName);
|
||||
|
@ -275,7 +275,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
|
||||
// Get chat log
|
||||
var chatLog = await _dataService.GetChatLogAsync(token, dialog.Guild, channel,
|
||||
dialog.From, dialog.To, operation);
|
||||
dialog.After, dialog.Before, operation);
|
||||
|
||||
// Export
|
||||
await _exportService.ExportChatLogAsync(chatLog, filePath, dialog.SelectedFormat,
|
||||
|
|
|
@ -86,8 +86,8 @@
|
|||
Margin="16,8"
|
||||
materialDesign:HintAssist.Hint="From (optional)"
|
||||
materialDesign:HintAssist.IsFloating="True"
|
||||
DisplayDateEnd="{Binding To}"
|
||||
SelectedDate="{Binding From}"
|
||||
DisplayDateEnd="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
SelectedDate="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
ToolTip="If this is set, only messages sent after this date will be exported" />
|
||||
<DatePicker
|
||||
Grid.Row="0"
|
||||
|
@ -95,8 +95,8 @@
|
|||
Margin="16,8"
|
||||
materialDesign:HintAssist.Hint="To (optional)"
|
||||
materialDesign:HintAssist.IsFloating="True"
|
||||
DisplayDateStart="{Binding From}"
|
||||
SelectedDate="{Binding To}"
|
||||
DisplayDateStart="{Binding After, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
SelectedDate="{Binding Before, Converter={x:Static converters:DateTimeOffsetToDateTimeConverter.Instance}}"
|
||||
ToolTip="If this is set, only messages sent before this date will be exported" />
|
||||
</Grid>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue