diff --git a/lib/core/aggregators/implementations/message_service_aggregator_impl.dart b/lib/core/aggregators/implementations/message_service_aggregator_impl.dart index 8cca9974..eb4727ca 100644 --- a/lib/core/aggregators/implementations/message_service_aggregator_impl.dart +++ b/lib/core/aggregators/implementations/message_service_aggregator_impl.dart @@ -32,17 +32,27 @@ class MessageServiceAggregatorImpl implements MessageServiceAggregator { ); @override - Future?> fetch({ + Future?> fetchByChatId({ required int chatId, int limit = 25, int? lastMessageId, }) => - _fetcherService.fetch( + _fetcherService.fetchByChatId( chatId: chatId, limit: limit, lastMessageId: lastMessageId, ); + @override + Future?> fetchByDialogId({ + required String dialogId, + int limit = 25, + }) => + _fetcherService.fetchByDialogId( + dialogId: dialogId, + limit: limit, + ); + @override Future send({ required String dialogId, diff --git a/lib/core/constants/api/ajax_action.dart b/lib/core/constants/api/ajax_action.dart index b7191f8b..b6b76630 100644 --- a/lib/core/constants/api/ajax_action.dart +++ b/lib/core/constants/api/ajax_action.dart @@ -35,8 +35,11 @@ class AjaxActionStrings { static const String importantBlogPostUsers = 'socialnetwork.api.livefeed.blogpost.important.getUsers'; - /// Для получения сообщений в чате - static const String fetchFirstMessage = 'im.v2.Chat.Message.list'; + /// Для получения первых N сообщений в чате по chat id + static const String fetchFirstMessageByChatId = 'im.v2.Chat.Message.list'; + + /// Для получения первых N сообщений в чате по dialog id + static const String fetchFirstMessageByDialogId = 'im.v2.Chat.load'; /// Для получения сообщений в чате c конкретного сообщения static const String fetchMessage = 'im.v2.Chat.Message.tail'; diff --git a/lib/core/misc/objects_with_pagination.dart b/lib/core/misc/objects_with_pagination.dart index 8ff32ced..81c00108 100644 --- a/lib/core/misc/objects_with_pagination.dart +++ b/lib/core/misc/objects_with_pagination.dart @@ -22,6 +22,17 @@ class PaginatedResult { }); } +class PaginatedResultWithChatId extends PaginatedResult { + final int chatId; + + const PaginatedResultWithChatId({ + required this.chatId, + required super.items, + required super.hasPreviousPage, + required super.hasNextPage, + }); +} + class PartialResult { final List items; final bool hasMore; diff --git a/lib/core/services/implementations/dialog/message/message_fetcher_service_impl.dart b/lib/core/services/implementations/dialog/message/message_fetcher_service_impl.dart index 5fc3031a..9918745b 100644 --- a/lib/core/services/implementations/dialog/message/message_fetcher_service_impl.dart +++ b/lib/core/services/implementations/dialog/message/message_fetcher_service_impl.dart @@ -27,7 +27,9 @@ import 'package:unn_mobile/core/services/interfaces/dialog/message/message_fetch class _DataKeys { static const String chatId = 'chatId'; + static const String dialogId = 'dialogId'; static const String limit = 'limit'; + static const String messageLimit = 'messageLimit'; static const String lastId = 'filter[lastId]'; static const String orderId = 'order[id]'; } @@ -38,6 +40,8 @@ class _DataValue { class _JsonKeys { static const String data = 'data'; + static const String chat = 'chat'; + static const String id = 'id'; static const String messages = 'messages'; static const String messageId = 'messageId'; static const String reactions = 'reactions'; @@ -67,15 +71,43 @@ class MessageFetcherServiceImpl implements MessageFetcherService { ); @override - Future?> fetch({ + Future?> fetchByChatId({ required int chatId, int limit = 25, int? lastMessageId, - }) async { - final response = lastMessageId == null - ? await _fetchFirstMessages(chatId, limit) - : await _fetchMessages(chatId, lastMessageId, limit); + }) async => + _processPaginatedResponse>( + lastMessageId == null + ? await _fetchFirstMessages(chatId, limit) + : await _fetchMessages(chatId, lastMessageId, limit), + (data, messages) => PaginatedResult( + items: messages, + hasPreviousPage: + data[PaginatedResultJsonKeys.hasPrevPage] as bool? ?? false, + hasNextPage: data[PaginatedResultJsonKeys.hasNextPage]! as bool, + ), + ); + @override + Future?> fetchByDialogId({ + required String dialogId, + int limit = 25, + }) async => + _processPaginatedResponse>( + await _fetchFirstMessages(dialogId, limit, false), + (data, messages) => PaginatedResultWithChatId( + chatId: (data[_JsonKeys.chat]! as JsonMap)[_JsonKeys.id]! as int, + items: messages, + hasPreviousPage: + data[PaginatedResultJsonKeys.hasPrevPage] as bool? ?? false, + hasNextPage: data[PaginatedResultJsonKeys.hasNextPage]! as bool, + ), + ); + + Future _processPaginatedResponse( + Response? response, + T Function(JsonMap data, List messages) createResult, + ) async { if (response == null) { return null; } @@ -86,12 +118,7 @@ class MessageFetcherServiceImpl implements MessageFetcherService { final data = (response.data as JsonMap)[_JsonKeys.data]! as JsonMap; final messages = await _processMessagesData(data); - return PaginatedResult( - items: messages, - hasPreviousPage: - data[PaginatedResultJsonKeys.hasPrevPage] as bool? ?? false, - hasNextPage: data[PaginatedResultJsonKeys.hasNextPage]! as bool, - ); + return createResult(data, messages); } Future> _processMessagesData(Map data) { @@ -281,15 +308,23 @@ class MessageFetcherServiceImpl implements MessageFetcherService { }; Future _fetchFirstMessages( - int chatId, - int limit, - ) => + dynamic id, + int limit, [ + bool isChatId = true, + ]) => _fetchMessagesFromApi( - action: AjaxActionStrings.fetchFirstMessage, - data: { - _DataKeys.chatId: chatId, - _DataKeys.limit: limit, - }, + action: isChatId + ? AjaxActionStrings.fetchFirstMessageByChatId + : AjaxActionStrings.fetchFirstMessageByDialogId, + data: isChatId + ? { + _DataKeys.chatId: id as int, + _DataKeys.limit: limit, + } + : { + _DataKeys.dialogId: id as String, + _DataKeys.messageLimit: limit, + }, ); Future _fetchMessages( diff --git a/lib/core/services/interfaces/dialog/message/message_fetcher_service.dart b/lib/core/services/interfaces/dialog/message/message_fetcher_service.dart index 2d5fbe9d..0ff4a621 100644 --- a/lib/core/services/interfaces/dialog/message/message_fetcher_service.dart +++ b/lib/core/services/interfaces/dialog/message/message_fetcher_service.dart @@ -20,9 +20,26 @@ abstract interface class MessageFetcherService { /// /// В случае ошибки: /// - Возвращает `null` - Future?> fetch({ + Future?> fetchByChatId({ required int chatId, int limit, int? lastMessageId, }); + + /// Получает пагинированный список сообщений из чата. + /// + /// Параметры: + /// - [dialogId] - идентификатор чата, из которого запрашиваются сообщения (обязательный). + /// - [limit] - максимальное количество сообщений в результате (по умолчанию 25) + /// + /// Возвращает [PaginatedResult] с: + /// - Списком сообщений ([items]) + /// - Флагами наличия предыдущей/следующей страниц ([hasPreviousPage], [hasNextPage]) + /// + /// В случае ошибки: + /// - Возвращает `null` + Future?> fetchByDialogId({ + required String dialogId, + int limit = 25, + }); } diff --git a/lib/core/viewmodels/main_page/chat/chat_inside_view_model.dart b/lib/core/viewmodels/main_page/chat/chat_inside_view_model.dart index a930d7f5..02aba974 100644 --- a/lib/core/viewmodels/main_page/chat/chat_inside_view_model.dart +++ b/lib/core/viewmodels/main_page/chat/chat_inside_view_model.dart @@ -79,7 +79,7 @@ class ChatInsideViewModel extends BaseViewModel { } final messages = await tryLoginAndRetrieveData>( - () => _messagesAggregator.fetch(chatId: _dialog!.chatId), + () => _messagesAggregator.fetchByChatId(chatId: _dialog!.chatId), () => null, ); if (messages == null) { @@ -137,7 +137,7 @@ class ChatInsideViewModel extends BaseViewModel { } final messages = await tryLoginAndRetrieveData?>( - () => _messagesAggregator.fetch( + () => _messagesAggregator.fetchByChatId( chatId: _dialog!.chatId, lastMessageId: _unpartitionedMessages.last.messageId, ), @@ -214,7 +214,7 @@ class ChatInsideViewModel extends BaseViewModel { _dialog = _dialogsViewModel!.dialogs.firstWhere((d) => d.chatId == chatId); final messages = await tryLoginAndRetrieveData>( - () => _messagesAggregator.fetch(chatId: chatId), + () => _messagesAggregator.fetchByChatId(chatId: chatId), () => null, ); if (messages == null) { diff --git a/pubspec.yaml b/pubspec.yaml index 847790b9..49a6d86f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: unn_mobile description: A mobile application for UNN Portal website publish_to: 'none' -version: 0.6.0+373 +version: 0.6.0+374 environment: sdk: '>=3.1.2 <4.0.0'