Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,27 @@ class MessageServiceAggregatorImpl implements MessageServiceAggregator {
);

@override
Future<PaginatedResult<Message>?> fetch({
Future<PaginatedResult<Message>?> fetchByChatId({
required int chatId,
int limit = 25,
int? lastMessageId,
}) =>
_fetcherService.fetch(
_fetcherService.fetchByChatId(
chatId: chatId,
limit: limit,
lastMessageId: lastMessageId,
);

@override
Future<PaginatedResult<Message>?> fetchByDialogId({
required String dialogId,
int limit = 25,
}) =>
_fetcherService.fetchByDialogId(
dialogId: dialogId,
limit: limit,
);

@override
Future<int?> send({
required String dialogId,
Expand Down
7 changes: 5 additions & 2 deletions lib/core/constants/api/ajax_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
11 changes: 11 additions & 0 deletions lib/core/misc/objects_with_pagination.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ class PaginatedResult<T> {
});
}

class PaginatedResultWithChatId<T> extends PaginatedResult<T> {
final int chatId;

const PaginatedResultWithChatId({
required this.chatId,
required super.items,
required super.hasPreviousPage,
required super.hasNextPage,
});
}

class PartialResult<T> {
final List<T> items;
final bool hasMore;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]';
}
Expand All @@ -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';
Expand Down Expand Up @@ -67,15 +71,43 @@ class MessageFetcherServiceImpl implements MessageFetcherService {
);

@override
Future<PaginatedResult<Message>?> fetch({
Future<PaginatedResult<Message>?> 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<PaginatedResult<Message>>(
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<PaginatedResultWithChatId<Message>?> fetchByDialogId({
required String dialogId,
int limit = 25,
}) async =>
_processPaginatedResponse<PaginatedResultWithChatId<Message>>(
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<T?> _processPaginatedResponse<T>(
Response? response,
T Function(JsonMap data, List<Message> messages) createResult,
) async {
if (response == null) {
return null;
}
Expand All @@ -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<List<Message>> _processMessagesData(Map<String, dynamic> data) {
Expand Down Expand Up @@ -281,15 +308,23 @@ class MessageFetcherServiceImpl implements MessageFetcherService {
};

Future<Response?> _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<Response?> _fetchMessages(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,26 @@ abstract interface class MessageFetcherService {
///
/// В случае ошибки:
/// - Возвращает `null`
Future<PaginatedResult<Message>?> fetch({
Future<PaginatedResult<Message>?> fetchByChatId({
required int chatId,
int limit,
int? lastMessageId,
});

/// Получает пагинированный список сообщений из чата.
///
/// Параметры:
/// - [dialogId] - идентификатор чата, из которого запрашиваются сообщения (обязательный).
/// - [limit] - максимальное количество сообщений в результате (по умолчанию 25)
///
/// Возвращает [PaginatedResult] с:
/// - Списком сообщений ([items])
/// - Флагами наличия предыдущей/следующей страниц ([hasPreviousPage], [hasNextPage])
///
/// В случае ошибки:
/// - Возвращает `null`
Future<PaginatedResult<Message>?> fetchByDialogId({
required String dialogId,
int limit = 25,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ChatInsideViewModel extends BaseViewModel {
}

final messages = await tryLoginAndRetrieveData<PaginatedResult<Message>>(
() => _messagesAggregator.fetch(chatId: _dialog!.chatId),
() => _messagesAggregator.fetchByChatId(chatId: _dialog!.chatId),
() => null,
);
if (messages == null) {
Expand Down Expand Up @@ -137,7 +137,7 @@ class ChatInsideViewModel extends BaseViewModel {
}
final messages =
await tryLoginAndRetrieveData<PaginatedResult<Message>?>(
() => _messagesAggregator.fetch(
() => _messagesAggregator.fetchByChatId(
chatId: _dialog!.chatId,
lastMessageId: _unpartitionedMessages.last.messageId,
),
Expand Down Expand Up @@ -214,7 +214,7 @@ class ChatInsideViewModel extends BaseViewModel {
_dialog = _dialogsViewModel!.dialogs.firstWhere((d) => d.chatId == chatId);

final messages = await tryLoginAndRetrieveData<PaginatedResult<Message>>(
() => _messagesAggregator.fetch(chatId: chatId),
() => _messagesAggregator.fetchByChatId(chatId: chatId),
() => null,
);
if (messages == null) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down