Add working leaving of a group
Additionally fixed a two bugs: - one group member will no longer show "1 members" - deletion of empty groups no longer throws an exception
This commit is contained in:
parent
bdb964a0d1
commit
c4d4708988
@ -379,12 +379,27 @@ public final class LocalDB implements EventListener {
|
||||
*/
|
||||
public void setUserAndMergeContacts(User user) {
|
||||
this.user = user;
|
||||
if (contactsChanged)
|
||||
if (contactsChanged) {
|
||||
final var contacts = user.getContacts();
|
||||
|
||||
// Mark chats as disabled if a contact is no longer in this users contact list
|
||||
changedChats = chats.stream()
|
||||
.filter(not(chat -> user.getContacts().contains(chat.getRecipient())))
|
||||
final var changedUserChats = chats.stream()
|
||||
.filter(not(chat -> contacts.contains(chat.getRecipient())))
|
||||
.peek(chat -> { chat.setDisabled(true); logger.log(Level.INFO, String.format("Marked %s as blocked.", chat.getRecipient())); });
|
||||
|
||||
// Also update groups with a different member count
|
||||
final var changedGroupChats = contacts.stream().filter(Group.class::isInstance).flatMap(group -> {
|
||||
final var potentialChat = getChat(group.getID());
|
||||
if (potentialChat.isEmpty()) return Stream.empty();
|
||||
final var chat = potentialChat.get();
|
||||
if (group.getContacts().size() != chat.getRecipient().getContacts().size()) {
|
||||
logger.log(Level.INFO, "Removed one (or more) members from " + group);
|
||||
return Stream.of(chat);
|
||||
} else return Stream.empty();
|
||||
});
|
||||
|
||||
changedChats = Stream.concat(changedUserChats, changedGroupChats);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,5 +16,7 @@ public final class GroupSizeLabel extends Label {
|
||||
* @param recipient the group whose members to show
|
||||
* @since Envoy Client v0.3-beta
|
||||
*/
|
||||
public GroupSizeLabel(Group recipient) { super(recipient.getContacts().size() + " members"); }
|
||||
public GroupSizeLabel(Group recipient) {
|
||||
super(recipient.getContacts().size() + " member" + (recipient.getContacts().size() != 1 ? "s" : ""));
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +281,8 @@ public final class ChatScene implements EventListener, Restorable {
|
||||
|
||||
// Update the top-bar status label if all conditions apply
|
||||
if (currentChat != null && currentChat.getRecipient().equals(chatFound.get().getRecipient()))
|
||||
topBarStatusLabel.setText(chatFound.get().getRecipient().getContacts().size() + " members");
|
||||
topBarStatusLabel.setText(chatFound.get().getRecipient().getContacts().size() + " member"
|
||||
+ (currentChat.getRecipient().getContacts().size() != 1 ? "s" : ""));
|
||||
});
|
||||
}
|
||||
|
||||
@ -383,7 +384,8 @@ public final class ChatScene implements EventListener, Restorable {
|
||||
topBarStatusLabel.setVisible(true);
|
||||
recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
|
||||
} else {
|
||||
topBarStatusLabel.setText(currentChat.getRecipient().getContacts().size() + " members");
|
||||
topBarStatusLabel.setText(currentChat.getRecipient().getContacts().size() + " member"
|
||||
+ (currentChat.getRecipient().getContacts().size() != 1 ? "s" : ""));
|
||||
topBarStatusLabel.getStyleClass().clear();
|
||||
recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43));
|
||||
}
|
||||
@ -752,7 +754,13 @@ public final class ChatScene implements EventListener, Restorable {
|
||||
* @since Envoy Client v0.3-beta
|
||||
*/
|
||||
public void disableChat(Contact recipient, boolean refreshChatList) {
|
||||
if (refreshChatList) chatList.refresh();
|
||||
if (refreshChatList) {
|
||||
chatList.refresh();
|
||||
|
||||
// Decrement member count for groups
|
||||
if (recipient instanceof Group)
|
||||
topBarStatusLabel.setText(recipient.getContacts().size() + " member" + (recipient.getContacts().size() != 1 ? "s" : ""));
|
||||
}
|
||||
if (currentChat != null && currentChat.getRecipient().equals(recipient)) {
|
||||
messageTextArea.setDisable(true);
|
||||
voiceButton.setDisable(true);
|
||||
|
@ -82,15 +82,19 @@ public final class UserUtil {
|
||||
if (!context.getClient().isOnline() || block == null) return;
|
||||
else {
|
||||
final var alert = new Alert(AlertType.CONFIRMATION);
|
||||
alert.setContentText("Are you sure you want to block " + block.getName() + "?");
|
||||
alert.setContentText("Are you sure you want to " + (block instanceof User ? "block " : "leave group ") + block.getName() + "?");
|
||||
AlertHelper.confirmAction(alert, () -> {
|
||||
context.getClient()
|
||||
.send(block instanceof User ? new UserOperation((User) block, ElementOperation.REMOVE)
|
||||
: new GroupResize(context.getLocalDB().getUser(), (Group) block, ElementOperation.REMOVE));
|
||||
context.getLocalDB().getChat(block.getID()).ifPresent(chat -> chat.setDisabled(true));
|
||||
if (block instanceof User) logger.log(Level.INFO, "A user was blocked.");
|
||||
else {
|
||||
block.getContacts().remove(context.getLocalDB().getUser());
|
||||
logger.log(Level.INFO, "The user left a group.");
|
||||
}
|
||||
final var controller = context.getSceneContext().getController();
|
||||
if (controller instanceof ChatScene) ((ChatScene) controller).disableChat(block, true);
|
||||
logger.log(Level.INFO, "A contact was blocked.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ public final class Startup {
|
||||
new MessageStatusChangeProcessor(),
|
||||
new GroupMessageStatusChangeProcessor(),
|
||||
new UserStatusChangeProcessor(),
|
||||
new GroupResizeProcessor(),
|
||||
new IDGeneratorRequestProcessor(),
|
||||
new UserSearchProcessor(),
|
||||
new UserOperationProcessor(),
|
||||
|
@ -51,7 +51,7 @@ public class Message {
|
||||
@Id
|
||||
protected long id;
|
||||
|
||||
@ManyToOne
|
||||
@ManyToOne(cascade = CascadeType.REMOVE)
|
||||
@JoinColumn
|
||||
protected User sender;
|
||||
|
||||
|
@ -105,11 +105,6 @@ public final class PersistenceManager {
|
||||
// Remove this contact from the contact list of his contacts
|
||||
for (final var remainingContact : contact.getContacts())
|
||||
remainingContact.getContacts().remove(contact);
|
||||
|
||||
// Delete messages sent or received by this contact
|
||||
entityManager.createQuery("DELETE FROM Message m WHERE (m.sender = :contact OR m.recipient = :contact )")
|
||||
.setParameter("contact", contact)
|
||||
.executeUpdate();
|
||||
});
|
||||
remove(contact);
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
package envoy.server.processors;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import envoy.event.GroupResize;
|
||||
import envoy.server.data.*;
|
||||
import envoy.server.net.*;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
/**
|
||||
* @author Maximilian Käfer
|
||||
@ -11,34 +15,37 @@ import envoy.server.net.*;
|
||||
public final class GroupResizeProcessor implements ObjectProcessor<GroupResize> {
|
||||
|
||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
|
||||
@Override
|
||||
public void process(GroupResize groupResize, long socketID, ObjectWriteProxy writeProxy) {
|
||||
|
||||
// Acquire the group to resize from the database
|
||||
var group = persistenceManager.getGroupByID(groupResize.getGroupID());
|
||||
final var group = persistenceManager.getGroupByID(groupResize.getGroupID());
|
||||
final var sender = persistenceManager.getUserByID(groupResize.get().getID());
|
||||
|
||||
// Perform the desired operation
|
||||
switch (groupResize.getOperation()) {
|
||||
case ADD:
|
||||
group.getContacts().add(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
break;
|
||||
persistenceManager.addContactBidirectional(sender, group);
|
||||
writeProxy.writeToOnlineContacts(group.getContacts(), group.toCommon());
|
||||
return;
|
||||
case REMOVE:
|
||||
persistenceManager.removeContactBidirectional(sender, group);
|
||||
sender.setLatestContactDeletion(Instant.now());
|
||||
|
||||
// The group has no more members and hence will be deleted
|
||||
if (group.getContacts().isEmpty()) {
|
||||
EnvoyLog.getLogger(GroupResizeProcessor.class).log(Level.INFO, "Deleting now empty group " + group.getName());
|
||||
persistenceManager.deleteContact(group);
|
||||
} else {
|
||||
|
||||
// Informing the other members
|
||||
writeProxy.writeToOnlineContacts(group.getContacts(), groupResize);
|
||||
group.getContacts().forEach(c -> ((User) c).setLatestContactDeletion(Instant.now()));
|
||||
}
|
||||
|
||||
group.getContacts().remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the group in the database
|
||||
persistenceManager.updateContact(group);
|
||||
|
||||
// Send the updated group to all of its members
|
||||
var commonGroup = group.toCommon();
|
||||
group.getContacts()
|
||||
.stream()
|
||||
.map(Contact::getID)
|
||||
.filter(connectionManager::isOnline)
|
||||
.map(connectionManager::getSocketID)
|
||||
.forEach(memberSocketID -> writeProxy.write(memberSocketID, commonGroup));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user