Skip to content

Conversation

@Glavo
Copy link
Member

@Glavo Glavo commented Jan 20, 2026

image

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

在“陶瓦联机”页面左侧菜单中加入账号入口,并支持通过右键弹出账号切换菜单,以便快速切换已登录账号。

Changes:

  • TerracottaPage 左侧工具栏新增账号项,并支持右键弹出账号列表菜单
  • RootPage 中账号切换弹出菜单逻辑抽取为可复用组件
  • 新增 AccountListPopupMenu 作为账号列表弹出菜单实现

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
HMCL/src/main/java/org/jackhuang/hmcl/ui/terracotta/TerracottaPage.java 在陶瓦联机页面侧边栏增加账号项,并提供右键弹出切换菜单入口
HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java 替换内联账号弹出菜单实现,改为复用新组件
HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountListPopupMenu.java 新增账号列表弹出菜单组件供多处复用

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +35 to +41
public final class AccountListPopupMenu extends StackPane {
public static void show(Node owner, JFXPopup.PopupVPosition vAlign, JFXPopup.PopupHPosition hAlign,
double initOffsetX, double initOffsetY) {
var menu = new AccountListPopupMenu();
JFXPopup popup = new JFXPopup(menu);
popup.show(owner, vAlign, hAlign, initOffsetX, initOffsetY);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccountListPopupMenu doesn’t apply the popup menu styling class used elsewhere (e.g. GameListPopupMenu adds popup-menu-content, and PopupMenu skin wraps content with the same class). Without it, this popup may render without the expected background/padding/theme. Consider adding the same style class to this root node (or reusing PopupMenu) to keep appearance consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +76
@SuppressWarnings("FieldCanBeLocal")
private final BooleanBinding isEmpty = Bindings.isEmpty(Accounts.getAccounts());
@SuppressWarnings("FieldCanBeLocal")
private final InvalidationListener listener;

public AccountListPopupMenu() {
AdvancedListBox box = new AdvancedListBox();
box.getStyleClass().add("no-padding");
box.setPrefWidth(220);
box.setPrefHeight(-1);
box.setMaxHeight(260);

listener = o -> {
box.clear();

for (Account account : Accounts.getAccounts()) {
AccountAdvancedListItem item = new AccountAdvancedListItem(account);
item.setOnAction(e -> {
Accounts.setSelectedAccount(account);
if (getScene().getWindow() instanceof JFXPopup popup)
popup.hide();
});
box.add(item);
}
};
listener.invalidated(null);
Accounts.getAccounts().addListener(new WeakInvalidationListener(listener));

Label placeholder = new Label(i18n("account.empty"));
placeholder.setStyle("-fx-padding: 10px; -fx-text-fill: -monet-on-surface-variant; -fx-font-style: italic;");

FXUtils.onChangeAndOperate(isEmpty, empty -> {
getChildren().setAll(empty ? placeholder : box);
});
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isEmpty is a BooleanBinding created from the global Accounts.getAccounts() list, and FXUtils.onChangeAndOperate(...) attaches a strong listener to that binding. Because the binding itself listens to Accounts.getAccounts(), this can keep each popup instance reachable via listeners even after the popup is hidden (leaking menus over time). Prefer updating the placeholder/content inside the existing (weak) list listener (e.g. check Accounts.getAccounts().isEmpty() there), or otherwise ensure listeners/bindings are disposed/unregistered when the popup closes.

Copilot uses AI. Check for mistakes.
@Glavo Glavo merged commit 90a795b into HMCL-dev:main Jan 27, 2026
2 checks passed
@Glavo Glavo deleted the terracotta-accounts branch January 27, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant