From 22eec113ff35b3c0479f69acc83c90c8e7093d5b Mon Sep 17 00:00:00 2001
From: Marc-Spector <38242291+Marc-Spector@users.noreply.github.com>
Date: Tue, 12 Apr 2022 01:30:23 +0300
Subject: [PATCH] Redesign context menu (#2596)
---
readme.md | 8 +-
.../client/chat/ChatUserItemController.java | 4 +-
.../fx/contextmenu/AbstractMenuItem.java | 19 +++++
.../CancelActionNotifyMeMenuItem.java | 5 ++
...celActionRunReplayImmediatelyMenuItem.java | 5 ++
.../ChangeUsernameColorMenuItem.java | 48 +++++++++++
.../fx/contextmenu/CopyLabelMenuItem.java | 5 ++
.../fx/contextmenu/CopyUsernameMenuItem.java | 5 ++
.../contextmenu/EditPlayerNoteMenuItem.java | 5 ++
.../fx/contextmenu/NotifyMeMenuItem.java | 5 ++
.../fx/contextmenu/ReportPlayerMenuItem.java | 5 ++
.../RunReplayImmediatelyMenuItem.java | 5 ++
.../SendPrivateMessageClanLeaderMenuItem.java | 5 ++
.../SendPrivateMessageMenuItem.java | 5 ++
.../contextmenu/ShowPlayerInfoMenuItem.java | 5 ++
.../fx/contextmenu/ViewReplaysMenuItem.java | 5 ++
.../fx/contextmenu/WatchGameMenuItem.java | 5 ++
src/main/resources/i18n/messages.properties | 1 +
src/main/resources/theme/colors.css | 4 +
src/main/resources/theme/icons.css | 24 ++++++
src/main/resources/theme/style.css | 21 ++++-
.../ChangeUsernameColorMenuItemTest.java | 84 +++++++++++++++++++
22 files changed, 271 insertions(+), 7 deletions(-)
create mode 100644 src/main/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItem.java
create mode 100644 src/test/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItemTest.java
diff --git a/readme.md b/readme.md
index 08dfa22781..9f8c4c309c 100644
--- a/readme.md
+++ b/readme.md
@@ -32,12 +32,12 @@ A video tutorial is available [here](https://youtu.be/6gsHnt02I_Y). Don't forget
Learn how to install the client on Linux [here](https://github.com/FAForever/downlords-faf-client/wiki/Install-on-Linux)
## Open Source licenses
-| | |
+| | |
|----------------|-------------------------------|
-||Thanks to [ej-technologies](https://www.ej-technologies.com) for their [open source license](https://www.ej-technologies.com/buy/install4j/openSource). We use Install4j to build installers.|
-|| Thanks to [bugsnag](https://www.bugsnag.com) for their [open source license](https://www.bugsnag.com/open-source/). We use bugsnag for our error reporting.|
+| | Thanks to [ej-technologies](https://www.ej-technologies.com) for their [open source license](https://www.ej-technologies.com/buy/install4j/openSource). We use Install4j to build installers. |
+| | Thanks to [bugsnag](https://www.bugsnag.com) for their [open source license](https://www.bugsnag.com/open-source/). We use bugsnag for our error reporting. |
|| Thanks to [YourKit](https://www.yourkit.com) for their open source license.|
-|| Thanks to [Twemoji Twitter](https://twemoji.twitter.com/) for their open source license. We use and display emojis in the chats.|
+| | Thanks to [Twemoji Twitter](https://twemoji.twitter.com/) for their open source license. We use and display emojis in the chats. |
## Contribute
diff --git a/src/main/java/com/faforever/client/chat/ChatUserItemController.java b/src/main/java/com/faforever/client/chat/ChatUserItemController.java
index 5e2b9f8816..cbe3a33a25 100644
--- a/src/main/java/com/faforever/client/chat/ChatUserItemController.java
+++ b/src/main/java/com/faforever/client/chat/ChatUserItemController.java
@@ -8,7 +8,7 @@
import com.faforever.client.fx.contextmenu.AddFoeMenuItem;
import com.faforever.client.fx.contextmenu.AddFriendMenuItem;
import com.faforever.client.fx.contextmenu.BroadcastMessageMenuItem;
-import com.faforever.client.fx.contextmenu.ChatUserColorPickerCustomMenuItemController;
+import com.faforever.client.fx.contextmenu.ChangeUsernameColorMenuItem;
import com.faforever.client.fx.contextmenu.ContextMenuBuilder;
import com.faforever.client.fx.contextmenu.CopyUsernameMenuItem;
import com.faforever.client.fx.contextmenu.InvitePlayerMenuItem;
@@ -156,7 +156,7 @@ public void onContextMenuRequested(ContextMenuEvent event) {
.addItem(ShowPlayerInfoMenuItem.class, player)
.addItem(SendPrivateMessageMenuItem.class, chatUser.getUsername())
.addItem(CopyUsernameMenuItem.class, chatUser.getUsername())
- .addCustomItem(uiService.loadFxml("theme/chat/color_picker_menu_item.fxml", ChatUserColorPickerCustomMenuItemController.class), chatUser)
+ .addItem(ChangeUsernameColorMenuItem.class, chatUser)
.addSeparator()
.addItem(SendPrivateMessageClanLeaderMenuItem.class, chatUser.getClan().orElse(null))
.addItem(OpenClanUrlMenuItem.class, chatUser.getClan().orElse(null))
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/AbstractMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/AbstractMenuItem.java
index adf30b4ff9..2e0517ffa3 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/AbstractMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/AbstractMenuItem.java
@@ -1,6 +1,7 @@
package com.faforever.client.fx.contextmenu;
import javafx.scene.control.MenuItem;
+import javafx.scene.layout.Region;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -20,11 +21,29 @@ private void finalizeProperties() {
if (isItemVisible()) {
setOnAction(event -> onClicked());
setText(getItemText());
+ setIcon();
} else {
setVisible(false);
}
}
+ private void setIcon() {
+ String styleIcon = getStyleIcon();
+ if (styleIcon != null) {
+ setGraphic(initializeIcon(styleIcon));
+ }
+ }
+
+ private Region initializeIcon(String styleIcon) {
+ Region iconView = new Region();
+ iconView.getStyleClass().addAll("icon", "icon16x16", styleIcon);
+ return iconView;
+ }
+
+ protected String getStyleIcon() {
+ return null; // by-default
+ }
+
protected abstract void onClicked();
protected abstract String getItemText();
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/CancelActionNotifyMeMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/CancelActionNotifyMeMenuItem.java
index 227fa70b04..1a2cbc75d5 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/CancelActionNotifyMeMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/CancelActionNotifyMeMenuItem.java
@@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.stopTrackingLiveReplay();
}
+ @Override
+ protected String getStyleIcon() {
+ return "close-icon";
+ }
+
@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/CancelActionRunReplayImmediatelyMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/CancelActionRunReplayImmediatelyMenuItem.java
index 9bf7bf79a0..d36a363f27 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/CancelActionRunReplayImmediatelyMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/CancelActionRunReplayImmediatelyMenuItem.java
@@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.stopTrackingLiveReplay();
}
+ @Override
+ protected String getStyleIcon() {
+ return "close-icon";
+ }
+
@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItem.java
new file mode 100644
index 0000000000..a861c4a161
--- /dev/null
+++ b/src/main/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItem.java
@@ -0,0 +1,48 @@
+package com.faforever.client.fx.contextmenu;
+
+import com.faforever.client.chat.ChatChannelUser;
+import com.faforever.client.i18n.I18n;
+import com.faforever.client.preferences.PreferencesService;
+import com.faforever.client.theme.UiService;
+import com.faforever.client.ui.StageHolder;
+import com.faforever.client.util.Assert;
+import javafx.geometry.Bounds;
+import javafx.scene.Node;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import static com.faforever.client.chat.ChatColorMode.RANDOM;
+
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+@RequiredArgsConstructor
+public class ChangeUsernameColorMenuItem extends AbstractMenuItem {
+
+ private final PreferencesService preferencesService;
+ private final UiService uiService;
+ private final I18n i18n;
+ private final ContextMenuBuilder contextMenuBuilder;
+
+ @Override
+ protected void onClicked() {
+ Assert.checkNullIllegalState(object, "no chat user has been set");
+ Node node = getStyleableNode();
+ Bounds screenBounds = node.localToScreen(node.getBoundsInLocal());
+ contextMenuBuilder.newBuilder()
+ .addCustomItem(uiService.loadFxml("theme/chat/color_picker_menu_item.fxml", ChatUserColorPickerCustomMenuItemController.class), object)
+ .build()
+ .show(StageHolder.getStage(), screenBounds.getMinX(), screenBounds.getMinY());
+ }
+
+ @Override
+ protected boolean isItemVisible() {
+ return object != null && !preferencesService.getPreferences().getChat().getChatColorMode().equals(RANDOM);
+ }
+
+ @Override
+ protected String getItemText() {
+ return i18n.get("chat.userContext.changeColor");
+ }
+}
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/CopyLabelMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/CopyLabelMenuItem.java
index 4f2b4c97f0..8b37fd4836 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/CopyLabelMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/CopyLabelMenuItem.java
@@ -25,6 +25,11 @@ protected void onClicked() {
ClipboardUtil.copyToClipboard(object.getText());
}
+ @Override
+ protected String getStyleIcon() {
+ return "copy-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null && !StringUtils.isBlank(object.getText());
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/CopyUsernameMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/CopyUsernameMenuItem.java
index 784b5041b8..fd202dae26 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/CopyUsernameMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/CopyUsernameMenuItem.java
@@ -22,6 +22,11 @@ protected void onClicked() {
ClipboardUtil.copyToClipboard(object);
}
+ @Override
+ protected String getStyleIcon() {
+ return "copy-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return !StringUtils.isBlank(object);
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/EditPlayerNoteMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/EditPlayerNoteMenuItem.java
index 928af8bc78..60083389dc 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/EditPlayerNoteMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/EditPlayerNoteMenuItem.java
@@ -32,6 +32,11 @@ protected void onClicked() {
dialog.show();
}
+ @Override
+ protected String getStyleIcon() {
+ return "mode-edit-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/NotifyMeMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/NotifyMeMenuItem.java
index e2a386391a..ebf7bf4850 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/NotifyMeMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/NotifyMeMenuItem.java
@@ -38,6 +38,11 @@ protected boolean isItemVisible() {
.anyMatch(trackingLiveReplay -> !trackingLiveReplay.getGameId().equals(object.getId()) || trackingLiveReplay.getAction() != NOTIFY_ME);
}
+ @Override
+ protected String getStyleIcon() {
+ return "notification-none-icon";
+ }
+
@Override
protected String getItemText() {
return i18n.get("vault.liveReplays.contextMenu.notifyMe");
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/ReportPlayerMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/ReportPlayerMenuItem.java
index 23fe186e80..137c81b5f6 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/ReportPlayerMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/ReportPlayerMenuItem.java
@@ -29,6 +29,11 @@ protected void onClicked() {
reportDialogController.show();
}
+ @Override
+ protected String getStyleIcon() {
+ return "assignment-late-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null && object.getSocialStatus() != SELF;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/RunReplayImmediatelyMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/RunReplayImmediatelyMenuItem.java
index 6d20035ea3..78e6e4cfc9 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/RunReplayImmediatelyMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/RunReplayImmediatelyMenuItem.java
@@ -26,6 +26,11 @@ protected void onClicked() {
liveReplayService.performActionWhenAvailable(object, RUN_REPLAY);
}
+ @Override
+ protected String getStyleIcon() {
+ return "play-circle-outline-icon";
+ }
+
@Override
protected boolean isItemVisible() {
boolean isValid = object != null && object.getStartTime() != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageClanLeaderMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageClanLeaderMenuItem.java
index ac44e2cd5a..cbcb0f45ac 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageClanLeaderMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageClanLeaderMenuItem.java
@@ -26,6 +26,11 @@ protected void onClicked() {
eventBus.post(new InitiatePrivateChatEvent(object.getLeader().getUsername()));
}
+ @Override
+ protected String getStyleIcon() {
+ return "bubble-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null && !playerService.getCurrentPlayer().getId().equals(object.getLeader().getId())
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageMenuItem.java
index 39bc2d84a0..683560f96c 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/SendPrivateMessageMenuItem.java
@@ -28,6 +28,11 @@ protected void onClicked() {
eventBus.post(new InitiatePrivateChatEvent(object));
}
+ @Override
+ protected String getStyleIcon() {
+ return "bubble-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return !StringUtils.isBlank(object)
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/ShowPlayerInfoMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/ShowPlayerInfoMenuItem.java
index 8e71c04d51..ddcb6bacdf 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/ShowPlayerInfoMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/ShowPlayerInfoMenuItem.java
@@ -27,6 +27,11 @@ protected void onClicked() {
controller.show();
}
+ @Override
+ protected String getStyleIcon() {
+ return "info-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/ViewReplaysMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/ViewReplaysMenuItem.java
index 0c659c8ace..96be58fbee 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/ViewReplaysMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/ViewReplaysMenuItem.java
@@ -24,6 +24,11 @@ protected void onClicked() {
eventBus.post(new ShowUserReplaysEvent(object.getId()));
}
+ @Override
+ protected String getStyleIcon() {
+ return "search-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null;
diff --git a/src/main/java/com/faforever/client/fx/contextmenu/WatchGameMenuItem.java b/src/main/java/com/faforever/client/fx/contextmenu/WatchGameMenuItem.java
index 8ac9fc51e1..9a18f429f2 100644
--- a/src/main/java/com/faforever/client/fx/contextmenu/WatchGameMenuItem.java
+++ b/src/main/java/com/faforever/client/fx/contextmenu/WatchGameMenuItem.java
@@ -33,6 +33,11 @@ protected void onClicked() {
}
}
+ @Override
+ protected String getStyleIcon() {
+ return "play-circle-outline-icon";
+ }
+
@Override
protected boolean isItemVisible() {
return object != null && object.getStatus() == PlayerStatus.PLAYING;
diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties
index 52853954d1..65fedbc60b 100644
--- a/src/main/resources/i18n/messages.properties
+++ b/src/main/resources/i18n/messages.properties
@@ -119,6 +119,7 @@ chat.userContext.viewReplays = View replays
chat.userContext.inviteToGame = Invite to party
chat.userContext.kick = Kick…
chat.userContext.ban = Ban…
+chat.userContext.changeColor = Change color
chat.userContext.addNote = Add note
chat.userContext.editNote = Edit note
chat.userContext.removeNote = Remove note
diff --git a/src/main/resources/theme/colors.css b/src/main/resources/theme/colors.css
index 59df61ef49..2e1a63c874 100644
--- a/src/main/resources/theme/colors.css
+++ b/src/main/resources/theme/colors.css
@@ -40,6 +40,10 @@
-fx-text-color: #fff;
-darkened-color: dimgrey;
+ -context-menu-color: #3c3f41;
+ -context-menu-border-color: #868686;
+ -menu-item-label-color: #DCDCDC;
+
FRIEND_IN_GAME_NOT_SELECTED_ITEM: rgba(42, 253, 53, 0.1);
FRIEND_IN_GAME_SELECTED_ITEM: rgba(42, 253, 53, 0.35);
}
diff --git a/src/main/resources/theme/icons.css b/src/main/resources/theme/icons.css
index e283e8c9b2..bcbed48039 100644
--- a/src/main/resources/theme/icons.css
+++ b/src/main/resources/theme/icons.css
@@ -285,4 +285,28 @@
.settings-icon {
-fx-shape: "M8 10.344c1.281 0 2.344-1.063 2.344-2.344s-1.063-2.344-2.344-2.344-2.344 1.063-2.344 2.344 1.063 2.344 2.344 2.344zM12.969 8.656l1.406 1.094c0.125 0.094 0.156 0.281 0.063 0.438l-1.344 2.313c-0.094 0.156-0.25 0.188-0.406 0.125l-1.656-0.656c-0.344 0.25-0.719 0.5-1.125 0.656l-0.25 1.75c-0.031 0.156-0.156 0.281-0.313 0.281h-2.688c-0.156 0-0.281-0.125-0.313-0.281l-0.25-1.75c-0.406-0.156-0.781-0.375-1.125-0.656l-1.656 0.656c-0.156 0.063-0.313 0.031-0.406-0.125l-1.344-2.313c-0.094-0.156-0.063-0.344 0.063-0.438l1.406-1.094c-0.031-0.219-0.031-0.438-0.031-0.656s0-0.438 0.031-0.656l-1.406-1.094c-0.125-0.094-0.156-0.281-0.063-0.438l1.344-2.313c0.094-0.156 0.25-0.188 0.406-0.125l1.656 0.656c0.344-0.25 0.719-0.5 1.125-0.656l0.25-1.75c0.031-0.156 0.156-0.281 0.313-0.281h2.688c0.156 0 0.281 0.125 0.313 0.281l0.25 1.75c0.406 0.156 0.781 0.375 1.125 0.656l1.656-0.656c0.156-0.063 0.313-0.031 0.406 0.125l1.344 2.313c0.094 0.156 0.063 0.344-0.063 0.438l-1.406 1.094c0.031 0.219 0.031 0.438 0.031 0.656s0 0.438-0.031 0.656z";
+}
+
+.copy-icon {
+ -fx-shape: "M20 8v-8h-14l-6 6v18h12v8h20v-24h-12zM6 2.828v3.172h-3.172l3.172-3.172zM2 22v-14h6v-6h10v6l-6 6v8h-10zM18 10.828v3.172h-3.172l3.172-3.172zM30 30h-16v-14h6v-6h10v20z";
+}
+
+.bubble-icon {
+ -fx-shape: "M16 6c-1.717 0-3.375 0.271-4.928 0.804-1.46 0.502-2.76 1.211-3.863 2.108-2.069 1.681-3.209 3.843-3.209 6.088 0 1.259 0.35 2.481 1.039 3.63 0.711 1.185 1.781 2.268 3.093 3.133 0.949 0.625 1.587 1.623 1.755 2.747 0.056 0.375 0.091 0.753 0.105 1.129 0.233-0.194 0.461-0.401 0.684-0.624 0.755-0.755 1.774-1.172 2.828-1.172 0.168 0 0.336 0.011 0.505 0.032 0.655 0.083 1.325 0.126 1.99 0.126 1.717 0 3.375-0.271 4.928-0.804 1.46-0.502 2.76-1.211 3.863-2.108 2.069-1.681 3.209-3.843 3.209-6.088s-1.14-4.407-3.209-6.088c-1.104-0.897-2.404-1.606-3.863-2.108-1.553-0.534-3.211-0.804-4.928-0.804zM16 2v0c8.837 0 16 5.82 16 13s-7.163 13-16 13c-0.849 0-1.682-0.054-2.495-0.158-3.437 3.437-7.539 4.053-11.505 4.144v-0.841c2.142-1.049 4-2.961 4-5.145 0-0.305-0.024-0.604-0.068-0.897-3.619-2.383-5.932-6.024-5.932-10.103 0-7.18 7.163-13 16-13z";
+}
+
+.mode-edit-icon {
+ -fx-shape: "M20.719 7.031l-1.828 1.828-3.75-3.75 1.828-1.828c0.375-0.375 1.031-0.375 1.406 0l2.344 2.344c0.375 0.375 0.375 1.031 0 1.406zM3 17.25l11.063-11.063 3.75 3.75-11.063 11.063h-3.75v-3.75z";
+}
+
+.notification-none-icon {
+ -fx-shape: "M15.984 17.016v-6c0-2.484-1.5-4.5-3.984-4.5s-3.984 2.016-3.984 4.5v6h7.969zM18 15.984l2.016 2.016v0.984h-16.031v-0.984l2.016-2.016v-4.969c0-3.094 1.641-5.625 4.5-6.328v-0.703c0-0.844 0.656-1.5 1.5-1.5s1.5 0.656 1.5 1.5v0.703c2.859 0.703 4.5 3.281 4.5 6.328v4.969zM12 21.984c-1.078 0-2.016-0.891-2.016-1.969h4.031c0 1.078-0.938 1.969-2.016 1.969z";
+}
+
+.assignment-late-icon {
+ -fx-shape: "M288 192.75c18 0 31.5-15 31.5-33s-13.5-31.5-31.5-31.5-31.5 13.5-31.5 31.5 13.5 33 31.5 33zM319.5 480.75v-192h-63v192h63zM319.5 608.25v-64.5h-63v64.5h63zM511.5 128.25c34.5 0 64.5 30 64.5 64.5v447c0 34.5-30 64.5-64.5 64.5h-447c-34.5 0-64.5-30-64.5-64.5v-447c0-34.5 30-64.5 64.5-64.5h133.5c13.5-37.5 48-64.5 90-64.5s76.5 27 90 64.5h133.5z";
+}
+
+.play-circle-outline-icon {
+ -fx-shape: "M16 26.688c5.875 0 10.688-4.813 10.688-10.688s-4.813-10.688-10.688-10.688-10.688 4.813-10.688 10.688 4.813 10.688 10.688 10.688zM16 2.688c7.375 0 13.313 5.938 13.313 13.313s-5.938 13.313-13.313 13.313-13.313-5.938-13.313-13.313 5.938-13.313 13.313-13.313zM13.313 22v-12l8 6z";
}
\ No newline at end of file
diff --git a/src/main/resources/theme/style.css b/src/main/resources/theme/style.css
index 6e6202d5c8..640c94f858 100644
--- a/src/main/resources/theme/style.css
+++ b/src/main/resources/theme/style.css
@@ -114,7 +114,7 @@
-fx-background-color: -fx-background;
}
-.query-filter .context-menu {
+.query-filter {
-fx-background-color: -fx-background;
}
@@ -1445,3 +1445,22 @@
.clickable:hover {
-fx-background-color: -fx-hover-accent;
}
+
+/***************** Root Context Menu ***************************/
+
+.context-menu {
+ -fx-background-color: derive(-context-menu-color, 5%);
+ -fx-border-color: -context-menu-border-color;
+ -fx-border-width: 0.0625em; /* 1px */
+ -fx-border-radius: 0.1875em; /* 3px */
+ -fx-background-radius: 0.1875em; /* 3px */
+}
+
+.context-menu .separator .line {
+ -fx-border-color: derive(-context-menu-color, 30%) transparent transparent transparent
+}
+
+.menu-item > .label {
+ -fx-text-fill: -menu-item-label-color;
+}
+
diff --git a/src/test/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItemTest.java b/src/test/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItemTest.java
new file mode 100644
index 0000000000..624fc2323e
--- /dev/null
+++ b/src/test/java/com/faforever/client/fx/contextmenu/ChangeUsernameColorMenuItemTest.java
@@ -0,0 +1,84 @@
+package com.faforever.client.fx.contextmenu;
+
+import com.faforever.client.builders.ChatChannelUserBuilder;
+import com.faforever.client.builders.PreferencesBuilder;
+import com.faforever.client.chat.ChatChannelUser;
+import com.faforever.client.chat.ChatColorMode;
+import com.faforever.client.fx.contextmenu.helper.ContextMenuBuilderHelper;
+import com.faforever.client.i18n.I18n;
+import com.faforever.client.preferences.Preferences;
+import com.faforever.client.preferences.PreferencesService;
+import com.faforever.client.test.UITest;
+import com.faforever.client.theme.UiService;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyDouble;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+public class ChangeUsernameColorMenuItemTest extends UITest {
+
+ @Mock
+ private PreferencesService preferencesService;
+ @Mock
+ private UiService uiService;
+ @Mock
+ private I18n i18n;
+ @Mock
+ private ContextMenuBuilder contextMenuBuilder;
+
+ @InjectMocks
+ private ChangeUsernameColorMenuItem instance;
+
+ private Preferences preferences;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ preferences = PreferencesBuilder.create().defaultValues().chatPrefs()
+ .chatColorMode(ChatColorMode.DEFAULT)
+ .then()
+ .get();
+ when(preferencesService.getPreferences()).thenReturn(preferences);
+ }
+
+ @Test
+ public void testOnClicked() {
+ runOnFxThreadAndWait(() -> {
+ ContextMenu contextMenu = new ContextMenu(instance);
+ Label label = new Label();
+ label.setContextMenu(contextMenu);
+ getRoot().getChildren().add(label);
+ instance.setObject(ChatChannelUserBuilder.create("junit", "channel").get());
+ contextMenu.show(getRoot(), 0, 0);
+ });
+
+ verifyNoInteractions(contextMenuBuilder);
+ ContextMenu contextMenuMock = ContextMenuBuilderHelper.mockContextMenuBuilderAndGetContextMenuMock(contextMenuBuilder);
+ instance.onClicked();
+ verify(contextMenuMock).show(eq(getStage()), anyDouble(), anyDouble());
+ }
+
+ @Test
+ public void testVisibleItem() {
+ runOnFxThreadAndWait(() -> instance.setObject(ChatChannelUserBuilder.create("junit", "channel").get()));
+ assertTrue(instance.isVisible());
+ }
+
+ @Test
+ public void testInvisibleItemWhenChatColorModeIsRandom() {
+ preferences = PreferencesBuilder.create().chatPrefs().chatColorMode(ChatColorMode.RANDOM).then().get();
+ when(preferencesService.getPreferences()).thenReturn(preferences);
+ runOnFxThreadAndWait(() -> instance.setObject(any(ChatChannelUser.class)));
+ assertFalse(instance.isVisible());
+ }
+}
\ No newline at end of file