Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,44 @@ class Channel {
);
}

/// Create a reminder for the given [messageId].
///
/// Optionally, provide a [remindAt] date to set when the reminder should
/// be triggered. If not provided, the reminder will be created as a
/// bookmark type instead.
Future<CreateReminderResponse> createReminder(
String messageId, {
required DateTime remindAt,
}) {
_checkInitialized();
return _client.createReminder(
messageId,
remindAt: remindAt,
);
}
Comment thread
xsahil03x marked this conversation as resolved.

/// Update an existing reminder with the given [reminderId].
///
/// Optionally, provide a [remindAt] date to set when the reminder should
/// be triggered. If not provided, the reminder will be updated as a
/// bookmark type instead.
Future<UpdateReminderResponse> updateReminder(
String messageId, {
DateTime? remindAt,
}) {
_checkInitialized();
return _client.updateReminder(
messageId,
remindAt: remindAt,
);
}

/// Remove the reminder for the given [messageId].
Future<EmptyResponse> deleteReminder(String messageId) {
_checkInitialized();
return _client.deleteReminder(messageId);
}

/// Send a reaction to this channel.
///
/// Set [enforceUnique] to true to remove the existing user reaction.
Expand Down Expand Up @@ -2093,6 +2131,16 @@ class ChannelClientState {

_listenUserStopWatching();

/* Start of reminder events */

_listenReminderCreated();

_listenReminderUpdated();

_listenReminderDeleted();

/* End of reminder events */

_startCleaningStaleTypingEvents();

_startCleaningStalePinnedMessages();
Expand Down Expand Up @@ -2578,6 +2626,65 @@ class ChannelClientState {
);
}

void _listenReminderCreated() {
_subscriptions.add(
_channel.on(EventType.reminderCreated).listen((event) {
final reminder = event.reminder;
if (reminder == null) return;

updateReminder(reminder);
}),
);
}

void _listenReminderUpdated() {
_subscriptions.add(
_channel.on(EventType.reminderUpdated).listen((event) {
final reminder = event.reminder;
if (reminder == null) return;

updateReminder(reminder);
}),
);
}

void _listenReminderDeleted() {
_subscriptions.add(
_channel.on(EventType.reminderDeleted).listen((event) {
final reminder = event.reminder;
if (reminder == null) return;

deleteReminder(reminder);
}),
);
}

/// Updates the [reminder] of the message if it exists.
void updateReminder(MessageReminder reminder) {
final messageId = reminder.messageId;
for (final message in messages) {
if (message.id == messageId) {
return updateMessage(
message.copyWith(reminder: reminder),
);
}
}
}

/// Deletes the [reminder] of the message if it exists.
void deleteReminder(MessageReminder reminder) {
// TODO: Delete the reminder from the persistence client.

final messageId = reminder.messageId;
for (final message in messages) {
if (message.id == messageId) {
return updateMessage(
message.copyWith(reminder: null),
);
}
}
}
Comment thread
xsahil03x marked this conversation as resolved.

void _listenReactionDeleted() {
_subscriptions.add(_channel.on(EventType.reactionDeleted).listen((event) {
final oldMessage =
Expand Down
56 changes: 48 additions & 8 deletions packages/stream_chat/lib/src/client/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'package:stream_chat/src/core/models/event.dart';
import 'package:stream_chat/src/core/models/filter.dart';
import 'package:stream_chat/src/core/models/member.dart';
import 'package:stream_chat/src/core/models/message.dart';
import 'package:stream_chat/src/core/models/message_reminder.dart';
import 'package:stream_chat/src/core/models/own_user.dart';
import 'package:stream_chat/src/core/models/poll.dart';
import 'package:stream_chat/src/core/models/poll_option.dart';
Expand Down Expand Up @@ -1914,14 +1915,6 @@ class StreamChatClient {
required String channelId,
required String channelType,
}) {
final currentUser = state.currentUser;
if (currentUser == null) {
throw const StreamChatError(
'User is not set on client, '
'use `connectUser` or `connectAnonymousUser` instead',
);
}

return partialMemberUpdate(
channelId: channelId,
channelType: channelType,
Expand Down Expand Up @@ -1962,6 +1955,53 @@ class StreamChatClient {
);
}

/// Queries reminders for the current user.
///
/// Optionally, pass [filter], [sort] and [pagination] to filter, sort and
/// paginate the reminders.
Future<QueryRemindersResponse> queryReminders({
Filter? filter,
SortOrder<MessageReminder>? sort,
PaginationParams pagination = const PaginationParams(),
}) {
return _chatApi.reminders.queryReminders(
filter: filter,
sort: sort,
pagination: pagination,
);
}

/// Creates a reminder for the given [messageId].
///
/// Optionally, pass [remindAt] to set the reminder time.
Future<CreateReminderResponse> createReminder(
String messageId, {
DateTime? remindAt,
}) {
return _chatApi.reminders.createReminder(
messageId,
remindAt: remindAt,
);
}

/// Updates a reminder for the given [messageId].
///
/// Optionally, pass [remindAt] to set the new reminder time.
Future<UpdateReminderResponse> updateReminder(
String messageId, {
DateTime? remindAt,
}) {
return _chatApi.reminders.updateReminder(
messageId,
remindAt: remindAt,
);
}

/// Deletes a reminder for the given [messageId].
Future<EmptyResponse> deleteReminder(String messageId) {
return _chatApi.reminders.deleteReminder(messageId);
}

/// Closes the [_ws] connection and resets the [state]
/// If [flushChatPersistence] is true the client deletes all offline
/// user's data.
Expand Down
91 changes: 91 additions & 0 deletions packages/stream_chat/lib/src/core/api/reminders_api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import 'dart:convert';

import 'package:stream_chat/src/core/api/requests.dart';
import 'package:stream_chat/src/core/api/responses.dart';
import 'package:stream_chat/src/core/api/sort_order.dart';
import 'package:stream_chat/src/core/http/stream_http_client.dart';
import 'package:stream_chat/src/core/models/filter.dart';
import 'package:stream_chat/src/core/models/message_reminder.dart';

/// Defines the api dedicated to message reminders operations
class RemindersApi {
/// Initialize a new reminders api
const RemindersApi(this._client);

final StreamHttpClient _client;

/// Retrieves the list of reminders for the current user.
///
/// Optionally, you can filter and sort the reminders using the [filter] and
/// [sort] parameters respectively. You can also paginate the results using
/// [pagination].
///
/// Returns a [QueryRemindersResponse] containing the list of reminders.
Future<QueryRemindersResponse> queryReminders({
Filter? filter,
SortOrder<MessageReminder>? sort,
PaginationParams? pagination,
}) async {
final response = await _client.post(
'/reminders/query',
data: jsonEncode({
if (filter != null) 'filter': filter,
if (sort != null) 'sort': sort,
if (pagination != null) ...pagination.toJson(),
}),
);

return QueryRemindersResponse.fromJson(response.data);
}

/// Creates a new reminder for the specified [messageId.
Comment thread
xsahil03x marked this conversation as resolved.
Outdated
///
/// You can specify the time to remind using the [remindAt] parameter.
///
/// Returns a [CreateReminderResponse] containing the created reminder.
Future<CreateReminderResponse> createReminder(
String messageId, {
DateTime? remindAt,
}) async {
final response = await _client.post(
'/messages/$messageId/reminders',
data: jsonEncode({
if (remindAt != null) 'remind_at': remindAt.toUtc().toIso8601String(),
}),
);

return CreateReminderResponse.fromJson(response.data);
}

/// Updates an existing reminder for the specified [messageId].
///
/// You can change the reminder time using the [remindAt] parameter.
///
/// Returns an [UpdateReminderResponse] containing the updated reminder.
Future<UpdateReminderResponse> updateReminder(
String messageId, {
DateTime? remindAt,
}) async {
final response = await _client.patch(
'/messages/$messageId/reminders',
data: jsonEncode({
if (remindAt != null) 'remind_at': remindAt.toUtc().toIso8601String(),
}),
);

return UpdateReminderResponse.fromJson(response.data);
}

/// Deletes a reminder for the specified [messageId].
///
/// Returns an [EmptyResponse] indicating the deletion was successful.
Future<EmptyResponse> deleteReminder(
String messageId,
) async {
final response = await _client.delete(
'/messages/$messageId/reminders',
);

return EmptyResponse.fromJson(response.data);
}
}
38 changes: 38 additions & 0 deletions packages/stream_chat/lib/src/core/api/responses.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:stream_chat/src/core/models/draft.dart';
import 'package:stream_chat/src/core/models/event.dart';
import 'package:stream_chat/src/core/models/member.dart';
import 'package:stream_chat/src/core/models/message.dart';
import 'package:stream_chat/src/core/models/message_reminder.dart';
import 'package:stream_chat/src/core/models/poll.dart';
import 'package:stream_chat/src/core/models/poll_option.dart';
import 'package:stream_chat/src/core/models/poll_vote.dart';
Expand Down Expand Up @@ -764,3 +765,40 @@ class QueryDraftsResponse extends _BaseResponse {
static QueryDraftsResponse fromJson(Map<String, dynamic> json) =>
_$QueryDraftsResponseFromJson(json);
}

/// Base Model response for draft based api calls.
class MessageReminderResponse extends _BaseResponse {
/// Draft returned by the api call
late MessageReminder reminder;
}

/// Model response for [StreamChatClient.createReminder] api call
@JsonSerializable(createToJson: false)
class CreateReminderResponse extends MessageReminderResponse {
/// Create a new instance from a json
static CreateReminderResponse fromJson(Map<String, dynamic> json) =>
_$CreateReminderResponseFromJson(json);
}

/// Model response for [StreamChatClient.updateReminder] api call
@JsonSerializable(createToJson: false)
class UpdateReminderResponse extends MessageReminderResponse {
/// Create a new instance from a json
static UpdateReminderResponse fromJson(Map<String, dynamic> json) =>
_$UpdateReminderResponseFromJson(json);
}

/// Model response for [StreamChatClient.queryReminders] api call
@JsonSerializable(createToJson: false)
class QueryRemindersResponse extends _BaseResponse {
/// List of reminders returned by the query
@JsonKey(defaultValue: [])
late List<MessageReminder> reminders;

/// The next page token
late String? next;

/// Create a new instance from a json
static QueryRemindersResponse fromJson(Map<String, dynamic> json) =>
_$QueryRemindersResponseFromJson(json);
}
24 changes: 24 additions & 0 deletions packages/stream_chat/lib/src/core/api/responses.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions packages/stream_chat/lib/src/core/api/stream_chat_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:stream_chat/src/core/api/guest_api.dart';
import 'package:stream_chat/src/core/api/message_api.dart';
import 'package:stream_chat/src/core/api/moderation_api.dart';
import 'package:stream_chat/src/core/api/polls_api.dart';
import 'package:stream_chat/src/core/api/reminders_api.dart';
import 'package:stream_chat/src/core/api/threads_api.dart';
import 'package:stream_chat/src/core/api/user_api.dart';
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
Expand Down Expand Up @@ -87,6 +88,10 @@ class StreamChatApi {
ModerationApi get moderation => _moderation ??= ModerationApi(_client);
ModerationApi? _moderation;

/// Api dedicated to message reminders operations
RemindersApi get reminders => _reminders ??= RemindersApi(_client);
RemindersApi? _reminders;

/// Api dedicated to general operations
GeneralApi get general => _general ??= GeneralApi(_client);
GeneralApi? _general;
Expand Down
Loading
Loading