Contact Deletion #97
@ -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())); });
|
||||
delvh marked this conversation as resolved
Outdated
|
||||
|
||||
// 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" : ""));
|
||||
delvh marked this conversation as resolved
kske
commented
We could just use parentheses, but I guess this is less ambiguous. We could just use parentheses, but I guess this is less ambiguous.
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
delvh marked this conversation as resolved
Outdated
kske
commented
This is unnecessary (your words). This is unnecessary (your words).
|
||||
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);
|
||||
delvh marked this conversation as resolved
kske
commented
Use an event here instead. This would also simplify the interaction with the local database. Use an event here instead. This would also simplify the interaction with the local database.
|
||||
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:
|
||||
group.getContacts().remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
break;
|
||||
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()));
|
||||
}
|
||||
|
||||
// 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));
|
||||
group.getContacts().remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user
Maybe log 'Disabled chat ...' here instead.