In the case where a thread is archived upon login, the thread channel is not cached by the client. When the thread channel is unarchived, the library simply outputs an unknown channel warning. When messages are sent in the unarchived thread, the library won't have it cached and will only output warnings. This change makes it so the channel is cached when unarchived and ThreadUpdated is invoked with an non specified "before" parameter. From that point, the channel will be available for future events.pull/1923/head
@@ -603,13 +603,13 @@ namespace Discord.WebSocket | |||||
/// <summary> | /// <summary> | ||||
/// Fired when a thread is updated within a guild. | /// Fired when a thread is updated within a guild. | ||||
/// </summary> | /// </summary> | ||||
public event Func<SocketThreadChannel, SocketThreadChannel, Task> ThreadUpdated | |||||
public event Func<Cacheable<SocketThreadChannel, ulong>, SocketThreadChannel, Task> ThreadUpdated | |||||
{ | { | ||||
add { _threadUpdated.Add(value); } | add { _threadUpdated.Add(value); } | ||||
remove { _threadUpdated.Remove(value); } | remove { _threadUpdated.Remove(value); } | ||||
} | } | ||||
internal readonly AsyncEvent<Func<SocketThreadChannel, SocketThreadChannel, Task>> _threadUpdated = new AsyncEvent<Func<SocketThreadChannel, SocketThreadChannel, Task>>(); | |||||
internal readonly AsyncEvent<Func<Cacheable<SocketThreadChannel, ulong>, SocketThreadChannel, Task>> _threadUpdated = new(); | |||||
/// <summary> | /// <summary> | ||||
/// Fired when a thread is deleted. | /// Fired when a thread is deleted. | ||||
@@ -2243,16 +2243,25 @@ namespace Discord.WebSocket | |||||
return; | return; | ||||
} | } | ||||
var channel = (SocketThreadChannel)guild.GetChannel(data.Id); | |||||
var threadChannel = guild.ThreadChannels.FirstOrDefault(x => x.Id == data.Id); | |||||
var before = threadChannel != null | |||||
? new Cacheable<SocketThreadChannel, ulong>(threadChannel.Clone(), data.Id, true, () => Task.FromResult((SocketThreadChannel)null)) | |||||
: new Cacheable<SocketThreadChannel, ulong>(null, data.Id, false, () => Task.FromResult((SocketThreadChannel)null)); | |||||
if (channel == null) | |||||
if (threadChannel != null) | |||||
{ | { | ||||
await UnknownChannelAsync(type, data.Id); | |||||
return; | |||||
} | |||||
threadChannel.Update(State, data); | |||||
var before = channel.Clone(); | |||||
channel.Update(State, data); | |||||
if (data.ThreadMember.IsSpecified) | |||||
threadChannel.AddOrUpdateThreadMember(data.ThreadMember.Value, guild.CurrentUser); | |||||
} | |||||
else | |||||
{ | |||||
// Thread is updated but was not cached, likely meaning the thread was unarchived. | |||||
threadChannel = (SocketThreadChannel)guild.AddChannel(State, data); | |||||
if (data.ThreadMember.IsSpecified) | |||||
threadChannel.AddOrUpdateThreadMember(data.ThreadMember.Value, guild.CurrentUser); | |||||
} | |||||
if (!(guild?.IsSynced ?? true)) | if (!(guild?.IsSynced ?? true)) | ||||
{ | { | ||||
@@ -2260,7 +2269,7 @@ namespace Discord.WebSocket | |||||
return; | return; | ||||
} | } | ||||
await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, channel).ConfigureAwait(false); | |||||
await TimedInvokeAsync(_threadUpdated, nameof(ThreadUpdated), before, threadChannel).ConfigureAwait(false); | |||||
} | } | ||||
break; | break; | ||||
case "THREAD_DELETE": | case "THREAD_DELETE": | ||||