From d03f31100ef3eed38e6ec85642a081971b954070 Mon Sep 17 00:00:00 2001
From: mikera <mike@mikera.net>
Date: Sun, 5 May 2024 16:30:55 +0100
Subject: [PATCH] GUI refactoring, experimental IP utilities

---
 .../src/main/java/convex/gui/MainGUI.java     | 12 ++---
 .../convex/gui/components/AbstractGUI.java    | 11 ++--
 .../convex/gui/components/BalanceLabel.java   |  3 ++
 .../convex/gui/components/WorldPanel.java     | 16 ++++--
 .../java/convex/gui/panels/HomePanel.java     | 20 +++-----
 .../java/convex/gui/peer/PeerComponent.java   |  2 +-
 .../convex/gui/wallet/AccountOverview.java    |  2 +-
 .../java/convex/gui/wallet/SwapPanel.java     | 20 ++++++++
 .../convex/gui/wallet/TokenComponent.java     |  5 ++
 .../src/main/java/convex/net/IPUtils.java     | 50 +++++++++++++++++++
 10 files changed, 111 insertions(+), 30 deletions(-)
 create mode 100644 convex-gui/src/main/java/convex/gui/wallet/SwapPanel.java
 create mode 100644 convex-peer/src/main/java/convex/net/IPUtils.java

diff --git a/convex-gui/src/main/java/convex/gui/MainGUI.java b/convex-gui/src/main/java/convex/gui/MainGUI.java
index 7c6af4255..093420b91 100644
--- a/convex-gui/src/main/java/convex/gui/MainGUI.java
+++ b/convex-gui/src/main/java/convex/gui/MainGUI.java
@@ -26,10 +26,10 @@
 public class MainGUI extends AbstractGUI {
 	public MainGUI() {
 		super ("Convex Desktop");
-		MigLayout layout=new MigLayout("center");
+		MigLayout layout=new MigLayout("wrap 1","[fill]");
 		setLayout(layout);
 		
-		add(new HomePanel(),"dock center");
+		add(new HomePanel());
 		
 		ActionPanel actionPanel=new ActionPanel();
 		actionPanel.setLayout(new MigLayout("center,align center,fillx"));
@@ -55,7 +55,7 @@ public MainGUI() {
 		JComponent www=createLaunchButton("convex.world",Toolkit.WWW_ICON,this::launchWebsite);
 		actionPanel.add(www);
 		
-		add(actionPanel,"dock south");
+		add(actionPanel);
 	}
 	
 	public void launchDLFS() {
@@ -103,9 +103,9 @@ public JPanel createLaunchButton(String label, ImageIcon icon, Runnable cmd) {
 		lab.setHorizontalAlignment(SwingConstants.CENTER);
 		
 		JPanel panel=new JPanel();
-		panel.setLayout(new MigLayout());
-		panel.add(butt,"dock center");
-		panel.add(lab,"dock south");
+		panel.setLayout(new MigLayout("center, wrap 1","[align center]"));
+		panel.add(butt);
+		panel.add(lab);
 		return panel;
 	}
 
diff --git a/convex-gui/src/main/java/convex/gui/components/AbstractGUI.java b/convex-gui/src/main/java/convex/gui/components/AbstractGUI.java
index e5e2b4d33..a794d84e3 100644
--- a/convex-gui/src/main/java/convex/gui/components/AbstractGUI.java
+++ b/convex-gui/src/main/java/convex/gui/components/AbstractGUI.java
@@ -1,7 +1,6 @@
 package convex.gui.components;
 
 
-import java.awt.BorderLayout;
 import java.awt.EventQueue;
 
 import javax.swing.JFrame;
@@ -12,6 +11,7 @@
 
 import convex.gui.MainGUI;
 import convex.gui.utils.Toolkit;
+import net.miginfocom.swing.MigLayout;
 
 /**
  * Base class for Convex GUI apps
@@ -41,12 +41,15 @@ public void run() {
 					frame.setTitle(title);
 					frame.setIconImage(Toolkit.getDefaultToolkit()
 							.getImage(MainGUI.class.getResource("/images/Convex.png")));
-					frame.setBounds(50, 50, 1200, 920);
+					
+					// Prefer not to have explicit frame size / position?
+					// frame.setBounds(50, 50, 1200, 920);
 					
 					Toolkit.closeIfFirstFrame(frame);
 
-					frame.getContentPane().setLayout(new BorderLayout());
-					frame.getContentPane().add(AbstractGUI.this, BorderLayout.CENTER);
+					frame.getContentPane().setLayout(new MigLayout());
+					frame.getContentPane().add(AbstractGUI.this);
+					frame.pack();
 					frame.setVisible(true);
 
 				} catch (Exception e) {
diff --git a/convex-gui/src/main/java/convex/gui/components/BalanceLabel.java b/convex-gui/src/main/java/convex/gui/components/BalanceLabel.java
index 53c6191ed..7f86a5a77 100644
--- a/convex-gui/src/main/java/convex/gui/components/BalanceLabel.java
+++ b/convex-gui/src/main/java/convex/gui/components/BalanceLabel.java
@@ -16,6 +16,7 @@
 import convex.core.data.prim.CVMLong;
 import convex.core.lang.RT;
 import convex.core.text.Text;
+import convex.core.util.Utils;
 import convex.gui.utils.SymbolIcon;
 import convex.gui.utils.Toolkit;
 
@@ -56,6 +57,7 @@ public BalanceLabel() {
 		//StyleConstants.setAlignment(attribs, StyleConstants.ALIGN_RIGHT);
 		//StyleConstants.setFontFamily(attribs, Font.PLAIN);
 		this.setParagraphAttributes(attribs, true);
+		this.setFocusable(false);
 	}
 	
 	public void setBalance(long a) {
@@ -71,6 +73,7 @@ public void setBalanceColour(Color c) {
 	}
 
 	public void setBalance(AInteger a) {
+		if (Utils.equals(a, balance)) return;
 		try {
 			if (a==null) {
 				setText("<No balance>");
diff --git a/convex-gui/src/main/java/convex/gui/components/WorldPanel.java b/convex-gui/src/main/java/convex/gui/components/WorldPanel.java
index 25670adf9..fff62029b 100644
--- a/convex-gui/src/main/java/convex/gui/components/WorldPanel.java
+++ b/convex-gui/src/main/java/convex/gui/components/WorldPanel.java
@@ -1,6 +1,7 @@
 package convex.gui.components;
 
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Image;
@@ -16,6 +17,9 @@
 
 import convex.gui.utils.RobinsonProjection;
 
+/**
+ * Panel displaying world image an optional locations
+ */
 @SuppressWarnings("serial")
 public class WorldPanel extends JPanel {
 	static BufferedImage image;
@@ -42,6 +46,7 @@ public class WorldPanel extends JPanel {
 
 	public WorldPanel() {
 		setBackground(Color.BLACK);
+		setPreferredSize(new Dimension(image.getWidth(),image.getHeight()));
 	}
 
 	@Override
@@ -57,13 +62,14 @@ public void paintComponent(Graphics g) {
 		int dh = Math.min(h, w * sh / sw);
 
 		int y = (h - dh) / 2;
+		int x = (w - dw) / 2;
 
-		g.drawImage(image, 0, y, dw, y + dh, 0, 0, sw, sh, null);
+		g.drawImage(image, x, y, x+dw, y + dh, 0, 0, sw, sh, null);
 
-		paintDot(g, 51.5073219, -0.1276474, 0, y, dw, dh); // London
-		paintDot(g, -33.928992, 18.417396, 0, y, dw, dh); // Cape Town
-		paintDot(g, 35.6828387, 139.7594549, 0, y, dw, dh); // Tokyo
-		paintDot(g, 23.135305, -82.3589631, 0, y, dw, dh); // Havana
+		paintDot(g, 51.5073219, -0.1276474, x, y, dw, dh); // London
+		paintDot(g, -33.928992, 18.417396, x, y, dw, dh); // Cape Town
+		paintDot(g, 35.6828387, 139.7594549, x, y, dw, dh); // Tokyo
+		paintDot(g, 23.135305, -82.3589631, x, y, dw, dh); // Havana
 	}
 
 	private void paintDot(Graphics g, double latitude, double longitude, int x, int y, int dw, int dh) {
diff --git a/convex-gui/src/main/java/convex/gui/panels/HomePanel.java b/convex-gui/src/main/java/convex/gui/panels/HomePanel.java
index d0ffb2a1c..5eff12563 100644
--- a/convex-gui/src/main/java/convex/gui/panels/HomePanel.java
+++ b/convex-gui/src/main/java/convex/gui/panels/HomePanel.java
@@ -1,15 +1,13 @@
 package convex.gui.panels;
 
-import javax.swing.JPanel;
-import java.awt.BorderLayout;
-import java.awt.Dimension;
+import java.awt.Font;
 
 import javax.swing.JLabel;
+import javax.swing.JPanel;
 import javax.swing.SwingConstants;
 
 import convex.gui.components.WorldPanel;
-
-import java.awt.Font;
+import net.miginfocom.swing.MigLayout;
 
 @SuppressWarnings("serial")
 public class HomePanel extends JPanel {
@@ -18,19 +16,15 @@ public class HomePanel extends JPanel {
 	 * Create the panel.
 	 */
 	public HomePanel() {
-		setPreferredSize(new Dimension(800,600));
-		setLayout(new BorderLayout(0, 0));
-
-		JPanel panel = new JPanel();
-		add(panel);
-		panel.setLayout(new BorderLayout(0, 0));
+		// setPreferredSize(new Dimension(800,600));
+		setLayout(new MigLayout());
 
 		JLabel lblWelome = new JLabel("Welcome to Convex");
 		lblWelome.setFont(new Font("Monospaced", Font.PLAIN, 24));
 		lblWelome.setHorizontalAlignment(SwingConstants.CENTER);
-		panel.add(lblWelome, BorderLayout.NORTH);
+		add(lblWelome,"dock north");
 
-		panel.add(new WorldPanel(), BorderLayout.CENTER);
+		add(new WorldPanel(),"align center");
 	}
 
 }
diff --git a/convex-gui/src/main/java/convex/gui/peer/PeerComponent.java b/convex-gui/src/main/java/convex/gui/peer/PeerComponent.java
index 04b7fe012..5784011ce 100644
--- a/convex-gui/src/main/java/convex/gui/peer/PeerComponent.java
+++ b/convex-gui/src/main/java/convex/gui/peer/PeerComponent.java
@@ -198,7 +198,7 @@ public String getPeerDescription() {
 			AccountKey paddr=server.getPeerKey();
 			// sb.append("0x"+paddr.toChecksumHex()+"\n");
 			if (server.isLive()) {
-				sb.append("Local peer on: " + server.getHostAddress() + " with store "+server.getStore().shortName()+"\n");
+				sb.append("Local peer on port: " + server.getPort() + " with store "+server.getStore().shortName()+"\n");
 			} else {
 				sb.append("Inactive Peer\n");
 			}
diff --git a/convex-gui/src/main/java/convex/gui/wallet/AccountOverview.java b/convex-gui/src/main/java/convex/gui/wallet/AccountOverview.java
index cfaaf8f78..13d374987 100644
--- a/convex-gui/src/main/java/convex/gui/wallet/AccountOverview.java
+++ b/convex-gui/src/main/java/convex/gui/wallet/AccountOverview.java
@@ -77,10 +77,10 @@ public AccountOverview(Convex convex) {
 	private void updateLoop() {
 		while (true) {
 			try {
+				Thread.sleep(1000);
 				if (isShowing()) {
 					balance.setBalance(convex.getBalance()); 
 				}
-				Thread.sleep(1000);
 			} catch (InterruptedException e) {
 				return;
 			} catch (Exception e) {
diff --git a/convex-gui/src/main/java/convex/gui/wallet/SwapPanel.java b/convex-gui/src/main/java/convex/gui/wallet/SwapPanel.java
new file mode 100644
index 000000000..e759021ed
--- /dev/null
+++ b/convex-gui/src/main/java/convex/gui/wallet/SwapPanel.java
@@ -0,0 +1,20 @@
+package convex.gui.wallet;
+
+import convex.api.Convex;
+import convex.gui.components.AbstractGUI;
+
+@SuppressWarnings("serial")
+public class SwapPanel extends AbstractGUI {
+
+	protected Convex convex;
+
+	private SwapPanel(String title) {
+		super(title);
+	}
+
+	public SwapPanel(Convex convex) {
+		this("Token Swap for account "+convex.getAddress());
+		this.convex=convex;
+	}
+
+}
diff --git a/convex-gui/src/main/java/convex/gui/wallet/TokenComponent.java b/convex-gui/src/main/java/convex/gui/wallet/TokenComponent.java
index 8229c48c2..fcc11f1c0 100644
--- a/convex-gui/src/main/java/convex/gui/wallet/TokenComponent.java
+++ b/convex-gui/src/main/java/convex/gui/wallet/TokenComponent.java
@@ -56,6 +56,11 @@ public TokenComponent(Convex convex, TokenInfo token) {
 		actions.add(new ActionButton(0xe872,e->{
 			WalletPanel.model.removeElement(token);
 		}));
+		actions.add(new ActionButton(0xe933,e->{
+			// Token swap
+			new SwapPanel(convex).run();
+		}));
+
 		add(actions,"dock east");
 		SwingUtilities.invokeLater(()->refresh(convex));
 	}
diff --git a/convex-peer/src/main/java/convex/net/IPUtils.java b/convex-peer/src/main/java/convex/net/IPUtils.java
new file mode 100644
index 000000000..c18f4a97c
--- /dev/null
+++ b/convex-peer/src/main/java/convex/net/IPUtils.java
@@ -0,0 +1,50 @@
+package convex.net;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+public class IPUtils {
+
+	public static InetAddress tryGetIP() throws InterruptedException {
+		
+		String s=tryGetWTF().trim();
+		if (s!=null) {
+			try {
+				InetAddress i= InetAddress.getByName(s);
+				return i;
+			} catch (UnknownHostException e) {
+				// continue
+			}
+		}
+		return null;
+	}
+		
+	public static String tryGetWTF() throws InterruptedException {
+		HttpClient client = HttpClient.newHttpClient();
+	
+		HttpRequest request = HttpRequest.newBuilder(
+			       URI.create("https://wtfismyip.com/text"))
+			   .header("accept", "text/plain")
+			   .build();
+
+		 HttpResponse<String> response;
+		try {
+			response = client.send(request, HttpResponse.BodyHandlers.ofString());
+			 String text=response.body();
+			 return text;
+		} catch (IOException e) {
+			return null;
+		}
+	}
+	
+	public static void main(String[] args) throws InterruptedException {
+		System.out.println(tryGetIP());
+		
+		System.out.println(tryGetIP());
+	}
+}