Fix several bugs

These are:
- not immediately updating ChatScene if a contact was blocked and both
are online
- ContactSearchTab showing previously entered text on reopening (without
showing suggestions)
- users not getting notified if someone else blocked them while they
were offline
- no logger statements in UserUtil

Still to do:
- Move ContextMenu from chatList to ChatControl
- Test behavior for groups
This commit is contained in:
Leon Hofmeister 2020-10-13 23:51:02 +02:00 committed by KSKE Git
parent 571a953c40
commit dd477b6cbc
Signed by: Käfer & Engelbart Git
GPG Key ID: 70F2F9206EDC1FCE
6 changed files with 45 additions and 21 deletions

View File

@ -57,7 +57,9 @@ public class Chat implements Serializable {
}
@Override
public String toString() { return String.format("%s[recipient=%s,messages=%d]", getClass().getSimpleName(), recipient, messages.size()); }
public String toString() {
return String.format("%s[recipient=%s,messages=%d, disabled=%b]", getClass().getSimpleName(), recipient, messages.size(), disabled);
}
/**
* Generates a hash code based on the recipient.

View File

@ -1,11 +1,14 @@
package envoy.client.data;
import static java.util.function.Predicate.not;
import java.io.*;
import java.nio.channels.*;
import java.nio.file.StandardOpenOption;
import java.time.Instant;
import java.util.*;
import java.util.logging.*;
import java.util.stream.Stream;
import javafx.application.Platform;
import javafx.collections.*;
@ -35,12 +38,13 @@ public final class LocalDB implements EventListener {
// Data
private User user;
private Map<String, User> users = Collections.synchronizedMap(new HashMap<>());
private ObservableList<Chat> chats = FXCollections.observableArrayList();
private Map<String, User> users = Collections.synchronizedMap(new HashMap<>());
private ObservableList<Chat> chats = FXCollections.observableArrayList();
private IDGenerator idGenerator;
private CacheMap cacheMap = new CacheMap();
private CacheMap cacheMap = new CacheMap();
private String authToken;
private Set<? extends Contact> originalContacts = Set.of();
private boolean contactsChanged;
private Stream<Chat> changedChats;
// Auto save timer
private Timer autoSaver;
@ -138,7 +142,19 @@ public final class LocalDB implements EventListener {
if (user == null) throw new IllegalStateException("Client user is null, cannot initialize user storage");
userFile = new File(dbDir, user.getID() + ".db");
try (var in = new ObjectInputStream(new FileInputStream(userFile))) {
chats = FXCollections.observableList((List<Chat>) in.readObject());
chats = FXCollections.observableList((List<Chat>) in.readObject());
// Some chats have changed and should not be overridden by the saved values
if (changedChats != null) {
changedChats.forEach(chat -> {
final var chatIndex = chats.indexOf(chat);
if (chatIndex == -1) return;
else chats.set(chatIndex, chat);
});
// loadUserData can get called two (or more?) times during application lifecycle
changedChats = null;
}
cacheMap = (CacheMap) in.readObject();
lastSync = (Instant) in.readObject();
} finally {
@ -324,7 +340,7 @@ public final class LocalDB implements EventListener {
private void onOwnStatusChange(OwnStatusChange statusChange) { user.setStatus(statusChange.get()); }
@Event(eventType = ContactsChangedSinceLastLogin.class, priority = 500)
private void onContactsChangedSinceLastLogin() { if (user != null) originalContacts = user.getContacts(); }
private void onContactsChangedSinceLastLogin() { if (user != null) contactsChanged = true; }
/**
* @return a {@code Map<String, User>} of all users stored locally with their
@ -363,13 +379,12 @@ public final class LocalDB implements EventListener {
*/
public void setUserAndMergeContacts(User user) {
this.user = user;
if (originalContacts.isEmpty()) return;
else {
if (contactsChanged)
// mark all chats of deleted contacts
originalContacts.removeAll(user.getContacts());
originalContacts.forEach(contact -> getChat(contact.getID()).ifPresent(chat -> chat.setDisabled(true)));
}
// 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())))
.peek(chat -> { chat.setDisabled(true); logger.log(Level.INFO, String.format("Marked %s as blocked.", chat.getRecipient())); });
}
/**

View File

@ -272,8 +272,7 @@ public final class ChatScene implements EventListener, Restorable {
@Event
private void onUserOperation(UserOperation operation) {
// All ADD dependant logic resides in LocalDB
if (operation.getOperationType().equals(ElementOperation.REMOVE))
if (currentChat != null && currentChat.getRecipient().equals(operation.get())) Platform.runLater(this::resetState);
if (operation.getOperationType().equals(ElementOperation.REMOVE)) Platform.runLater(() -> disableChat(operation.get(), true));
}
@Event

View File

@ -124,5 +124,8 @@ public class ContactSearchTab implements EventListener {
}
@FXML
private void backButtonClicked() { eventBus.dispatch(new BackEvent()); }
private void backButtonClicked() {
searchBar.setText("");
eventBus.dispatch(new BackEvent());
}
}

View File

@ -82,7 +82,7 @@ public class GroupCreationTab implements EventListener {
.map(User.class::cast)
.collect(Collectors.toList()));
resizeQuickSelectSpace(0);
quickSelectList.addEventFilter(MouseEvent.MOUSE_PRESSED, evt -> evt.consume());
quickSelectList.addEventFilter(MouseEvent.MOUSE_PRESSED, MouseEvent::consume);
}
/**
@ -169,7 +169,7 @@ public class GroupCreationTab implements EventListener {
/**
* Removes an element from the quickSelectList.
*
*
* @param element the element to be removed.
* @since Envoy Client v0.3-beta
*/
@ -238,7 +238,7 @@ public class GroupCreationTab implements EventListener {
Platform.runLater(() -> {
switch (operation.getOperationType()) {
case ADD:
userList.getItems().add((User) operation.get());
userList.getItems().add(operation.get());
break;
case REMOVE:
userList.getItems().removeIf(operation.get()::equals);

View File

@ -1,6 +1,6 @@
package envoy.client.util;
import java.util.logging.Level;
import java.util.logging.*;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
@ -26,7 +26,8 @@ import dev.kske.eventbus.EventBus;
*/
public final class UserUtil {
private static final Context context = Context.getInstance();
private static final Context context = Context.getInstance();
private static final Logger logger = EnvoyLog.getLogger(UserUtil.class);
private UserUtil() {}
@ -46,6 +47,7 @@ public final class UserUtil {
EventBus.getInstance().dispatch(new EnvoyCloseEvent());
EventBus.getInstance().dispatch(new Logout());
context.getSceneContext().load(SceneInfo.LOGIN_SCENE);
logger.log(Level.INFO, "A logout occurred.");
});
}
@ -63,6 +65,7 @@ public final class UserUtil {
else {
EventBus.getInstance().dispatch(new OwnStatusChange(newStatus));
if (context.getClient().isOnline()) context.getClient().send(new UserStatusChange(context.getLocalDB().getUser().getID(), newStatus));
logger.log(Level.INFO, "A manual status change occurred.");
}
}
@ -87,6 +90,7 @@ public final class UserUtil {
context.getLocalDB().getChat(block.getID()).ifPresent(chat -> chat.setDisabled(true));
final var controller = context.getSceneContext().getController();
if (controller instanceof ChatScene) ((ChatScene) controller).disableChat(block, true);
logger.log(Level.INFO, "A contact was blocked.");
});
}
}
@ -108,6 +112,7 @@ public final class UserUtil {
context.getLocalDB().getChats().removeIf(chat -> chat.getRecipient().equals(delete));
if (context.getSceneContext().getController() instanceof ChatScene)
((ChatScene) context.getSceneContext().getController()).resetState();
logger.log(Level.INFO, "A contact with all his messages was deleted.");
});
}
}