Skip to content

Commit

Permalink
Fix the typing status is not sent to group conversations #1363 + Cach…
Browse files Browse the repository at this point in the history
…e the result of `hasNoRelationshipOrNotBlocked` and `isBlocked` for better performance + Update outdate doc for response status codes
  • Loading branch information
JamesChenX committed Dec 25, 2023
1 parent b82e129 commit 9148daf
Show file tree
Hide file tree
Showing 13 changed files with 496 additions and 292 deletions.
18 changes: 12 additions & 6 deletions turms-client-cpp/include/turms/client/model/response_status_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,18 @@ const int kSendGroupInvitationToGroupNotRequireInvitation = 3709;
const int kRecallNonPendingGroupInvitation = 3710;

// Conversation
const int kUpdatingTypingStatusIsDisabled = 4000;
const int kUpdatingReadDateIsDisabled = 4001;
const int kUpdatingReadDateIsDisabledByGroup = 4002;
const int kUpdatingReadDateOfNonexistentGroupConversation = 4003;
const int kNotGroupMemberToUpdateReadDateOfGroupConversation = 4004;
const int kMovingReadDateForwardIsDisabled = 4005;

// Conversation - Read Date
const int kUpdatingReadDateIsDisabled = 4000;
const int kUpdatingReadDateIsDisabledByGroup = 4001;
const int kUpdatingReadDateOfNonexistentGroupConversation = 4002;
const int kNotGroupMemberToUpdateReadDateOfGroupConversation = 4003;
const int kMovingReadDateForwardIsDisabled = 4004;

// Conversation - Typing Status
const int kUpdatingTypingStatusIsDisabled = 4100;
const int kNotGroupMemberToSendTypingStatus = 4101;
const int kNotFriendToSendTypingStatus = 4102;

// Message

Expand Down
18 changes: 12 additions & 6 deletions turms-client-dart/lib/src/model/response_status_code.dart
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,18 @@ class ResponseStatusCode {
static const recallNonPendingGroupInvitation = 3710;

// Conversation
static const updatingTypingStatusIsDisabled = 4000;
static const updatingReadDateIsDisabled = 4001;
static const updatingReadDateIsDisabledByGroup = 4002;
static const updatingReadDateOfNonexistentGroupConversation = 4003;
static const notGroupMemberToUpdateReadDateOfGroupConversation = 4004;
static const movingReadDateForwardIsDisabled = 4005;

// Conversation - Read Date
static const updatingReadDateIsDisabled = 4000;
static const updatingReadDateIsDisabledByGroup = 4001;
static const updatingReadDateOfNonexistentGroupConversation = 4002;
static const notGroupMemberToUpdateReadDateOfGroupConversation = 4003;
static const movingReadDateForwardIsDisabled = 4004;

// Conversation - Typing Status
static const updatingTypingStatusIsDisabled = 4100;
static const notGroupMemberToSendTypingStatus = 4101;
static const notFriendToSendTypingStatus = 4102;

// Message

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,18 @@ object ResponseStatusCode {
const val RECALL_NON_PENDING_GROUP_INVITATION = 3710

// Conversation
const val UPDATING_TYPING_STATUS_IS_DISABLED = 4000
const val UPDATING_READ_DATE_IS_DISABLED = 4001
const val UPDATING_READ_DATE_IS_DISABLED_BY_GROUP = 4002
const val UPDATING_READ_DATE_OF_NONEXISTENT_GROUP_CONVERSATION = 4003
const val NOT_GROUP_MEMBER_TO_UPDATE_READ_DATE_OF_GROUP_CONVERSATION = 4004
const val MOVING_READ_DATE_FORWARD_IS_DISABLED = 4005

// Conversation - Read Date
const val UPDATING_READ_DATE_IS_DISABLED = 4000
const val UPDATING_READ_DATE_IS_DISABLED_BY_GROUP = 4001
const val UPDATING_READ_DATE_OF_NONEXISTENT_GROUP_CONVERSATION = 4002
const val NOT_GROUP_MEMBER_TO_UPDATE_READ_DATE_OF_GROUP_CONVERSATION = 4003
const val MOVING_READ_DATE_FORWARD_IS_DISABLED = 4004

// Conversation - Typing Status
const val UPDATING_TYPING_STATUS_IS_DISABLED = 4100
const val NOT_GROUP_MEMBER_TO_SEND_TYPING_STATUS = 4101
const val NOT_FRIEND_TO_SEND_TYPING_STATUS = 4102

// Message

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,19 @@ public enum ResponseStatusCode: Int {
case recallNonPendingGroupInvitation

// Conversation
case updatingTypingStatusIsDisabled = 4000
case updatingReadDateIsDisabled

// Conversation - Read Date
case updatingReadDateIsDisabled = 4000
case updatingReadDateIsDisabledByGroup
case updatingReadDateOfNonexistentGroupConversation
case notGroupMemberToUpdateReadDateOfGroupConversation
case movingReadDateForwardIsDisabled

// Conversation - Typing Status
case updatingTypingStatusIsDisabled = 4100
case notGroupMemberToSendTypingStatus
case notFriendToSendTypingStatus

// Message

// Message - Send
Expand Down
271 changes: 157 additions & 114 deletions turms-docs/src/reference/status-code.md

Large diffs are not rendered by default.

271 changes: 157 additions & 114 deletions turms-docs/src/zh-CN/reference/status-code.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,8 @@ private Mono<Map<String, String>> queryMessageAttachmentUploadInfo(
}
sharedWithUserIds = List.of(userId);
associatedGroupIds = null;
authorize = userRelationshipService.hasRelationshipAndNotBlocked(userId, requesterId)
authorize = userRelationshipService
.hasRelationshipAndNotBlocked(userId, requesterId, false)
.flatMap(hasRelationshipAndNotBlocked -> hasRelationshipAndNotBlocked
? Mono.empty()
: Mono.error(ResponseException.get(
Expand Down Expand Up @@ -912,7 +913,7 @@ public Mono<List<StorageResourceInfo>> queryMessageAttachmentInfosInPrivateConve
.findSimpleAttachmentsInPrivateConversation(requesterId, creationDateRange);
} else {
attachmentFlux =
userRelationshipService.hasRelationshipAndNotBlocked(userId, requesterId)
userRelationshipService.hasRelationshipAndNotBlocked(userId, requesterId, false)
.flatMapMany(hasRelationshipAndNotBlocked -> {
if (!hasRelationshipAndNotBlocked) {
return Mono.error(ResponseException.get(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,15 +279,22 @@ public enum ResponseStatusCode {
RECALL_NON_PENDING_GROUP_INVITATION(3710, "Cannot recall non-pending group invitations", 403),

// Conversation
UPDATING_TYPING_STATUS_IS_DISABLED(4000, "Updating the typing status is disabled", 510),
UPDATING_READ_DATE_IS_DISABLED(4001, "Updating the read data is disabled", 510),
UPDATING_READ_DATE_IS_DISABLED_BY_GROUP(4002, "Updating the read data is disabled by the group",

// Conversation - Read Date
UPDATING_READ_DATE_IS_DISABLED(4000, "Updating the read data is disabled", 510),
UPDATING_READ_DATE_IS_DISABLED_BY_GROUP(4001, "Updating the read data is disabled by the group",
510),
UPDATING_READ_DATE_OF_NONEXISTENT_GROUP_CONVERSATION(4003,
UPDATING_READ_DATE_OF_NONEXISTENT_GROUP_CONVERSATION(4002,
"Cannot update the read date of a nonexistent group conversation", 510),
NOT_GROUP_MEMBER_TO_UPDATE_READ_DATE_OF_GROUP_CONVERSATION(4004,
NOT_GROUP_MEMBER_TO_UPDATE_READ_DATE_OF_GROUP_CONVERSATION(4003,
"Only group members can update the read date of a group conversation", 403),
MOVING_READ_DATE_FORWARD_IS_DISABLED(4005, "Moving the read data forward is disabled", 510),
MOVING_READ_DATE_FORWARD_IS_DISABLED(4004, "Moving the read data forward is disabled", 510),

// Conversation - Typing Status
UPDATING_TYPING_STATUS_IS_DISABLED(4100, "Updating the typing status is disabled", 510),
NOT_GROUP_MEMBER_TO_SEND_TYPING_STATUS(4101, "Only group members can send their typing status",
403),
NOT_FRIEND_TO_SEND_TYPING_STATUS(4102, "Only friends can send their typing status", 403),

// Message

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import im.turms.server.common.access.client.dto.ClientMessagePool;
import im.turms.server.common.access.client.dto.notification.TurmsNotification;
import im.turms.server.common.access.client.dto.request.TurmsRequest;
import im.turms.server.common.access.client.dto.request.conversation.QueryConversationsRequest;
import im.turms.server.common.access.client.dto.request.conversation.UpdateConversationRequest;
import im.turms.server.common.access.client.dto.request.conversation.UpdateTypingStatusRequest;
Expand Down Expand Up @@ -57,8 +58,6 @@ public class ConversationServiceController extends BaseServiceController {
private final ConversationService conversationService;
private final GroupMemberService groupMemberService;

private boolean isTypingStatusEnabled;

private boolean notifyRequesterOtherOnlineSessionsOfPrivateConversationReadDateUpdated;
private boolean notifyContactOfPrivateConversationReadDateUpdated;

Expand All @@ -78,9 +77,6 @@ public ConversationServiceController(
private void updateProperties(TurmsProperties properties) {
ServiceProperties serviceProperties = properties.getService();
NotificationProperties notificationProperties = serviceProperties.getNotification();
isTypingStatusEnabled = serviceProperties.getConversation()
.getTypingStatus()
.isEnabled();

NotificationPrivateConversationReadDateUpdatedProperties privateConversationReadDateUpdatedProperties =
notificationProperties.getPrivateConversationReadDateUpdated();
Expand Down Expand Up @@ -134,26 +130,16 @@ public ClientRequestHandler handleQueryConversationsRequest() {
};
}

/**
* Allow sending typing status to recipients without checking their relationships for better
* performance. The application itself should check their relationships on the client side.
*
* @implNote No need to authenticate because: 1. Most requests are authenticated indeed, so
* avoid frequent authentication to improve the performance greatly; 2. For
* unauthenticated requests, it is easy for the client to ignore it according to its
* local data, and the user won't be aware of these requests.
*/
@ServiceRequestMapping(UPDATE_TYPING_STATUS_REQUEST)
public ClientRequestHandler handleUpdateTypingStatusRequest() {
return clientRequest -> {
if (!isTypingStatusEnabled) {
return Mono.just(RequestHandlerResult
.of(ResponseStatusCode.UPDATING_TYPING_STATUS_IS_DISABLED));
}
UpdateTypingStatusRequest request = clientRequest.turmsRequest()
.getUpdateTypingStatusRequest();
return Mono.just(RequestHandlerResult
.of(ResponseStatusCode.OK, request.getToId(), clientRequest.turmsRequest()));
TurmsRequest turmsRequest = clientRequest.turmsRequest();
UpdateTypingStatusRequest request = turmsRequest.getUpdateTypingStatusRequest();
return conversationService
.authAndUpdateTypingStatus(clientRequest.userId(),
request.getIsGroupMessage(),
request.getToId())
.map(recipientIds -> RequestHandlerResult.of(recipientIds, turmsRequest));
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import im.turms.server.common.infra.exception.ResponseException;
import im.turms.server.common.infra.property.TurmsProperties;
import im.turms.server.common.infra.property.TurmsPropertiesManager;
import im.turms.server.common.infra.property.env.service.ServiceProperties;
import im.turms.server.common.infra.property.env.service.business.conversation.ReadReceiptProperties;
import im.turms.server.common.infra.validation.Validator;
import im.turms.server.common.storage.mongo.IMongoCollectionInitializer;
Expand All @@ -51,6 +52,7 @@
import im.turms.service.domain.conversation.repository.PrivateConversationRepository;
import im.turms.service.domain.group.service.GroupMemberService;
import im.turms.service.domain.group.service.GroupService;
import im.turms.service.domain.user.service.UserRelationshipService;
import im.turms.service.storage.mongo.OperationResultPublisherPool;

/**
Expand All @@ -60,6 +62,7 @@
@DependsOn(IMongoCollectionInitializer.BEAN_NAME)
public class ConversationService {

private final UserRelationshipService userRelationshipService;
private final GroupService groupService;
private final GroupMemberService groupMemberService;

Expand All @@ -70,16 +73,20 @@ public class ConversationService {
private boolean isReadReceiptEnabled;
private boolean useServerTime;

private boolean isTypingStatusEnabled;

/**
* @param groupService is lazy because conversationService -> groupService ->
* conversationService
*/
public ConversationService(
TurmsPropertiesManager propertiesManager,
UserRelationshipService userRelationshipService,
@Lazy GroupService groupService,
GroupMemberService groupMemberService,
GroupConversationRepository groupConversationRepository,
PrivateConversationRepository privateConversationRepository) {
this.userRelationshipService = userRelationshipService;
this.groupService = groupService;
this.groupMemberService = groupMemberService;
this.groupConversationRepository = groupConversationRepository;
Expand All @@ -89,12 +96,17 @@ public ConversationService(
}

private void updateProperties(TurmsProperties properties) {
ReadReceiptProperties readReceiptProperties = properties.getService()
.getConversation()
ServiceProperties serviceProperties = properties.getService();

ReadReceiptProperties readReceiptProperties = serviceProperties.getConversation()
.getReadReceipt();
allowMoveReadDateForward = readReceiptProperties.isAllowMoveReadDateForward();
isReadReceiptEnabled = readReceiptProperties.isEnabled();
useServerTime = readReceiptProperties.isUseServerTime();

isTypingStatusEnabled = serviceProperties.getConversation()
.getTypingStatus()
.isEnabled();
}

public Mono<Void> authAndUpsertGroupConversationReadDate(
Expand Down Expand Up @@ -361,4 +373,40 @@ public Mono<Void> deleteGroupMemberConversations(
return delete;
}

// Typing Status

public Mono<Set<Long>> authAndUpdateTypingStatus(
@NotNull Long requesterId,
boolean isGroupMessage,
@NotNull Long toId) {
try {
Validator.notNull(requesterId, "requesterId");
Validator.notNull(toId, "toId");
} catch (ResponseException e) {
return Mono.error(e);
}
if (!isTypingStatusEnabled) {
return Mono.error(
ResponseException.get(ResponseStatusCode.UPDATING_TYPING_STATUS_IS_DISABLED));
}
if (isGroupMessage) {
return groupMemberService.isGroupMember(toId, requesterId, true)
.flatMap(isMember -> {
if (!isMember) {
return Mono.error(ResponseException.get(
ResponseStatusCode.NOT_GROUP_MEMBER_TO_SEND_TYPING_STATUS));
}
return groupMemberService.queryGroupMemberIds(toId, true);
});
} else {
return userRelationshipService.hasRelationshipAndNotBlocked(toId, requesterId)
.flatMap(hasRelationshipAndNotBlocked -> {
if (!hasRelationshipAndNotBlocked) {
return Mono.error(ResponseException
.get(ResponseStatusCode.NOT_FRIEND_TO_SEND_TYPING_STATUS));
}
return Mono.just(Set.of(toId));
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public Mono<UserFriendRequest> createFriendRequest(
Validator.pastOrPresent(responseDate, "responseDate");
Validator.notEquals(requesterId,
recipientId,
"The requester ID must not equal to the recipient ID");
"The requester ID must not be equal to the recipient ID");
} catch (ResponseException e) {
return Mono.error(e);
}
Expand Down Expand Up @@ -254,7 +254,8 @@ public Mono<UserFriendRequest> authAndCreateFriendRequest(
} catch (ResponseException e) {
return Mono.error(e);
}
return userRelationshipService.hasNoRelationshipOrNotBlocked(recipientId, requesterId)
return userRelationshipService
.hasNoRelationshipOrNotBlocked(recipientId, requesterId, false)
.flatMap(isNotBlocked -> {
if (!isNotBlocked) {
return Mono.error(ResponseException
Expand Down
Loading

0 comments on commit 9148daf

Please sign in to comment.