Contact Deletion #97
@ -379,12 +379,27 @@ public final class LocalDB implements EventListener {
|
|||||||
*/
|
*/
|
||||||
public void setUserAndMergeContacts(User user) {
|
public void setUserAndMergeContacts(User user) {
|
||||||
this.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
|
// Mark chats as disabled if a contact is no longer in this users contact list
|
||||||
changedChats = chats.stream()
|
final var changedUserChats = chats.stream()
|
||||||
.filter(not(chat -> user.getContacts().contains(chat.getRecipient())))
|
.filter(not(chat -> contacts.contains(chat.getRecipient())))
|
||||||
.peek(chat -> { chat.setDisabled(true); logger.log(Level.INFO, String.format("Marked %s as blocked.", 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
|
* @param recipient the group whose members to show
|
||||||
* @since Envoy Client v0.3-beta
|
* @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
|
// Update the top-bar status label if all conditions apply
|
||||||
if (currentChat != null && currentChat.getRecipient().equals(chatFound.get().getRecipient()))
|
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);
|
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));
|
recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
|
||||||
} else {
|
} else {
|
||||||
topBarStatusLabel.setText(currentChat.getRecipient().getContacts().size() + " members");
|
topBarStatusLabel.setText(currentChat.getRecipient().getContacts().size() + " member"
|
||||||
|
+ (currentChat.getRecipient().getContacts().size() != 1 ? "s" : ""));
|
||||||
topBarStatusLabel.getStyleClass().clear();
|
topBarStatusLabel.getStyleClass().clear();
|
||||||
recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43));
|
recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43));
|
||||||
}
|
}
|
||||||
@ -752,7 +754,13 @@ public final class ChatScene implements EventListener, Restorable {
|
|||||||
* @since Envoy Client v0.3-beta
|
* @since Envoy Client v0.3-beta
|
||||||
*/
|
*/
|
||||||
public void disableChat(Contact recipient, boolean refreshChatList) {
|
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)) {
|
if (currentChat != null && currentChat.getRecipient().equals(recipient)) {
|
||||||
messageTextArea.setDisable(true);
|
messageTextArea.setDisable(true);
|
||||||
voiceButton.setDisable(true);
|
voiceButton.setDisable(true);
|
||||||
|
@ -82,15 +82,19 @@ public final class UserUtil {
|
|||||||
if (!context.getClient().isOnline() || block == null) return;
|
if (!context.getClient().isOnline() || block == null) return;
|
||||||
else {
|
else {
|
||||||
final var alert = new Alert(AlertType.CONFIRMATION);
|
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, () -> {
|
AlertHelper.confirmAction(alert, () -> {
|
||||||
context.getClient()
|
context.getClient()
|
||||||
.send(block instanceof User ? new UserOperation((User) block, ElementOperation.REMOVE)
|
.send(block instanceof User ? new UserOperation((User) block, ElementOperation.REMOVE)
|
||||||
: new GroupResize(context.getLocalDB().getUser(), (Group) block, ElementOperation.REMOVE));
|
: new GroupResize(context.getLocalDB().getUser(), (Group) block, ElementOperation.REMOVE));
|
||||||
context.getLocalDB().getChat(block.getID()).ifPresent(chat -> chat.setDisabled(true));
|
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();
|
final var controller = context.getSceneContext().getController();
|
||||||
if (controller instanceof ChatScene) ((ChatScene) controller).disableChat(block, true);
|
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 MessageStatusChangeProcessor(),
|
||||||
new GroupMessageStatusChangeProcessor(),
|
new GroupMessageStatusChangeProcessor(),
|
||||||
new UserStatusChangeProcessor(),
|
new UserStatusChangeProcessor(),
|
||||||
|
new GroupResizeProcessor(),
|
||||||
new IDGeneratorRequestProcessor(),
|
new IDGeneratorRequestProcessor(),
|
||||||
new UserSearchProcessor(),
|
new UserSearchProcessor(),
|
||||||
new UserOperationProcessor(),
|
new UserOperationProcessor(),
|
||||||
|
@ -51,7 +51,7 @@ public class Message {
|
|||||||
@Id
|
@Id
|
||||||
protected long id;
|
protected long id;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne(cascade = CascadeType.REMOVE)
|
||||||
@JoinColumn
|
@JoinColumn
|
||||||
protected User sender;
|
protected User sender;
|
||||||
|
|
||||||
|
@ -105,11 +105,6 @@ public final class PersistenceManager {
|
|||||||
// Remove this contact from the contact list of his contacts
|
// Remove this contact from the contact list of his contacts
|
||||||
for (final var remainingContact : contact.getContacts())
|
for (final var remainingContact : contact.getContacts())
|
||||||
remainingContact.getContacts().remove(contact);
|
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);
|
remove(contact);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package envoy.server.processors;
|
package envoy.server.processors;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import envoy.event.GroupResize;
|
import envoy.event.GroupResize;
|
||||||
import envoy.server.data.*;
|
import envoy.server.data.*;
|
||||||
import envoy.server.net.*;
|
import envoy.server.net.ObjectWriteProxy;
|
||||||
|
import envoy.util.EnvoyLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Maximilian Käfer
|
* @author Maximilian Käfer
|
||||||
@ -10,35 +14,38 @@ import envoy.server.net.*;
|
|||||||
*/
|
*/
|
||||||
public final class GroupResizeProcessor implements ObjectProcessor<GroupResize> {
|
public final class GroupResizeProcessor implements ObjectProcessor<GroupResize> {
|
||||||
|
|
||||||
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
|
||||||
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(GroupResize groupResize, long socketID, ObjectWriteProxy writeProxy) {
|
public void process(GroupResize groupResize, long socketID, ObjectWriteProxy writeProxy) {
|
||||||
|
|
||||||
// Acquire the group to resize from the database
|
// 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
|
// Perform the desired operation
|
||||||
switch (groupResize.getOperation()) {
|
switch (groupResize.getOperation()) {
|
||||||
case ADD:
|
case ADD:
|
||||||
group.getContacts().add(persistenceManager.getUserByID(groupResize.get().getID()));
|
persistenceManager.addContactBidirectional(sender, group);
|
||||||
break;
|
writeProxy.writeToOnlineContacts(group.getContacts(), group.toCommon());
|
||||||
|
return;
|
||||||
case REMOVE:
|
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()));
|
group.getContacts().remove(persistenceManager.getUserByID(groupResize.get().getID()));
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user
Maybe log 'Disabled chat ...' here instead.