Skip to content
This repository was archived by the owner on Apr 30, 2024. It is now read-only.

Commit

Permalink
WIP Loading older messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Avid29 committed May 10, 2022
1 parent 4387fa6 commit ae1b666
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 22 deletions.
3 changes: 3 additions & 0 deletions src/API/Discord.API/Rest/IChannelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ internal interface IChannelService
[Get("/v9/channels/{channelId}/messages?limit={limit}")]
Task<JsonMessage[]> GetChannelMessages([AliasAs("channelId")] ulong channelId, [AliasAs("limit")] int limit = 50);

[Get("/v9/channels/{channelId}/messages?limit={limit}&before={before}")]
Task<JsonMessage[]> GetChannelMessagesBefore([AliasAs("channelId")] ulong channelId, [AliasAs("before")] ulong before, [AliasAs("limit")] int limit = 50);

[Post("/v9/channels/{channelId}/messages")]
Task<JsonMessage> CreateMessage([AliasAs("channelId")] ulong channelId, [Body] JsonMessageUpsert message);
}
Expand Down
12 changes: 10 additions & 2 deletions src/Quarrel.Client/QuarrelClient.Methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,19 @@ public partial class QuarrelClient
/// Gets messages in a channel.
/// </summary>
/// <param name="channelId">The channel's id.</param>
public async Task<Message[]> GetMessagesAsync(ulong channelId, ulong? guildId = null)
/// <param name="guildId">The id of the guild the channel belongs to.</param>
/// <param name="beforeId">The message to get the messages from before.</param>
public async Task<Message[]> GetMessagesAsync(ulong channelId, ulong? guildId = null, ulong? beforeId = null)
{
Guard.IsNotNull(_channelService, nameof(_channelService));

JsonMessage[]? jsonMessages = await MakeRefitRequest(() => _channelService.GetChannelMessages(channelId));
Func<Task<JsonMessage[]>> request = () => _channelService.GetChannelMessages(channelId);
if (beforeId.HasValue)
{
request = () => _channelService.GetChannelMessagesBefore(channelId, beforeId.Value);
}

JsonMessage[]? jsonMessages = await MakeRefitRequest(request);
Guard.IsNotNull(jsonMessages, nameof(jsonMessages));

Message[] messages = new Message[jsonMessages.Length];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ public BindableGuildFolder[] GetMyGuildFolders()
}

/// <inheritdoc/>
public async Task<Message[]> GetChannelMessagesAsync(IBindableMessageChannel channel)
public async Task<Message[]> GetChannelMessagesAsync(IBindableMessageChannel channel, ulong? beforeId = null)
{
var rawMessages = await _quarrelClient.GetMessagesAsync(channel.Id, channel.GuildId);
var rawMessages = await _quarrelClient.GetMessagesAsync(channel.Id, channel.GuildId, beforeId);
Guard.IsNotNull(rawMessages, nameof(rawMessages));
return rawMessages;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Quarrel.ViewModels/Services/Discord/IDiscordService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ public interface IDiscordService
/// </remarks>
/// <returns>The array of <see cref="BindableGuildFolder"/>s that the current user has.</returns>
BindableGuildFolder[] GetMyGuildFolders();

/// <summary>
/// Gets the messages in a channel.
/// </summary>
/// <param name="channel">The channel to get the messages for.</param>
/// <param name="beforeId">The if of the last message to load messages before, or null.</param>
/// <returns>An array of <see cref="BindableMessage"/>s from the channel.</returns>
Task<Message[]> GetChannelMessagesAsync(IBindableMessageChannel channel);
Task<Message[]> GetChannelMessagesAsync(IBindableMessageChannel channel, ulong? beforeId = null);

/// <summary>
/// Gets the channels in a guild.
Expand Down
56 changes: 41 additions & 15 deletions src/Quarrel.ViewModels/ViewModels/Panels/MessagesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,25 @@ public bool IsLoading
private set => SetProperty(ref _isLoading, value);
}

private void LoadChannel()
/// <remarks>
/// Must be called on the UI thread.
/// </remarks>
public async void LoadOlderMessages()
{
if (SelectedChannel is IBindableMessageChannel)
{
LoadInitialMessages();
}
if (Source.Count == 0) return;

ulong beforeId = Source[0].Message.Id;
IBindableMessageChannel? channel = SelectedChannel as IBindableMessageChannel;
Guard.IsNotNull(channel, nameof(channel));

// Load messages
IsLoading = true;
var messages = await _discordService.GetChannelMessagesAsync(channel, beforeId);
var bindableMessages = ParseMessages(messages);

// Add messages to the UI and mark loading as finished
Source.InsertRange(0, bindableMessages);
IsLoading = false;
}

/// <remarks>
Expand All @@ -89,25 +102,38 @@ private async void LoadInitialMessages()
Guard.IsNotNull(channel, nameof(channel));
// Clear the messages and begin loading
Source.Clear();
IsLoading = true;

// Load messages
IsLoading = true;
var messages = await _discordService.GetChannelMessagesAsync(channel);
BindableMessage[] bindableMessages = new BindableMessage[messages.Length];
if (bindableMessages.Length > 0)
{
bindableMessages[0] = new BindableMessage(_messenger, _discordService, _dispatcherService, messages[messages.Length - 1]);
for (int i = 1; i < messages.Length; i++)
{
bindableMessages[i] = new BindableMessage(_messenger, _discordService, _dispatcherService, messages[messages.Length - 1 - i], messages[messages.Length - i]);
}
}
var bindableMessages = ParseMessages(messages);

// Add messages to the UI and mark loading as finished
Source.AddRange(bindableMessages);
IsLoading = false;
}

private void LoadChannel()
{
if (SelectedChannel is IBindableMessageChannel)
{
LoadInitialMessages();
}
}

private BindableMessage[] ParseMessages(Message[] messages)
{
BindableMessage[] bindableMessages = new BindableMessage[messages.Length];
if (bindableMessages.Length == 0) return bindableMessages;

bindableMessages[0] = new BindableMessage(_messenger, _discordService, _dispatcherService, messages[messages.Length - 1]);
for (int i = 1; i < messages.Length; i++)
{
bindableMessages[i] = new BindableMessage(_messenger, _discordService, _dispatcherService, messages[messages.Length - 1 - i], messages[messages.Length - i]);
}
return bindableMessages;
}

/// <remarks>
/// Must be called on the UI thread.
/// </remarks>
Expand Down
5 changes: 4 additions & 1 deletion src/Quarrel/Controls/Panels/Messages/MessagePanel.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ private void OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
var viewer = (ScrollViewer)sender;
if (viewer.VerticalOffset <= ScrollPadding)
{
// TODO: Scrolled to top
if (!ViewModel.IsLoading)
{
ViewModel.LoadOlderMessages();
}
}
else if (viewer.VerticalOffset >= viewer.ScrollableHeight - ScrollPadding)
{
Expand Down

0 comments on commit ae1b666

Please sign in to comment.