Skip to content

Commit 7844f25

Browse files
Server URL button: route to interface-picker dialog with memory (#10475)
Remember the last-copied URL in a new NET_LAST_COPIED_URL pref. On open, auto-copy and star the remembered row (fallback: first row); an italic notice at the bottom confirms what was copied. Mobile continues to use NetConnectUtil.copyHostedServerUrl — the new dialog is desktop-only Swing. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 640cde0 commit 7844f25

4 files changed

Lines changed: 66 additions & 27 deletions

File tree

forge-gui-desktop/src/main/java/forge/screens/home/online/CSubmenuOnlineLobby.java

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import javax.swing.JMenu;
1414
import javax.swing.JPanel;
15+
import javax.swing.SwingConstants;
1516
import javax.swing.SwingUtilities;
1617

1718
import com.google.common.collect.ImmutableList;
@@ -94,50 +95,87 @@ private void host() {
9495
});
9596
}
9697

97-
private void showServerAddressesDialog() {
98-
final int port = FModel.getNetPreferences().getPrefInt(ForgeNetPreferences.FNetPref.NET_PORT);
98+
static void showServerAddressesDialog() {
99+
final ForgeNetPreferences netPrefs = FModel.getNetPreferences();
100+
final int port = netPrefs.getPrefInt(ForgeNetPreferences.FNetPref.NET_PORT);
99101
final LinkedHashMap<String, String> addresses = FServerManager.getAllLocalAddresses();
100102
final String externalAddress = FServerManager.getExternalAddress();
101103
final Localizer localizer = Localizer.getInstance();
102104

103-
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 4 6, wrap 3", "[grow][grow][pref]"));
105+
// Collect rows in display order; we auto-copy and star whichever row matches
106+
// the last-copied URL, falling back to the first row.
107+
final List<String> orderedLabels = new ArrayList<>();
108+
final List<String> orderedUrls = new ArrayList<>();
109+
if (externalAddress != null) {
110+
orderedLabels.add("External (WAN)");
111+
orderedUrls.add(externalAddress + ":" + port);
112+
}
113+
for (final Map.Entry<String, String> entry : addresses.entrySet()) {
114+
orderedLabels.add(entry.getKey());
115+
orderedUrls.add(entry.getValue() + ":" + port);
116+
}
117+
118+
// If the remembered URL is present in the current list, auto-copy and star it.
119+
// Otherwise fall back to the first entry (external if present, else first local
120+
// interface) — matches the old copyHostedServerUrl default. Do NOT overwrite
121+
// the remembered value on fallback, so a later reconnect to the original
122+
// network restores the preference.
123+
final String rememberedUrl = netPrefs.getPref(ForgeNetPreferences.FNetPref.NET_LAST_COPIED_URL);
124+
int starIndex = orderedUrls.indexOf(rememberedUrl);
125+
if (starIndex < 0) {
126+
starIndex = orderedUrls.isEmpty() ? -1 : 0;
127+
}
128+
if (starIndex >= 0) {
129+
copyToClipboard(orderedUrls.get(starIndex));
130+
}
131+
132+
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 4 6, wrap 3", "[pref]30[pref]30[pref]"));
104133
panel.setOpaque(false);
105134

106-
panel.add(new FLabel.Builder().text(localizer.getMessage("lblInterface")).fontStyle(Font.BOLD).fontSize(12).build(), "growx");
107-
panel.add(new FLabel.Builder().text(localizer.getMessage("lblAddress")).fontStyle(Font.BOLD).fontSize(12).build(), "growx");
135+
panel.add(new FLabel.Builder()
136+
.text(localizer.getMessage("lblChooseAddressToCopy"))
137+
.fontSize(12).fontAlign(SwingConstants.LEFT).build(),
138+
"span 3, growx, gapbottom 10");
139+
140+
panel.add(new FLabel.Builder().text(localizer.getMessage("lblInterface")).fontStyle(Font.BOLD).fontSize(12).fontAlign(SwingConstants.LEFT).build(), "growx");
141+
panel.add(new FLabel.Builder().text(localizer.getMessage("lblAddress")).fontStyle(Font.BOLD).fontSize(12).fontAlign(SwingConstants.LEFT).build(), "growx");
108142
panel.add(new FLabel.Builder().text("").build());
109143

110-
if (externalAddress != null) {
111-
final String externalUrl = externalAddress + ":" + port;
112-
panel.add(new FLabel.Builder().text("External (WAN)").fontSize(12).build(), "growx");
113-
panel.add(new FLabel.Builder().text(externalUrl).fontSize(12).build(), "growx");
144+
final FOptionPane[] holder = new FOptionPane[1];
145+
for (int i = 0; i < orderedUrls.size(); i++) {
146+
final String url = orderedUrls.get(i);
147+
final String label = (i == starIndex) ? orderedLabels.get(i) + " \u2605" : orderedLabels.get(i);
148+
panel.add(new FLabel.Builder().text(label).fontSize(12).fontAlign(SwingConstants.LEFT).build(), "growx");
149+
panel.add(new FLabel.Builder().text(url).fontSize(12).fontAlign(SwingConstants.LEFT).build(), "growx");
114150
final FButton btnCopy = new FButton(localizer.getMessage("lblCopy"));
115151
btnCopy.setFont(FSkin.getFont(11));
116-
btnCopy.addActionListener(e -> copyToClipboard(externalUrl));
152+
btnCopy.addActionListener(e -> {
153+
copyToClipboard(url);
154+
netPrefs.setPref(ForgeNetPreferences.FNetPref.NET_LAST_COPIED_URL, url);
155+
netPrefs.save();
156+
holder[0].setVisible(false);
157+
});
117158
panel.add(btnCopy, "w 70!, h 24!");
118159
}
119160

120-
boolean first = true;
121-
for (final Map.Entry<String, String> entry : addresses.entrySet()) {
122-
final String url = entry.getValue() + ":" + port;
123-
final String label = first ? entry.getKey() + " \u2605" : entry.getKey();
124-
first = false;
125-
126-
panel.add(new FLabel.Builder().text(label).fontSize(12).build(), "growx");
127-
panel.add(new FLabel.Builder().text(url).fontSize(12).build(), "growx");
128-
final FButton btnCopy = new FButton(localizer.getMessage("lblCopy"));
129-
btnCopy.setFont(FSkin.getFont(11));
130-
btnCopy.addActionListener(e -> copyToClipboard(url));
131-
panel.add(btnCopy, "w 70!, h 24!");
161+
if (starIndex >= 0) {
162+
panel.add(new FLabel.Builder()
163+
.text(localizer.getMessage("lblServerUrlCopiedToClipboard", orderedUrls.get(starIndex)))
164+
.fontSize(11).fontStyle(Font.ITALIC).fontAlign(SwingConstants.LEFT).build(),
165+
"span 3, growx, gaptop 10");
132166
}
133167

134-
FOptionPane.showOptionDialog(
135-
localizer.getMessage("lblChooseAddressToCopy"),
168+
// Pass null as the prompt message so dialog width is driven by the panel's
169+
// actual content width rather than the much-wider localised instruction line.
170+
holder[0] = new FOptionPane(
171+
null,
136172
localizer.getMessage("lblServerURL"),
137173
FOptionPane.INFORMATION_ICON,
138174
panel,
139175
ImmutableList.of(localizer.getMessage("lblOK")),
140176
0);
177+
holder[0].setVisible(true);
178+
holder[0].dispose();
141179
}
142180

143181
private static void copyToClipboard(final String text) {

forge-gui-desktop/src/main/java/forge/screens/home/online/VSubmenuOnlineLobby.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import forge.deckchooser.FDeckChooser;
66
import forge.gamemodes.match.GameLobby;
77
import forge.gamemodes.net.IOnlineLobby;
8-
import forge.gamemodes.net.NetConnectUtil;
98
import forge.gamemodes.net.client.FGameClient;
109
import forge.gamemodes.net.server.FServerManager;
1110
import forge.gui.FNetOverlay;
@@ -96,7 +95,7 @@ public void populate() {
9695
FButton btnServerUrl = new FButton(Localizer.getInstance().getMessage("lblServerURL"));
9796
btnServerUrl.setFont(FSkin.getRelativeFont(14));
9897
pnlTitle.add(btnServerUrl, "w 150!, h 35!, gap 10 10 0 0, align right");
99-
btnServerUrl.addActionListener(e -> NetConnectUtil.copyHostedServerUrl());
98+
btnServerUrl.addActionListener(e -> CSubmenuOnlineLobby.showServerAddressesDialog());
10099
}
101100
pnlTitle.add(btnStop, "gap 10 10 0 0, align right");
102101
container.add(pnlTitle,"w 80%, gap 0 0 0 0, al right, pushx");

forge-gui/res/languages/en-US.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,6 +3130,7 @@ lblServerURL=Server URL
31303130
lblInterface=Interface
31313131
lblAddress=Address
31323132
lblChooseAddressToCopy=Click "Copy" next to the address you want to share with other players.
3133+
lblServerUrlCopiedToClipboard=Last used address automatically copied to clipboard: {0}
31333134
lblCopyExternalURL=Copy External URL
31343135
lblCopyLocalURL=Copy Local URL
31353136
lblYourConnectionToHostWasInterrupted=Your connection to the host ({0}) was interrupted.

forge-gui/src/main/java/forge/localinstance/properties/ForgeNetPreferences.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public enum FNetPref implements PreferencesStore.IPref {
3030
NET_BANDWIDTH_LOGGING("false"),
3131
NET_MAX_LOG_FILES("10"),
3232
NET_LOG_CLEANUP_ENABLED("true"),
33-
NET_AFK_TIMEOUT("5");
33+
NET_AFK_TIMEOUT("5"),
34+
NET_LAST_COPIED_URL("");
3435

3536
private final String strDefaultVal;
3637

0 commit comments

Comments
 (0)