Skip to content

Commit

Permalink
Merge branch 'dev' into feature/LWF-14_adding-contacts
Browse files Browse the repository at this point in the history
  • Loading branch information
JeriRov committed May 4, 2024
2 parents 353b84b + 9ce18e4 commit d94a0da
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,16 @@ public interface ChatService {
*/
void updateChat(@NonNull Chat chat);

Map<String, List<ChatMember>> getChatsMembers(Long userId, List<String> chatId);
/**
* Returns members for each chat that user (userId) is a member of. Every chat from the {@code chatIds} list
* is checked to determine if user is a member too. When it is, the members of that chat is retrieved, otherwise
* the chat is gonna to be skipped.
*
* @param userId id of the user
* @param chatIds chats to return members for
* @return map where key is chat id, and value is list of members of this chat
*/
Map<String, List<ChatMember>> getChatsMembers(Long userId, List<String> chatIds);

/**
* Used to get to know if user is a member of specific chat.
Expand Down Expand Up @@ -115,6 +124,14 @@ public interface ChatService {

boolean isAdmin(Long memberId, @NonNull Chat chat);

/**
* Checks whether member has specified role in the chat.
*
* @param chat duo / group chat
* @param memberId member that is needed to check role for
* @param role role is needed to check
* @throws ChatMemberPermissionsDenied when member not found or does not have the specified role
*/
void checkMemberRole(@NonNull Chat chat, Long memberId, ChatRole role) throws ChatMemberPermissionsDenied;

ChatMemberDto addGroupChatMember(String chatId, @NonNull RequestInitiator initiator);
Expand Down Expand Up @@ -146,7 +163,11 @@ GroupChatDetailsDto getGroupChatDetails(@NonNull RequestInitiator initiator, Str
*/
void changeGroupChatAvatar(String chatId, @NonNull MultipartFile avatar);

boolean isAvatarSet(GroupChat chat);
/**
* @param chat non-null group chat object
* @return true if avatar is set, otherwise false
*/
boolean isAvatarSet(@NonNull GroupChat chat);

/**
* Retrieve a group chat avatar as array of bytes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.linkwave.chatservice.api.ws.LoadChatRequest;
import org.linkwave.chatservice.api.ws.WSServiceClient;
import org.linkwave.chatservice.chat.duo.Chat;
import org.linkwave.chatservice.chat.duo.CompanionDto;
import org.linkwave.chatservice.chat.duo.DuoChatDto;
import org.linkwave.chatservice.chat.duo.NewChatRequest;
import org.linkwave.chatservice.chat.group.GroupChat;
Expand Down Expand Up @@ -184,46 +185,7 @@ public Pair<Long, List<ChatDto>> getUserChats(@NonNull RequestInitiator initiato
final Set<Long> usersIds = new HashSet<>();
final List<ChatDto> selectedChats = userChats
.stream()
.map(chat -> {
final boolean isGroupChat = chat instanceof GroupChat;
final Class<? extends ChatDto> cls = isGroupChat
? GroupChatDto.class
: DuoChatDto.class;

final ChatDto chatDto = modelMapper.map(chat, cls);

if (isGroupChat) {
chatDto.setAvatarAvailable(isAvatarSet((GroupChat) chat));
} else {
// pull user info for duo chat
final List<ChatMember> members = chat.getMembers();
Long memberId = members.get(0).getId();
usersIds.add(memberId.equals(initiator.userId())
? memberId = members.get(1).getId()
: memberId
);

((DuoChatDto) chatDto).setUser(
UserDto.builder().id(memberId).build()
);
}

final Message lastMessage = chat.getLastMessage();
if (lastMessage == null) {
return chatDto;
}

final MessageDto messageDto = lastMessage.convert(modelMapper);

// save author ID for filling user data in the future
messageDto.setAuthor(MessageAuthorDto.builder()
.id(lastMessage.getAuthorId())
.build());
chatDto.setLastMessage(messageDto);

usersIds.add(lastMessage.getAuthorId());
return chatDto;
})
.map(chat -> mapChats(chat, usersIds, initiator))
.toList();

final Map<Long, UserDto> usersMap = new LinkedHashMap<>();
Expand All @@ -238,9 +200,7 @@ public Pair<Long, List<ChatDto>> getUserChats(@NonNull RequestInitiator initiato
);

// pull contacts
final Map<Long, ContactDto> contactsMap = fetchAllContacts(initiator)
.stream()
.collect(toMap(contact -> contact.getUser().getId(), identity()));
final Map<Long, ContactDto> contactsMap = fetchAllContacts(initiator);

selectedChats.forEach(chat -> {
final MessageDto lastMessage = chat.getLastMessage();
Expand All @@ -255,10 +215,12 @@ public Pair<Long, List<ChatDto>> getUserChats(@NonNull RequestInitiator initiato

if (chat instanceof DuoChatDto duoChat) {
duoChat.setAvatarAvailable(user.getAvatarPath() != null);

// inject companion dto
final Long companionId = duoChat.getUser().getId();
final UserDto companionUserDto = usersMap.get(companionId);
if (companionUserDto != null) {
duoChat.setUser(companionUserDto);
final UserDto userDto = usersMap.get(companionId);
if (userDto != null) {
duoChat.setUser(modelMapper.map(userDto, CompanionDto.class));
}
}

Expand All @@ -278,7 +240,7 @@ public Pair<Long, List<ChatDto>> getUserChats(@NonNull RequestInitiator initiato
}

@NonNull
private List<ContactDto> fetchAllContacts(@NonNull RequestInitiator initiator) {
private Map<Long, ContactDto> fetchAllContacts(@NonNull RequestInitiator initiator) {
final String username = ""; // any username is matched
int offset = 0;

Expand All @@ -290,7 +252,49 @@ private List<ContactDto> fetchAllContacts(@NonNull RequestInitiator initiator) {
allContacts.addAll(contacts);
offset += DEFAULT_BATCH_SIZE;
} while (contacts.size() == DEFAULT_BATCH_SIZE);
return allContacts;
return allContacts.stream()
.collect(toMap(contact -> contact.getUser().getId(), identity()));
}

private ChatDto mapChats(Chat chat, Set<Long> usersIds, RequestInitiator initiator) {
final boolean isGroupChat = chat instanceof GroupChat;
final Class<? extends ChatDto> cls = isGroupChat
? GroupChatDto.class
: DuoChatDto.class;

final ChatDto chatDto = modelMapper.map(chat, cls);

if (isGroupChat) {
chatDto.setAvatarAvailable(isAvatarSet((GroupChat) chat));
} else {
// pull user info for duo chat
final List<ChatMember> members = chat.getMembers();
Long memberId = members.get(0).getId();
usersIds.add(memberId.equals(initiator.userId())
? memberId = members.get(1).getId()
: memberId
);

((DuoChatDto) chatDto).setUser(
CompanionDto.builder().id(memberId).build()
);
}

final Message lastMessage = chat.getLastMessage();
if (lastMessage == null) {
return chatDto;
}

final MessageDto messageDto = lastMessage.convert(modelMapper);

// save author ID for filling user data in the future
messageDto.setAuthor(MessageAuthorDto.builder()
.id(lastMessage.getAuthorId())
.build());
chatDto.setLastMessage(messageDto);

usersIds.add(lastMessage.getAuthorId());
return chatDto;
}

@Override
Expand All @@ -307,8 +311,8 @@ public void updateChat(@NonNull Chat chat) {
}

@Override
public Map<String, List<ChatMember>> getChatsMembers(Long userId, List<String> chatId) {
return chatRepository.findAllById(chatId)
public Map<String, List<ChatMember>> getChatsMembers(Long userId, List<String> chatIds) {
return chatRepository.findAllById(chatIds)
.stream()
.filter(chat -> isMember(userId, chat))
.collect(toMap(Chat::getId, Chat::getMembers));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.linkwave.chatservice.chat.duo;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.time.ZonedDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class CompanionDto {

private Long id;
private String username;
private String name;
private ZonedDateTime lastSeen;

@JsonProperty("online")
private boolean isOnline;

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.linkwave.chatservice.api.users.UserDto;
import org.linkwave.chatservice.chat.ChatDto;

@NoArgsConstructor
Expand All @@ -13,6 +12,6 @@
@SuperBuilder
public class DuoChatDto extends ChatDto {

private UserDto user;
private CompanionDto user;

}
102 changes: 97 additions & 5 deletions backend/chat-service/src/main/resources/static/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"items": {
"anyOf": [
{
"$ref": "#/components/schemas/ChatDto"
"$ref": "#/components/schemas/DuoChatDto"
},
{
"$ref": "#/components/schemas/GroupChatDto"
Expand Down Expand Up @@ -1034,6 +1034,10 @@
"type": "number",
"nullable": false
},
"avatarAvailable": {
"type": "boolean",
"nullable": false
},
"lastMessage": {
"$ref": "#/components/schemas/TextMessageDto"
}
Expand All @@ -1042,6 +1046,62 @@
"id": "65ed725dc636007bd4027c80",
"type": "DUO",
"createdAt": 1710060125.916620300,
"avatarAvailable": true,
"lastMessage": {
"id": "66055236cb761a59d173d978",
"action": "MESSAGE",
"createdAt": 1711624758.135000000,
"author": {
"id": 1,
"username": "@mathewmcc",
"name": "Matthew McConaughey"
},
"reactions": [],
"text": "Hi everyone!",
"edited": false,
"isRead": false
}
}
},
"DuoChatDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"nullable": false
},
"type": {
"type": "string",
"nullable": false,
"example": "DUO"
},
"createdAt": {
"type": "number",
"nullable": false
},
"avatarAvailable": {
"type": "boolean",
"nullable": false
},
"user": {
"$ref": "#/components/schemas/CompanionDto"
},
"lastMessage": {
"$ref": "#/components/schemas/TextMessageDto"
}
},
"example": {
"id": "65ed725dc636007bd4027c80",
"type": "DUO",
"createdAt": 1710060125.916620300,
"avatarAvailable": true,
"user": {
"id": 22,
"username": "@emmtlor",
"name": "Emma Taylor",
"lastSeen": 1707606183.446933000,
"online": false
},
"lastMessage": {
"id": "66055236cb761a59d173d978",
"action": "MESSAGE",
Expand Down Expand Up @@ -1096,9 +1156,9 @@
"type": "string",
"nullable": false
},
"avatarPath": {
"type": "string",
"nullable": true
"avatarAvailable": {
"type": "boolean",
"nullable": false
},
"createdAt": {
"type": "number",
Expand All @@ -1112,7 +1172,7 @@
"id": "65e8b0e4404b9356a273e305",
"type": "GROUP",
"name": "My group chat",
"avatarPath": null,
"avatarAvailable": true,
"createdAt": 1709748452.204932100,
"lastMessage": {
"id": "66055236cb761a59d173d978",
Expand Down Expand Up @@ -1466,6 +1526,38 @@
"contentType": "application/zip",
"size": 5012275
}
},
"CompanionDto": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"nullable": false
},
"username": {
"type": "string",
"nullable": false
},
"name": {
"type": "string",
"nullable": false
},
"lastSeen": {
"type": "number",
"nullable": false
},
"online": {
"type": "boolean",
"nullable": false
}
},
"example": {
"id": 22,
"username": "@emmtlor",
"name": "Emma Taylor",
"lastSeen": 1707606183.446933000,
"online": false
}
}
},
"headers": {
Expand Down

0 comments on commit d94a0da

Please sign in to comment.