@@ -58,8 +58,19 @@ var alignment = []table.Alignment{
5858}
5959
6060func PeerLine (idx int , peer tsnet.Peer , peerData tsnet.PeerData ) []string {
61+ idxStr := strconv .Itoa (idx )
62+ switch peerData .Status {
63+ case tsnet .NotLinked :
64+ // leave uncolored
65+ case tsnet .Connecting :
66+ idxStr = tcolor .Inverse + Color16 (tcolor .BrightYellow , idxStr )
67+ case tsnet .Failed :
68+ idxStr = tcolor .Inverse + Color16 (tcolor .BrightRed , idxStr )
69+ case tsnet .Connected :
70+ idxStr = tcolor .Inverse + Color16 (tcolor .BrightGreen , idxStr )
71+ }
6172 return []string {
62- strconv . Itoa ( idx ) ,
73+ idxStr ,
6374 Color16 (tcolor .BrightCyan , peer .Name ),
6475 Color16 (tcolor .BrightGreen , peer .IP ),
6576 Color16f (tcolor .Blue , "%d" , peerData .Port ),
@@ -91,6 +102,30 @@ func DarkGray(s string) string {
91102 return Color16 (tcolor .DarkGray , s )
92103}
93104
105+ func InitiatePeerConnection (srv * tsnet.Server , peer tsnet.Peer , peerData tsnet.PeerData ) {
106+ log .Infof ("Initiating connection to peer %q at %s:%d" , peer .Name , peer .IP , peerData .Port )
107+ if connErr := srv .ConnectToPeer (peer ); connErr != nil {
108+ log .Errf ("Failed to connect to peer %s: %v" , peer .Name , connErr )
109+ }
110+ }
111+
112+ // MouseInsideBox returns whether the mouse is inside the box and the index of the line inside the box.
113+ func MouseInsideBox (ap * ansipixels.AnsiPixels , tableWidth , numPeers int ) (int , bool ) {
114+ tableWidth -= 2 // remove the borders
115+ startTable := (ap .W - tableWidth )/ 2 + 1 // mouse coordinates start at 1
116+ endTable := startTable + tableWidth
117+ log .LogVf ("MouseInsideBox: ap.Mx=%d, ap.My=%d, tableWidth=%d, startTable=%d, endTable=%d, numPeers=%d" ,
118+ ap .Mx , ap .My , tableWidth , startTable , endTable , numPeers )
119+ if ap .Mx < startTable || ap .Mx >= endTable {
120+ return - 1 , false
121+ }
122+ line := ap .My - 4 // accounts for border, our line and header and mouse coordinates starting at 1
123+ if line >= 0 && line < numPeers {
124+ return line , true
125+ }
126+ return - 1 , false
127+ }
128+
94129func Main () int {
95130 fName := flag .String ("name" , "" , "Name to use for this machine instead of the hostname" )
96131 // echo -n "ts" | od -d -> 29556
@@ -105,7 +140,11 @@ func Main() int {
105140 if err := ap .Open (); err != nil {
106141 return 1 // error already logged
107142 }
108- defer ap .Restore ()
143+ ap .MouseClickOn ()
144+ defer func () {
145+ ap .MouseClickOff ()
146+ ap .Restore ()
147+ }()
109148 id , err := LoadIdentity ()
110149 if err != nil {
111150 return log .FErrf ("Failed to load or create identity: %v" , err )
@@ -147,6 +186,19 @@ func Main() int {
147186 return nil
148187 }
149188 var peersSnapshot []smap.KV [tsnet.Peer , tsnet.PeerData ]
189+ tableWidth := 0
190+ ap .OnMouse = func () {
191+ if ! ap .LeftClick () || ! ap .MouseRelease () {
192+ return
193+ }
194+ if peerLine , ok := MouseInsideBox (ap , tableWidth , len (peersSnapshot )); ok {
195+ peer := peersSnapshot [peerLine ]
196+ log .Infof ("Left click (release) at %d,%d -> line %d - connecting to %q" , ap .Mx , ap .My , peerLine + 1 , peer .Key .Name )
197+ InitiatePeerConnection (srv , peer .Key , peer .Value )
198+ } else {
199+ log .Infof ("Left click (release) at %d,%d -> outside peer list" , ap .Mx , ap .My )
200+ }
201+ }
150202 err = ap .FPSTicks (func () bool {
151203 // Only refresh if we had (log) output or something changed, so cursor blinks (!).
152204 logHadOutput := ap .FlushLogger ()
@@ -169,7 +221,7 @@ func Main() int {
169221 lines = append (lines , PeerLine (idx , kv .Key , kv .Value ))
170222 idx ++
171223 }
172- table .WriteTable (ap , 0 , alignment , 1 , lines , table .BorderOuterColumns )
224+ tableWidth = table .WriteTable (ap , 0 , alignment , 1 , lines , table .BorderOuterColumns )
173225 ap .RestoreCursorPos ()
174226 ap .EndSyncMode ()
175227 }
@@ -183,10 +235,7 @@ func Main() int {
183235 maxPeerIdx := len (peersSnapshot )
184236 if connectToPeerIdx <= maxPeerIdx {
185237 peer := peersSnapshot [connectToPeerIdx - 1 ]
186- log .Infof ("Initiating connection to peer %q at %s:%d" , peer .Key .Name , peer .Key .IP , peer .Value .Port )
187- if connErr := srv .ConnectToPeer (peer .Key ); connErr != nil {
188- log .Errf ("Failed to connect to peer %s: %v" , peer .Key .Name , connErr )
189- }
238+ InitiatePeerConnection (srv , peer .Key , peer .Value )
190239 } else {
191240 log .Warnf ("No peer with index %d to connect to (max %d)." , connectToPeerIdx , maxPeerIdx )
192241 }
0 commit comments