diff --git a/src/Clients/ChannelClient.Crud.cs b/src/Clients/ChannelClient.Crud.cs index 870444b9..7a7b2e48 100644 --- a/src/Clients/ChannelClient.Crud.cs +++ b/src/Clients/ChannelClient.Crud.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; using StreamChat.Rest; @@ -22,82 +23,106 @@ public async Task GetOrCreateAsync(string channelType, strin }, }); + public async Task GetOrCreateAsync(string channelType, string channelId, string createdBy, + string[] members, CancellationToken cancellationToken = default) + => await GetOrCreateAsync(channelType, + channelId, + new ChannelGetRequest + { + Data = new ChannelRequest + { + CreatedBy = new UserRequest { Id = createdBy }, + Members = members.Select(x => new ChannelMember { UserId = x }), + }, + }, + cancellationToken: cancellationToken); + public async Task GetOrCreateAsync(string channelType, string channelId, - ChannelGetRequest channelRequest) + ChannelGetRequest channelRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}/query", HttpMethod.POST, HttpStatusCode.Created, - channelRequest); + channelRequest, + cancellationToken: cancellationToken); - public async Task GetOrCreateAsync(string channelType, ChannelGetRequest channelRequest) + public async Task GetOrCreateAsync(string channelType, ChannelGetRequest channelRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/query", HttpMethod.POST, HttpStatusCode.Created, - channelRequest); + channelRequest, + cancellationToken: cancellationToken); public async Task UpdateAsync(string channelType, string channelId, - ChannelUpdateRequest updateRequest) + ChannelUpdateRequest updateRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, - updateRequest); + updateRequest, + cancellationToken: cancellationToken); public async Task PartialUpdateAsync(string channelType, string channelId, - PartialUpdateChannelRequest partialUpdateChannelRequest) + PartialUpdateChannelRequest partialUpdateChannelRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.PATCH, HttpStatusCode.OK, - partialUpdateChannelRequest); + partialUpdateChannelRequest, + cancellationToken: cancellationToken); - public async Task DeleteAsync(string channelType, string channelId) + public async Task DeleteAsync(string channelType, string channelId, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.DELETE, - HttpStatusCode.OK); + HttpStatusCode.OK, + cancellationToken: cancellationToken); - public async Task TruncateAsync(string channelType, string channelId) - => await TruncateAsync(channelType, channelId, null); + public async Task TruncateAsync(string channelType, string channelId, CancellationToken cancellationToken = default) + => await TruncateAsync(channelType, channelId, null, cancellationToken); public async Task TruncateAsync(string channelType, string channelId, - TruncateOptions truncateOptions) + TruncateOptions truncateOptions, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}/truncate", HttpMethod.POST, HttpStatusCode.Created, - truncateOptions); + truncateOptions, + cancellationToken: cancellationToken); - public Task PinAsync(string channelType, string channelId, string userId) + public Task PinAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => UpdateMemberPartialAsync(channelType, channelId, new ChannelMemberPartialRequest { - UserId = userId, Set = new Dictionary() + UserId = userId, + Set = new Dictionary() { { "pinned", true }, }, - }); + }, cancellationToken); - public Task UnpinAsync(string channelType, string channelId, string userId) + public Task UnpinAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => UpdateMemberPartialAsync(channelType, channelId, new ChannelMemberPartialRequest { - UserId = userId, Set = new Dictionary() + UserId = userId, + Set = new Dictionary() { { "pinned", false }, }, - }); + }, cancellationToken); - public Task ArchiveAsync(string channelType, string channelId, string userId) + public Task ArchiveAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => UpdateMemberPartialAsync(channelType, channelId, new ChannelMemberPartialRequest { - UserId = userId, Set = new Dictionary() + UserId = userId, + Set = new Dictionary() { { "archived", true }, }, - }); + }, cancellationToken); - public Task UnarchiveAsync(string channelType, string channelId, string userId) + public Task UnarchiveAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => UpdateMemberPartialAsync(channelType, channelId, new ChannelMemberPartialRequest { - UserId = userId, Set = new Dictionary() + UserId = userId, + Set = new Dictionary() { { "archived", false }, }, - }); + }, cancellationToken); } } \ No newline at end of file diff --git a/src/Clients/ChannelClient.FilterTags.cs b/src/Clients/ChannelClient.FilterTags.cs index ce1a5fc3..6a083a78 100644 --- a/src/Clients/ChannelClient.FilterTags.cs +++ b/src/Clients/ChannelClient.FilterTags.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; using StreamChat.Rest; @@ -21,7 +22,7 @@ public Task AddFilterTagsAsync(string channelType, string /// Adds filter tags to the channel. /// public async Task AddFilterTagsAsync(string channelType, string channelId, - IEnumerable filterTags, MessageRequest msg = null) => await ExecuteRequestAsync( + IEnumerable filterTags, MessageRequest msg = null, CancellationToken cancellationToken = default) => await ExecuteRequestAsync( $"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, @@ -41,7 +42,8 @@ public Task RemoveFilterTagsAsync(string channelType, string channe /// Removes filter tags from the channel. /// public async Task RemoveFilterTagsAsync(string channelType, string channelId, - IEnumerable filterTags, MessageRequest msg = null) => await ExecuteRequestAsync( + IEnumerable filterTags, MessageRequest msg = null, + CancellationToken cancellationToken = default) => await ExecuteRequestAsync( $"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, @@ -49,6 +51,7 @@ public async Task RemoveFilterTagsAsync(string channelType, string { RemoveFilterTags = filterTags, Message = msg, - }); + }, + cancellationToken: cancellationToken); } } diff --git a/src/Clients/ChannelClient.Members.cs b/src/Clients/ChannelClient.Members.cs index 2e60c0c2..abc9f341 100644 --- a/src/Clients/ChannelClient.Members.cs +++ b/src/Clients/ChannelClient.Members.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; using StreamChat.Rest; @@ -11,7 +12,10 @@ public partial class ChannelClient public async Task AddMembersAsync(string channelType, string channelId, params string[] userIds) => await AddMembersAsync(channelType, channelId, userIds, null, null); - public async Task AddMembersAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg, AddMemberOptions options) + public async Task AddMembersAsync(string channelType, string channelId, string[] userIds, CancellationToken cancellationToken = default) + => await AddMembersAsync(channelType, channelId, userIds, null, null, cancellationToken); + + public async Task AddMembersAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg, AddMemberOptions options, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, @@ -21,9 +25,10 @@ public async Task AddMembersAsync(string channelType, str HideHistory = options?.HideHistory, HideHistoryBefore = options?.HideHistoryBefore, Message = msg, - }); + }, + cancellationToken: cancellationToken); - public async Task RemoveMembersAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg = null) + public async Task RemoveMembersAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg = null, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, @@ -31,51 +36,55 @@ public async Task RemoveMembersAsync(string channelType, string cha { RemoveMembers = userIds, Message = msg, - }); + }, + cancellationToken: cancellationToken); - public async Task UpdateMemberPartialAsync(string channelType, string channelId, ChannelMemberPartialRequest channelMemberPartialRequest) + public async Task UpdateMemberPartialAsync(string channelType, string channelId, ChannelMemberPartialRequest channelMemberPartialRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}/member/{channelMemberPartialRequest.UserId}", HttpMethod.PATCH, HttpStatusCode.OK, - channelMemberPartialRequest); + channelMemberPartialRequest, + cancellationToken: cancellationToken); - public async Task QueryMembersAsync(QueryMembersRequest queryMembersRequest) + public async Task QueryMembersAsync(QueryMembersRequest queryMembersRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("members", HttpMethod.GET, HttpStatusCode.OK, - queryParams: queryMembersRequest.ToQueryParameters()); + queryParams: queryMembersRequest.ToQueryParameters(), + cancellationToken: cancellationToken); - public async Task AssignRolesAsync(string channelType, string channelId, AssignRoleRequest roleRequest) + public async Task AssignRolesAsync(string channelType, string channelId, AssignRoleRequest roleRequest, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, - roleRequest); + roleRequest, + cancellationToken: cancellationToken); - public async Task InviteAsync(string channelType, string channelId, string userId, MessageRequest msg = null) - => await InviteAsync(channelType, channelId, new[] { userId }, msg); + public async Task InviteAsync(string channelType, string channelId, string userId, MessageRequest msg = null, CancellationToken cancellationToken = default) + => await InviteAsync(channelType, channelId, new[] { userId }, msg, cancellationToken); - public async Task InviteAsync(string channelType, string channelId, IEnumerable userIds) - => await InviteAsync(channelType, channelId, userIds, null); + public async Task InviteAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default) + => await InviteAsync(channelType, channelId, userIds, null, cancellationToken); - public async Task InviteAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg = null) + public async Task InviteAsync(string channelType, string channelId, IEnumerable userIds, MessageRequest msg = null, CancellationToken cancellationToken = default) => await UpdateAsync(channelType, channelId, new ChannelUpdateRequest { Invites = userIds, Message = msg, - }); + }, cancellationToken); - public async Task AcceptInviteAsync(string channelType, string channelId, string userId) + public async Task AcceptInviteAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => await UpdateAsync(channelType, channelId, new ChannelUpdateRequest { AcceptInvite = true, UserId = userId, - }); + }, cancellationToken); - public async Task RejectInviteAsync(string channelType, string channelId, string userId) + public async Task RejectInviteAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => await UpdateAsync(channelType, channelId, new ChannelUpdateRequest { RejectInvite = true, UserId = userId, - }); + }, cancellationToken); } } \ No newline at end of file diff --git a/src/Clients/ChannelClient.Moderation.cs b/src/Clients/ChannelClient.Moderation.cs index d4956abe..c681dbf8 100644 --- a/src/Clients/ChannelClient.Moderation.cs +++ b/src/Clients/ChannelClient.Moderation.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; using StreamChat.Rest; @@ -8,28 +9,32 @@ namespace StreamChat.Clients { public partial class ChannelClient { - public async Task AddModeratorsAsync(string channelType, string channelId, IEnumerable userIds) + public async Task AddModeratorsAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, - new { add_moderators = userIds }); + new { add_moderators = userIds }, + cancellationToken: cancellationToken); - public async Task DemoteModeratorsAsync(string channelType, string channelId, IEnumerable userIds) + public async Task DemoteModeratorsAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}", HttpMethod.POST, HttpStatusCode.Created, - new { demote_moderators = userIds }); + new { demote_moderators = userIds }, + cancellationToken: cancellationToken); - public async Task MuteChannelAsync(ChannelMuteRequest request) + public async Task MuteChannelAsync(ChannelMuteRequest request, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("moderation/mute/channel", HttpMethod.POST, HttpStatusCode.Created, - request); + request, + cancellationToken: cancellationToken); - public async Task UnmuteChannelAsync(ChannelUnmuteRequest request) + public async Task UnmuteChannelAsync(ChannelUnmuteRequest request, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("moderation/unmute/channel", HttpMethod.POST, HttpStatusCode.Created, - request); + request, + cancellationToken: cancellationToken); } } \ No newline at end of file diff --git a/src/Clients/ChannelClient.cs b/src/Clients/ChannelClient.cs index f7ec8869..63cb388e 100644 --- a/src/Clients/ChannelClient.cs +++ b/src/Clients/ChannelClient.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; using StreamChat.Rest; @@ -12,41 +13,48 @@ internal ChannelClient(IRestClient client) : base(client) { } - public async Task QueryChannelsAsync(QueryChannelsOptions opts) + public async Task QueryChannelsAsync(QueryChannelsOptions opts, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("channels", HttpMethod.POST, HttpStatusCode.Created, - opts); + opts, + cancellationToken: cancellationToken); - public async Task ExportChannelAsync(ExportChannelItem request) - => await ExportChannelsAsync(new ExportChannelRequest { Channels = new[] { request } }); + public async Task ExportChannelAsync(ExportChannelItem request, CancellationToken cancellationToken = default) + => await ExportChannelsAsync( + new ExportChannelRequest { Channels = new[] { request } }, + cancellationToken: cancellationToken); - public async Task ExportChannelsAsync(ExportChannelRequest request) + public async Task ExportChannelsAsync(ExportChannelRequest request, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("export_channels", HttpMethod.POST, HttpStatusCode.Created, - request); + request, + cancellationToken: cancellationToken); - public async Task GetExportChannelsStatusAsync(string taskId) + public async Task GetExportChannelsStatusAsync(string taskId, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"export_channels/{taskId}", HttpMethod.GET, - HttpStatusCode.OK); + HttpStatusCode.OK, + cancellationToken: cancellationToken); - public async Task DeleteChannelsAsync(IEnumerable cids, bool hardDelete = false) + public async Task DeleteChannelsAsync(IEnumerable cids, bool hardDelete = false, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("channels/delete", HttpMethod.POST, HttpStatusCode.Created, - new { cids = cids, hard_delete = hardDelete }); + new { cids = cids, hard_delete = hardDelete }, + cancellationToken: cancellationToken); - public async Task UpdateChannelsBatchAsync(ChannelsBatchOptions options) + public async Task UpdateChannelsBatchAsync(ChannelsBatchOptions options, CancellationToken cancellationToken = default) => await ExecuteRequestAsync("channels/batch", HttpMethod.PUT, HttpStatusCode.Created, - options); + options, + cancellationToken: cancellationToken); public ChannelBatchUpdater BatchUpdater() => new ChannelBatchUpdater(this); - public async Task HideAsync(string channelType, string channelId, string userId, bool clearHistory = false) + public async Task HideAsync(string channelType, string channelId, string userId, bool clearHistory = false, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}/hide", HttpMethod.POST, HttpStatusCode.Created, @@ -54,12 +62,14 @@ public async Task HideAsync(string channelType, string channelId, s { user_id = userId, clear_history = clearHistory, - }); + }, + cancellationToken: cancellationToken); - public async Task ShowAsync(string channelType, string channelId, string userId) + public async Task ShowAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default) => await ExecuteRequestAsync($"channels/{channelType}/{channelId}/show", HttpMethod.POST, HttpStatusCode.Created, - new { user_id = userId }); + new { user_id = userId }, + cancellationToken: cancellationToken); } } diff --git a/src/Clients/ClientBase.cs b/src/Clients/ClientBase.cs index d5970fb3..5640fd62 100644 --- a/src/Clients/ClientBase.cs +++ b/src/Clients/ClientBase.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Net; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using StreamChat.Exceptions; using StreamChat.Models; @@ -26,11 +27,12 @@ protected async Task ExecuteRequestAsync( HttpStatusCode expectedStatusCode, object body = null, IEnumerable> queryParams = null, - MultipartFormDataContent multipartBody = null) where T : ApiResponse + MultipartFormDataContent multipartBody = null, + CancellationToken cancellationToken = default) where T : ApiResponse { var req = _client.BuildRestRequest(relativeUri, method, body, queryParams, multipartBody); - var resp = await _client.ExecuteAsync(req); + var resp = await _client.ExecuteAsync(req, cancellationToken); if (resp.StatusCode == expectedStatusCode) { diff --git a/src/Clients/IChannelClient.cs b/src/Clients/IChannelClient.cs index f3c4e77f..e5d45231 100644 --- a/src/Clients/IChannelClient.cs +++ b/src/Clients/IChannelClient.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using StreamChat.Models; @@ -16,31 +17,37 @@ public interface IChannelClient /// https://getstream.io/chat/docs/dotnet-csharp/channel_members/?language=csharp Task AddMembersAsync(string channelType, string channelId, params string[] userIds); + /// + /// Adds members to a channel. + /// + /// https://getstream.io/chat/docs/dotnet-csharp/channel_members/?language=csharp + Task AddMembersAsync(string channelType, string channelId, string[] userIds, CancellationToken cancellationToken = default); + /// /// Adds members to a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_members/?language=csharp Task AddMembersAsync(string channelType, string channelId, IEnumerable userIds, - MessageRequest msg, AddMemberOptions options); + MessageRequest msg, AddMemberOptions options, CancellationToken cancellationToken = default); /// /// Makes a member a moderator in a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/moderation/?language=csharp - Task AddModeratorsAsync(string channelType, string channelId, IEnumerable userIds); + Task AddModeratorsAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default); /// /// Assigns a role to a user. /// /// https://getstream.io/chat/docs/dotnet-csharp/chat_permission_policies/?language=csharp Task AssignRolesAsync(string channelType, string channelId, - AssignRoleRequest roleRequest); + AssignRoleRequest roleRequest, CancellationToken cancellationToken = default); /// /// Deletes a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_delete/?language=csharp - Task DeleteAsync(string channelType, string channelId); + Task DeleteAsync(string channelType, string channelId, CancellationToken cancellationToken = default); /// /// Deletes multiple channels. @@ -48,14 +55,14 @@ Task AssignRolesAsync(string channelType, string channelI /// You can use to check the status of the task. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_delete/?language=csharp - Task DeleteChannelsAsync(IEnumerable cids, bool hardDelete = false); + Task DeleteChannelsAsync(IEnumerable cids, bool hardDelete = false, CancellationToken cancellationToken = default); /// /// Updates channels in batch based on the provided options. /// This is an asynchronous operation and the returned value is a task Id. /// You can use to check the status of the task. /// - Task UpdateChannelsBatchAsync(ChannelsBatchOptions options); + Task UpdateChannelsBatchAsync(ChannelsBatchOptions options, CancellationToken cancellationToken = default); /// /// Returns a instance for convenient batch channel operations. @@ -66,7 +73,7 @@ Task AssignRolesAsync(string channelType, string channelI /// Takes away moderators status from given user ids. /// /// https://getstream.io/chat/docs/dotnet-csharp/moderation/?language=csharp - Task DemoteModeratorsAsync(string channelType, string channelId, IEnumerable userIds); + Task DemoteModeratorsAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default); /// /// Mutes a channel. @@ -76,7 +83,7 @@ Task AssignRolesAsync(string channelType, string channelI /// of muted channels and their expiration time is returned when the user connects. /// /// https://getstream.io/chat/docs/dotnet-csharp/muting_channels/?language=csharp - Task MuteChannelAsync(ChannelMuteRequest request); + Task MuteChannelAsync(ChannelMuteRequest request, CancellationToken cancellationToken = default); /// /// Unmutes a channel. @@ -87,7 +94,7 @@ Task AssignRolesAsync(string channelType, string channelI /// This method removes the mute which means the users will receive notifications again. /// /// https://getstream.io/chat/docs/dotnet-csharp/muting_channels/?language=csharp - Task UnmuteChannelAsync(ChannelUnmuteRequest request); + Task UnmuteChannelAsync(ChannelUnmuteRequest request, CancellationToken cancellationToken = default); /// /// Export a channel and download all messages and metadata. @@ -96,7 +103,7 @@ Task AssignRolesAsync(string channelType, string channelI /// Use to check the status of the export. /// /// https://getstream.io/chat/docs/dotnet-csharp/exporting_channels/?language=csharp - Task ExportChannelAsync(ExportChannelItem request); + Task ExportChannelAsync(ExportChannelItem request, CancellationToken cancellationToken = default); /// /// Export of one or many channels and download all messages and metadata. @@ -105,13 +112,13 @@ Task AssignRolesAsync(string channelType, string channelI /// Use to check the status of the export. /// /// https://getstream.io/chat/docs/dotnet-csharp/exporting_channels/?language=csharp - Task ExportChannelsAsync(ExportChannelRequest request); + Task ExportChannelsAsync(ExportChannelRequest request, CancellationToken cancellationToken = default); /// /// Returns the status of a channel export. It contains the URL to the JSON file. /// /// https://getstream.io/chat/docs/dotnet-csharp/exporting_channels/?language=csharp - Task GetExportChannelsStatusAsync(string taskId); + Task GetExportChannelsStatusAsync(string taskId, CancellationToken cancellationToken = default); /// /// Returns a channel. If it doesn't exist yet with the given name, it will be created. @@ -125,35 +132,35 @@ Task GetOrCreateAsync(string channelType, string channelId, /// /// https://getstream.io/chat/docs/dotnet-csharp/creating_channels/?language=csharp Task GetOrCreateAsync(string channelType, string channelId, - ChannelGetRequest channelRequest); + ChannelGetRequest channelRequest, CancellationToken cancellationToken = default); /// /// Returns a channel. If it doesn't exist yet with the given name, it will be created. /// This overload creates or gets a channel without explicit channel id. /// /// https://getstream.io/chat/docs/dotnet-csharp/creating_channels/?language=csharp - Task GetOrCreateAsync(string channelType, ChannelGetRequest channelRequest); + Task GetOrCreateAsync(string channelType, ChannelGetRequest channelRequest, CancellationToken cancellationToken = default); /// /// Removes a channel from query channel requests for that user until a new message is added. /// Use to cancel this operation. /// /// https://getstream.io/chat/docs/dotnet-csharp/muting_channels/?language=csharp - Task HideAsync(string channelType, string channelId, string userId, bool clearHistory = false); + Task HideAsync(string channelType, string channelId, string userId, bool clearHistory = false, CancellationToken cancellationToken = default); /// /// Shows a previously hidden channel. /// Use to hide a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/muting_channels/?language=csharp - Task ShowAsync(string channelType, string channelId, string userId); + Task ShowAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Can be used to set and unset specific fields when it is necessary to retain additional custom data fields on the object. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/?language=csharp Task PartialUpdateAsync(string channelType, string channelId, - PartialUpdateChannelRequest partialUpdateChannelRequest); + PartialUpdateChannelRequest partialUpdateChannelRequest, CancellationToken cancellationToken = default); /// /// Queries channels. @@ -163,7 +170,7 @@ Task PartialUpdateAsync(string channelType, string /// You can find the complete list of supported operators in the query syntax section of the docs. /// /// https://getstream.io/chat/docs/dotnet-csharp/query_channels/?language=csharp - Task QueryChannelsAsync(QueryChannelsOptions opts); + Task QueryChannelsAsync(QueryChannelsOptions opts, CancellationToken cancellationToken = default); /// /// Queries members of a channel. @@ -173,26 +180,26 @@ Task PartialUpdateAsync(string channelType, string /// you want to search members or if you want to display the full list of members for a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/query_members/?language=csharp - Task QueryMembersAsync(QueryMembersRequest queryMembersRequest); + Task QueryMembersAsync(QueryMembersRequest queryMembersRequest, CancellationToken cancellationToken = default); /// /// Removes member(s) from a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_members/?language=csharp Task RemoveMembersAsync(string channelType, string channelId, IEnumerable userIds, - MessageRequest msg = null); + MessageRequest msg = null, CancellationToken cancellationToken = default); /// /// Adds filter tags to a channel. /// - Task AddFilterTagsAsync(string channelType, string channelId, IEnumerable filterTags, MessageRequest msg = null); + Task AddFilterTagsAsync(string channelType, string channelId, IEnumerable filterTags, MessageRequest msg = null, CancellationToken cancellationToken = default); Task AddFilterTagsAsync(string channelType, string channelId, params string[] filterTags); /// /// Removes filter tags from a channel. /// - Task RemoveFilterTagsAsync(string channelType, string channelId, IEnumerable filterTags, MessageRequest msg = null); + Task RemoveFilterTagsAsync(string channelType, string channelId, IEnumerable filterTags, MessageRequest msg = null, CancellationToken cancellationToken = default); Task RemoveFilterTagsAsync(string channelType, string channelId, params string[] filterTags); @@ -201,53 +208,53 @@ Task RemoveMembersAsync(string channelType, string channelId, IEnum /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_member/#update-channel-members Task UpdateMemberPartialAsync(string channelType, string channelId, - ChannelMemberPartialRequest channelMemberPartialRequest); + ChannelMemberPartialRequest channelMemberPartialRequest, CancellationToken cancellationToken = default); /// /// Removes all messages but not affect the channel data or channel members. /// If you want to delete both channel and message data then use method instead. /// /// https://getstream.io/chat/docs/dotnet-csharp/truncate_channel/?language=csharp - Task TruncateAsync(string channelType, string channelId); + Task TruncateAsync(string channelType, string channelId, CancellationToken cancellationToken = default); /// /// Removes all messages but not affect the channel data or channel members. /// If you want to delete both channel and message data then use method instead. /// /// https://getstream.io/chat/docs/dotnet-csharp/truncate_channel/?language=csharp - Task TruncateAsync(string channelType, string channelId, TruncateOptions truncateOptions); + Task TruncateAsync(string channelType, string channelId, TruncateOptions truncateOptions, CancellationToken cancellationToken = default); /// /// Invites a user to the channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_invites/?language=csharp/ Task InviteAsync(string channelType, string channelId, string userId, - MessageRequest msg = null); + MessageRequest msg = null, CancellationToken cancellationToken = default); /// /// Invites a user to the channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_invites/?language=csharp/ - Task InviteAsync(string channelType, string channelId, IEnumerable userIds); + Task InviteAsync(string channelType, string channelId, IEnumerable userIds, CancellationToken cancellationToken = default); /// /// Invites a user to the channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_invites/?language=csharp/ Task InviteAsync(string channelType, string channelId, IEnumerable userIds, - MessageRequest msg = null); + MessageRequest msg = null, CancellationToken cancellationToken = default); /// /// Accepts an invitaton to a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_invites/?language=csharp/ - Task AcceptInviteAsync(string channelType, string channelId, string userId); + Task AcceptInviteAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Rejects an invitaton to a channel. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_invites/?language=csharp/ - Task RejectInviteAsync(string channelType, string channelId, string userId); + Task RejectInviteAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Updates a channel. @@ -257,30 +264,30 @@ Task InviteAsync(string channelType, string channelId, IE /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/?language=csharp Task UpdateAsync(string channelType, string channelId, - ChannelUpdateRequest updateRequest); + ChannelUpdateRequest updateRequest, CancellationToken cancellationToken = default); /// /// Pins the channel for the user. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/#pinning-a-channel - Task PinAsync(string channelType, string channelId, string userId); + Task PinAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Unpins the channel for the user. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/#pinning-a-channel - Task UnpinAsync(string channelType, string channelId, string userId); + Task UnpinAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Archives the channel for the user. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/#archiving-a-channel - Task ArchiveAsync(string channelType, string channelId, string userId); + Task ArchiveAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); /// /// Unarchives the channel for the user. /// /// https://getstream.io/chat/docs/dotnet-csharp/channel_update/#archiving-a-channel - Task UnarchiveAsync(string channelType, string channelId, string userId); + Task UnarchiveAsync(string channelType, string channelId, string userId, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/src/Models/Channel.cs b/src/Models/Channel.cs index dc8403fb..a76a6b0b 100644 --- a/src/Models/Channel.cs +++ b/src/Models/Channel.cs @@ -53,6 +53,7 @@ public class ChannelGetResponse : ApiResponse public class UpdateChannelResponse : ApiResponse { public ChannelWithConfig Channel { get; set; } + public bool? Hidden { get; set; } public Message Message { get; set; } public List Members { get; set; } } diff --git a/src/Models/CustomDataBase.cs b/src/Models/CustomDataBase.cs index 2d874aa6..0817c7cc 100644 --- a/src/Models/CustomDataBase.cs +++ b/src/Models/CustomDataBase.cs @@ -9,6 +9,11 @@ public abstract class CustomDataBase [JsonExtensionData] private IDictionary _data = new Dictionary(); + /// + /// Gets the list of all keys which are present at the custom data. + /// + public IEnumerable GetKeys() => _data.Keys; + /// /// Gets a custom data value. /// diff --git a/src/Rest/IRestClient.cs b/src/Rest/IRestClient.cs index 49eff2a6..0e7d35b8 100644 --- a/src/Rest/IRestClient.cs +++ b/src/Rest/IRestClient.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; namespace StreamChat.Rest @@ -12,6 +13,6 @@ RestRequest BuildRestRequest(string fullPath, IEnumerable> queryParams = null, MultipartFormDataContent multipartBody = null); - Task ExecuteAsync(RestRequest request); + Task ExecuteAsync(RestRequest request, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/src/Rest/RestClient.cs b/src/Rest/RestClient.cs index 22cfeaad..acdbbba5 100644 --- a/src/Rest/RestClient.cs +++ b/src/Rest/RestClient.cs @@ -57,11 +57,12 @@ public RestRequest BuildRestRequest(string fullPath, .AddQueryParametersIfNotNull(queryParams); } - public async Task ExecuteAsync(RestRequest request) + public async Task ExecuteAsync(RestRequest request, CancellationToken cancellationToken = default) { var uri = BuildUriWithQueryString(request); - using (var cancelTokenSource = new CancellationTokenSource(_timeout)) + using (var cancelTokenSourceTimeout = new CancellationTokenSource(_timeout)) + using (var cancelTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancelTokenSourceTimeout.Token)) using (var req = GenerateRequestMessage(request, uri)) { var response = await _httpClient.SendAsync(req, cancelTokenSource.Token); diff --git a/tests/ChannelClientTests.cs b/tests/ChannelClientTests.cs index 11b99135..3c7c3aa6 100644 --- a/tests/ChannelClientTests.cs +++ b/tests/ChannelClientTests.cs @@ -229,7 +229,7 @@ public async Task TestMembersQueryAsync() await _channelClient.AddMembersAsync(channel.Type, channel.Id, userIds); // Invite members - await _channelClient.InviteAsync(channel.Type, channel.Id, userIdsToInvite); + await _channelClient.InviteAsync(channel.Type, channel.Id, userIdsToInvite, cancellationToken: default); // Ban members foreach (var userToBanId in usersToBan) @@ -407,6 +407,7 @@ public async Task TestChannelUpdateAsync() var actualChannel = await _channelClient.UpdateAsync(_channel.Type, _channel.Id, expectedChannel); + actualChannel.Channel.GetKeys().Should().BeEquivalentTo(new[] { "plain", "complex" }); actualChannel.Channel.GetData("plain").Should() .BeEquivalentTo(expectedChannel.Data.GetData("plain")); actualChannel.Channel.GetData("complex").Should() @@ -423,6 +424,7 @@ public async Task TestChannelPartialUpdateAsync() var actualChannel = await _channelClient.PartialUpdateAsync(_channel.Type, _channel.Id, channelUpdates); + actualChannel.Channel.GetKeys().Should().BeEquivalentTo(new[] { "color", "age" }); actualChannel.Channel.GetData("color").Should().BeEquivalentTo((string)channelUpdates.Set["color"]); actualChannel.Channel.GetData("age").Should().Be((int)channelUpdates.Set["age"]); } @@ -557,7 +559,7 @@ await _channelClient.UnmuteChannelAsync(new ChannelUnmuteRequest public async Task TestGetExportChannelAsync() { var resp = await _channelClient.ExportChannelAsync(new ExportChannelItem - { Id = _channel.Id, Type = _channel.Type }); + { Id = _channel.Id, Type = _channel.Type }); await WaitForAsync(async () => {