app.go raw

   1  package gui
   2  
   3  import (
   4  	"fmt"
   5  	"io/ioutil"
   6  	"os"
   7  	"os/exec"
   8  	"path/filepath"
   9  
  10  	uberatomic "go.uber.org/atomic"
  11  	"golang.org/x/exp/shiny/materialdesign/icons"
  12  
  13  	l "github.com/p9c/p9/pkg/gel/gio/layout"
  14  	"github.com/p9c/p9/pkg/gel/gio/text"
  15  
  16  	"github.com/p9c/p9/pkg/gel"
  17  	"github.com/p9c/p9/cmd/gui/cfg"
  18  	"github.com/p9c/p9/pkg/p9icons"
  19  )
  20  
  21  func (wg *WalletGUI) GetAppWidget() (a *gel.App) {
  22  	a = wg.App(wg.Window.Width, uberatomic.NewString("home"), Break1).
  23  		SetMainDirection(l.W).
  24  		SetLogo(&p9icons.ParallelCoin).
  25  		SetAppTitleText("Parallelcoin Wallet")
  26  	wg.MainApp = a
  27  	wg.config = cfg.New(wg.Window, wg.quit)
  28  	wg.configs = wg.config.Config()
  29  	a.Pages(
  30  		map[string]l.Widget{
  31  			"home": wg.Page(
  32  				"home", gel.Widgets{
  33  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  34  					gel.WidgetSize{Widget: wg.OverviewPage()},
  35  				},
  36  			),
  37  			"send": wg.Page(
  38  				"send", gel.Widgets{
  39  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  40  					gel.WidgetSize{Widget: wg.SendPage.Fn},
  41  				},
  42  			),
  43  			"receive": wg.Page(
  44  				"receive", gel.Widgets{
  45  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  46  					gel.WidgetSize{Widget: wg.ReceivePage.Fn},
  47  				},
  48  			),
  49  			"history": wg.Page(
  50  				"history", gel.Widgets{
  51  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  52  					gel.WidgetSize{Widget: wg.HistoryPage()},
  53  				},
  54  			),
  55  			"settings": wg.Page(
  56  				"settings", gel.Widgets{
  57  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  58  					gel.WidgetSize{
  59  						Widget: func(gtx l.Context) l.Dimensions {
  60  							return wg.configs.Widget(wg.config)(gtx)
  61  						},
  62  					},
  63  				},
  64  			),
  65  			"console": wg.Page(
  66  				"console", gel.Widgets{
  67  					// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
  68  					gel.WidgetSize{Widget: wg.console.Fn},
  69  				},
  70  			),
  71  			"help": wg.Page(
  72  				"help", gel.Widgets{
  73  					gel.WidgetSize{Widget: wg.HelpPage()},
  74  				},
  75  			),
  76  			"log": wg.Page(
  77  				"log", gel.Widgets{
  78  					gel.WidgetSize{Widget: a.Placeholder("log")},
  79  				},
  80  			),
  81  			"quit": wg.Page(
  82  				"quit", gel.Widgets{
  83  					gel.WidgetSize{
  84  						Widget: func(gtx l.Context) l.Dimensions {
  85  							return wg.VFlex().
  86  								SpaceEvenly().
  87  								AlignMiddle().
  88  								Rigid(
  89  									wg.H4("are you sure?").Color(wg.MainApp.BodyColorGet()).Alignment(text.Middle).Fn,
  90  								).
  91  								Rigid(
  92  									wg.Flex().
  93  										// SpaceEvenly().
  94  										Flexed(0.5, gel.EmptyMaxWidth()).
  95  										Rigid(
  96  											wg.Button(
  97  												wg.clickables["quit"].SetClick(
  98  													func() {
  99  														// interrupt.Request()
 100  														wg.gracefulShutdown()
 101  														// close(wg.quit)
 102  													},
 103  												),
 104  											).Color("Light").TextScale(5).Text(
 105  												"yes!!!",
 106  											).Fn,
 107  										).
 108  										Flexed(0.5, gel.EmptyMaxWidth()).
 109  										Fn,
 110  								).
 111  								Fn(gtx)
 112  						},
 113  					},
 114  				},
 115  			),
 116  			// "goroutines": wg.Page(
 117  			// 	"log", p9.Widgets{
 118  			// 		// p9.WidgetSize{Widget: p9.EmptyMaxHeight()},
 119  			//
 120  			// 		p9.WidgetSize{
 121  			// 			Widget: func(gtx l.Context) l.Dimensions {
 122  			// 				le := func(gtx l.Context, index int) l.Dimensions {
 123  			// 					return wg.State.goroutines[index](gtx)
 124  			// 				}
 125  			// 				return func(gtx l.Context) l.Dimensions {
 126  			// 					return wg.ButtonInset(
 127  			// 						0.25,
 128  			// 						wg.Fill(
 129  			// 							"DocBg",
 130  			// 							wg.lists["recent"].
 131  			// 								Vertical().
 132  			// 								// Background("DocBg").Color("DocText").Active("Primary").
 133  			// 								Length(len(wg.State.goroutines)).
 134  			// 								ListElement(le).
 135  			// 								Fn,
 136  			// 						).Fn,
 137  			// 					).
 138  			// 						Fn(gtx)
 139  			// 				}(gtx)
 140  			// 				// wg.NodeRunCommandChan <- "stop"
 141  			// 				// consume.Kill(wg.Worker)
 142  			// 				// consume.Kill(wg.cx.StateCfg.Miner)
 143  			// 				// close(wg.cx.NodeKill)
 144  			// 				// close(wg.cx.KillAll)
 145  			// 				// time.Sleep(time.Second*3)
 146  			// 				// interrupt.Request()
 147  			// 				// os.Exit(0)
 148  			// 				// return l.Dimensions{}
 149  			// 			},
 150  			// 		},
 151  			// 	},
 152  			// ),
 153  			"mining": wg.Page(
 154  				"mining", gel.Widgets{
 155  					gel.WidgetSize{
 156  						Widget: a.Placeholder("mining"),
 157  					},
 158  				},
 159  			),
 160  			"explorer": wg.Page(
 161  				"explorer", gel.Widgets{
 162  					gel.WidgetSize{
 163  						Widget: a.Placeholder("explorer"),
 164  					},
 165  				},
 166  			),
 167  		},
 168  	)
 169  	a.SideBar(
 170  		[]l.Widget{
 171  			// wg.SideBarButton(" ", " ", 11),
 172  			wg.SideBarButton("home", "home", 0),
 173  			wg.SideBarButton("send", "send", 1),
 174  			wg.SideBarButton("receive", "receive", 2),
 175  			wg.SideBarButton("history", "history", 3),
 176  			// wg.SideBarButton("explorer", "explorer", 6),
 177  			// wg.SideBarButton("mining", "mining", 7),
 178  			wg.SideBarButton("console", "console", 9),
 179  			wg.SideBarButton("settings", "settings", 5),
 180  			// wg.SideBarButton("log", "log", 10),
 181  			wg.SideBarButton("help", "help", 8),
 182  			// wg.SideBarButton(" ", " ", 11),
 183  			// wg.SideBarButton("quit", "quit", 11),
 184  		},
 185  	)
 186  	a.ButtonBar(
 187  		[]l.Widget{
 188  			
 189  			// gel.EmptyMaxWidth(),
 190  			// wg.PageTopBarButton(
 191  			// 	"goroutines", 0, &icons.ActionBugReport, func(name string) {
 192  			// 		wg.App.ActivePage(name)
 193  			// 	}, a, "",
 194  			// ),
 195  			wg.PageTopBarButton(
 196  				"help", 1, &icons.ActionHelp, func(name string) {
 197  					wg.MainApp.ActivePage(name)
 198  				}, a, "",
 199  			),
 200  			wg.PageTopBarButton(
 201  				"home", 4, &icons.ActionLockOpen, func(name string) {
 202  					wg.unlockPassword.Wipe()
 203  					wg.unlockPassword.Focus()
 204  					wg.WalletWatcher.Q()
 205  					// if wg.WalletClient != nil {
 206  					// 	wg.WalletClient.Disconnect()
 207  					// 	wg.WalletClient = nil
 208  					// }
 209  					// wg.wallet.Stop()
 210  					// wg.node.Stop()
 211  					wg.State.SetActivePage("home")
 212  					wg.unlockPage.ActivePage("home")
 213  					wg.stateLoaded.Store(false)
 214  					wg.ready.Store(false)
 215  				}, a, "green",
 216  			),
 217  			// wg.Flex().Rigid(wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn).Fn,
 218  			// wg.PageTopBarButton(
 219  			// 	"quit", 3, &icons.ActionExitToApp, func(name string) {
 220  			// 		wg.MainApp.ActivePage(name)
 221  			// 	}, a, "",
 222  			// ),
 223  		},
 224  	)
 225  	a.StatusBar(
 226  		[]l.Widget{
 227  			// func(gtx l.Context) l.Dimensions { return wg.RunStatusPanel(gtx) },
 228  			// wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
 229  			// wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
 230  			wg.RunStatusPanel,
 231  		},
 232  		[]l.Widget{
 233  			// gel.EmptyMaxWidth(),
 234  			wg.StatusBarButton(
 235  				"console", 3, &p9icons.Terminal, func(name string) {
 236  					wg.MainApp.ActivePage(name)
 237  				}, a,
 238  			),
 239  			wg.StatusBarButton(
 240  				"log", 4, &icons.ActionList, func(name string) {
 241  					D.Ln("click on button", name)
 242  					if wg.MainApp.MenuOpen {
 243  						wg.MainApp.MenuOpen = false
 244  					}
 245  					wg.MainApp.ActivePage(name)
 246  				}, a,
 247  			),
 248  			wg.StatusBarButton(
 249  				"settings", 5, &icons.ActionSettings, func(name string) {
 250  					D.Ln("click on button", name)
 251  					if wg.MainApp.MenuOpen {
 252  						wg.MainApp.MenuOpen = false
 253  					}
 254  					wg.MainApp.ActivePage(name)
 255  				}, a,
 256  			),
 257  			// wg.Inset(0.5, gel.EmptySpace(0, 0)).Fn,
 258  		},
 259  	)
 260  	// a.PushOverlay(wg.toasts.DrawToasts())
 261  	// a.PushOverlay(wg.dialog.DrawDialog())
 262  	return
 263  }
 264  
 265  func (wg *WalletGUI) Page(title string, widget gel.Widgets) func(gtx l.Context) l.Dimensions {
 266  	return func(gtx l.Context) l.Dimensions {
 267  		return wg.VFlex().
 268  			// SpaceEvenly().
 269  			Rigid(
 270  				wg.Responsive(
 271  					wg.Size.Load(), gel.Widgets{
 272  						// p9.WidgetSize{
 273  						// 	Widget: a.ButtonInset(0.25, a.H5(title).Color(wg.App.BodyColorGet()).Fn).Fn,
 274  						// },
 275  						gel.WidgetSize{
 276  							// Size:   800,
 277  							Widget: gel.EmptySpace(0, 0),
 278  							// a.ButtonInset(0.25, a.Caption(title).Color(wg.BodyColorGet()).Fn).Fn,
 279  						},
 280  					},
 281  				).Fn,
 282  			).
 283  			Flexed(
 284  				1,
 285  				wg.Inset(
 286  					0.25,
 287  					wg.Responsive(wg.Size.Load(), widget).Fn,
 288  				).Fn,
 289  			).Fn(gtx)
 290  	}
 291  }
 292  
 293  func (wg *WalletGUI) SideBarButton(title, page string, index int) func(gtx l.Context) l.Dimensions {
 294  	return func(gtx l.Context) l.Dimensions {
 295  		var scale float32
 296  		scale = gel.Scales["H6"]
 297  		var color string
 298  		background := "Transparent"
 299  		color = "DocText"
 300  		var ins float32 = 0.5
 301  		// var hl = false
 302  		if wg.MainApp.ActivePageGet() == page || wg.MainApp.PreRendering {
 303  			background = "PanelBg"
 304  			scale = gel.Scales["H6"]
 305  			color = "DocText"
 306  			// ins = 0.5
 307  			// hl = true
 308  		}
 309  		if title == " " {
 310  			scale = gel.Scales["H6"] / 2
 311  		}
 312  		max := int(wg.MainApp.SideBarSize.V)
 313  		if max > 0 {
 314  			gtx.Constraints.Max.X = max
 315  			gtx.Constraints.Min.X = max
 316  		}
 317  		// D.Ln("sideMAXXXXXX!!", max)
 318  		return wg.Direction().E().Embed(
 319  			wg.ButtonLayout(wg.sidebarButtons[index]).
 320  				CornerRadius(scale).Corners(0).
 321  				Background(background).
 322  				Embed(
 323  					wg.Inset(
 324  						ins,
 325  						func(gtx l.Context) l.Dimensions {
 326  							return wg.H5(title).
 327  								Color(color).
 328  								Alignment(text.End).
 329  								Fn(gtx)
 330  						},
 331  					).Fn,
 332  				).
 333  				SetClick(
 334  					func() {
 335  						if wg.MainApp.MenuOpen {
 336  							wg.MainApp.MenuOpen = false
 337  						}
 338  						wg.MainApp.ActivePage(page)
 339  					},
 340  				).
 341  				Fn,
 342  		).
 343  			Fn(gtx)
 344  	}
 345  }
 346  
 347  func (wg *WalletGUI) PageTopBarButton(
 348  	name string, index int, ico *[]byte, onClick func(string), app *gel.App,
 349  	highlightColor string,
 350  ) func(gtx l.Context) l.Dimensions {
 351  	return func(gtx l.Context) l.Dimensions {
 352  		background := "Transparent"
 353  		// background := app.TitleBarBackgroundGet()
 354  		color := app.MenuColorGet()
 355  		
 356  		if app.ActivePageGet() == name {
 357  			color = "PanelText"
 358  			// background = "scrim"
 359  			background = "PanelBg"
 360  		}
 361  		// if name == "home" {
 362  		// 	background = "scrim"
 363  		// }
 364  		if highlightColor != "" {
 365  			color = highlightColor
 366  		}
 367  		ic := wg.Icon().
 368  			Scale(gel.Scales["H5"]).
 369  			Color(color).
 370  			Src(ico).
 371  			Fn
 372  		return wg.Flex().Rigid(
 373  			// wg.ButtonInset(0.25,
 374  			wg.ButtonLayout(wg.buttonBarButtons[index]).
 375  				CornerRadius(0).
 376  				Embed(
 377  					wg.Inset(
 378  						0.375,
 379  						ic,
 380  					).Fn,
 381  				).
 382  				Background(background).
 383  				SetClick(func() { onClick(name) }).
 384  				Fn,
 385  			// ).Fn,
 386  		).Fn(gtx)
 387  	}
 388  }
 389  
 390  func (wg *WalletGUI) StatusBarButton(
 391  	name string,
 392  	index int,
 393  	ico *[]byte,
 394  	onClick func(string),
 395  	app *gel.App,
 396  ) func(gtx l.Context) l.Dimensions {
 397  	return func(gtx l.Context) l.Dimensions {
 398  		background := app.StatusBarBackgroundGet()
 399  		color := app.StatusBarColorGet()
 400  		if app.ActivePageGet() == name {
 401  			// background, color = color, background
 402  			background = "PanelBg"
 403  			// color = "Danger"
 404  		}
 405  		ic := wg.Icon().
 406  			Scale(gel.Scales["H5"]).
 407  			Color(color).
 408  			Src(ico).
 409  			Fn
 410  		return wg.Flex().
 411  			Rigid(
 412  				wg.ButtonLayout(wg.statusBarButtons[index]).
 413  					CornerRadius(0).
 414  					Embed(
 415  						wg.Inset(0.25, ic).Fn,
 416  					).
 417  					Background(background).
 418  					SetClick(func() { onClick(name) }).
 419  					Fn,
 420  			).Fn(gtx)
 421  	}
 422  }
 423  
 424  func (wg *WalletGUI) SetNodeRunState(b bool) {
 425  	go func() {
 426  		D.Ln("node run state is now", b)
 427  		if b {
 428  			wg.node.Start()
 429  		} else {
 430  			wg.node.Stop()
 431  		}
 432  	}()
 433  }
 434  
 435  func (wg *WalletGUI) SetWalletRunState(b bool) {
 436  	go func() {
 437  		D.Ln("node run state is now", b)
 438  		if b {
 439  			wg.wallet.Start()
 440  		} else {
 441  			wg.wallet.Stop()
 442  		}
 443  	}()
 444  }
 445  
 446  func (wg *WalletGUI) RunStatusPanel(gtx l.Context) l.Dimensions {
 447  	return func(gtx l.Context) l.Dimensions {
 448  		t, f := &p9icons.Link, &p9icons.LinkOff
 449  		var runningIcon *[]byte
 450  		if wg.node.Running() {
 451  			runningIcon = t
 452  		} else {
 453  			runningIcon = f
 454  		}
 455  		miningIcon := &p9icons.Mine
 456  		if !wg.miner.Running() {
 457  			miningIcon = &p9icons.NoMine
 458  		}
 459  		controllerIcon := &icons.NotificationSyncDisabled
 460  		if wg.cx.Config.Controller.True() {
 461  			controllerIcon = &icons.NotificationSync
 462  		}
 463  		discoverColor :=
 464  			"DocText"
 465  		discoverIcon :=
 466  			&icons.DeviceWiFiTethering
 467  		if wg.cx.Config.Discovery.False() {
 468  			discoverIcon =
 469  				&icons.CommunicationPortableWiFiOff
 470  			discoverColor =
 471  				"scrim"
 472  		}
 473  		clr := "scrim"
 474  		if wg.cx.Config.Controller.True() {
 475  			clr = "DocText"
 476  		}
 477  		clr2 := "DocText"
 478  		if wg.cx.Config.GenThreads.V() == 0 {
 479  			clr2 = "scrim"
 480  		}
 481  		// background := wg.App.StatusBarBackgroundGet()
 482  		color := wg.MainApp.StatusBarColorGet()
 483  		ic := wg.Icon().
 484  			Scale(gel.Scales["H5"]).
 485  			Color(color).
 486  			Src(&icons.NavigationRefresh).
 487  			Fn
 488  		return wg.Flex().AlignMiddle().
 489  			Rigid(
 490  				wg.ButtonLayout(wg.statusBarButtons[0]).
 491  					CornerRadius(0).
 492  					Embed(
 493  						wg.Inset(
 494  							0.25,
 495  							wg.Icon().
 496  								Scale(gel.Scales["H5"]).
 497  								Color("DocText").
 498  								Src(runningIcon).
 499  								Fn,
 500  						).Fn,
 501  					).
 502  					Background(wg.MainApp.StatusBarBackgroundGet()).
 503  					SetClick(
 504  						func() {
 505  							go func() {
 506  								D.Ln("clicked node run control button", wg.node.Running())
 507  								// wg.toggleNode()
 508  								wg.unlockPassword.Wipe()
 509  								wg.unlockPassword.Focus()
 510  								if wg.node.Running() {
 511  									if wg.wallet.Running() {
 512  										wg.WalletWatcher.Q()
 513  									}
 514  									wg.node.Stop()
 515  									wg.ready.Store(false)
 516  									wg.stateLoaded.Store(false)
 517  									wg.State.SetActivePage("home")
 518  								} else {
 519  									wg.node.Start()
 520  									// wg.ready.Store(true)
 521  									// wg.stateLoaded.Store(true)
 522  								}
 523  							}()
 524  						},
 525  					).
 526  					Fn,
 527  			).
 528  			Rigid(
 529  				wg.Inset(
 530  					0.33,
 531  					wg.Body1(fmt.Sprintf("%d", wg.State.bestBlockHeight.Load())).
 532  						Font("go regular").TextScale(gel.Scales["Caption"]).
 533  						Color("DocText").
 534  						Fn,
 535  				).Fn,
 536  			).
 537  			Rigid(
 538  				wg.ButtonLayout(wg.statusBarButtons[6]).
 539  					CornerRadius(0).
 540  					Embed(
 541  						wg.Inset(
 542  							0.25,
 543  							wg.Icon().
 544  								Scale(gel.Scales["H5"]).
 545  								Color(discoverColor).
 546  								Src(discoverIcon).
 547  								Fn,
 548  						).Fn,
 549  					).
 550  					Background(wg.MainApp.StatusBarBackgroundGet()).
 551  					SetClick(
 552  						func() {
 553  							go func() {
 554  								wg.cx.Config.Discovery.Flip()
 555  								_ = wg.cx.Config.WriteToFile(wg.cx.Config.ConfigFile.V())
 556  								I.Ln("discover enabled:",
 557  									wg.cx.Config.Discovery.True())
 558  							}()
 559  						},
 560  					).
 561  					Fn,
 562  			).
 563  			Rigid(
 564  				wg.Inset(
 565  					0.33,
 566  					wg.Caption(fmt.Sprintf("%d LAN %d", len(wg.otherNodes), wg.peerCount.Load())).
 567  						Font("go regular").
 568  						Color("DocText").
 569  						Fn,
 570  				).Fn,
 571  			).
 572  			Rigid(
 573  				wg.ButtonLayout(wg.statusBarButtons[7]).
 574  					CornerRadius(0).
 575  					Embed(
 576  						wg.
 577  							Inset(
 578  								0.25, wg.
 579  									Icon().
 580  									Scale(gel.Scales["H5"]).
 581  									Color(clr).
 582  									Src(controllerIcon).Fn,
 583  							).Fn,
 584  					).
 585  					Background(wg.MainApp.StatusBarBackgroundGet()).
 586  					SetClick(
 587  						func() {
 588  							if wg.ChainClient != nil && !wg.ChainClient.Disconnected() {
 589  								wg.cx.Config.Controller.Flip()
 590  								I.Ln("controller running:",
 591  									wg.cx.Config.Controller.True())
 592  								var e error
 593  								if e = wg.ChainClient.SetGenerate(
 594  									wg.cx.Config.Controller.True(),
 595  									wg.cx.Config.GenThreads.V(),
 596  								); !E.Chk(e) {
 597  								}
 598  							}
 599  							// // wg.toggleMiner()
 600  							// go func() {
 601  							// 	if wg.miner.Running() {
 602  							// 		*wg.cx.Config.Generate = false
 603  							// 		wg.miner.Stop()
 604  							// 	} else {
 605  							// 		wg.miner.Start()
 606  							// 		*wg.cx.Config.Generate = true
 607  							// 	}
 608  							// 	save.Save(wg.cx.Config)
 609  							// }()
 610  						},
 611  					).
 612  					Fn,
 613  			).
 614  			Rigid(
 615  				wg.ButtonLayout(wg.statusBarButtons[1]).
 616  					CornerRadius(0).
 617  					Embed(
 618  						wg.Inset(
 619  							0.25, wg.
 620  								Icon().
 621  								Scale(gel.Scales["H5"]).
 622  								Color(clr2).
 623  								Src(miningIcon).Fn,
 624  						).Fn,
 625  					).
 626  					Background(wg.MainApp.StatusBarBackgroundGet()).
 627  					SetClick(
 628  						func() {
 629  							// wg.toggleMiner()
 630  							go func() {
 631  								if wg.cx.Config.GenThreads.V() != 0 {
 632  									if wg.miner.Running() {
 633  										wg.cx.Config.Generate.F()
 634  										wg.miner.Stop()
 635  									} else {
 636  										wg.miner.Start()
 637  										wg.cx.Config.Generate.T()
 638  									}
 639  									_ = wg.cx.Config.WriteToFile(wg.cx.Config.ConfigFile.V())
 640  								}
 641  							}()
 642  						},
 643  					).
 644  					Fn,
 645  			).
 646  			Rigid(
 647  				func(gtx l.Context) l.Dimensions {
 648  					return wg.incdecs["generatethreads"].
 649  						// Color("DocText").
 650  						// Background(wg.MainApp.StatusBarBackgroundGet()).
 651  						Fn(gtx)
 652  				},
 653  			).
 654  			Rigid(
 655  				func(gtx l.Context) l.Dimensions {
 656  					if !wg.wallet.Running() {
 657  						return l.Dimensions{}
 658  					}
 659  					
 660  					return wg.Flex().
 661  						Rigid(
 662  							wg.ButtonLayout(wg.statusBarButtons[2]).
 663  								CornerRadius(0).
 664  								Embed(
 665  									wg.Inset(0.25, ic).Fn,
 666  								).
 667  								Background(wg.MainApp.StatusBarBackgroundGet()).
 668  								SetClick(
 669  									func() {
 670  										D.Ln("clicked reset wallet button")
 671  										go func() {
 672  											var e error
 673  											wasRunning := wg.wallet.Running()
 674  											D.Ln("was running", wasRunning)
 675  											if wasRunning {
 676  												wg.wallet.Stop()
 677  											}
 678  											args := []string{
 679  												os.Args[0],
 680  												 "DD"+
 681  												wg.cx.Config.DataDir.V(),
 682  												"pipelog",
 683  												"walletpass"+
 684  												wg.cx.Config.WalletPass.V(),
 685  												"wallet",
 686  												"drophistory",
 687  											}
 688  											runner := exec.Command(args[0], args[1:]...)
 689  											runner.Stderr = os.Stderr
 690  											runner.Stdout = os.Stderr
 691  											if e = wg.writeWalletCookie(); E.Chk(e) {
 692  											}
 693  											if e = runner.Run(); E.Chk(e) {
 694  											}
 695  											if wasRunning {
 696  												wg.wallet.Start()
 697  											}
 698  										}()
 699  									},
 700  								).
 701  								Fn,
 702  						).Fn(gtx)
 703  				},
 704  			).
 705  			Fn(gtx)
 706  	}(gtx)
 707  }
 708  
 709  func (wg *WalletGUI) writeWalletCookie() (e error) {
 710  	// for security with apps launching the wallet, the public password can be set with a file that is deleted after
 711  	walletPassPath := filepath.Join(wg.cx.Config.DataDir.V(), wg.cx.ActiveNet.Name, "wp.txt")
 712  	D.Ln("runner", walletPassPath)
 713  	b := wg.cx.Config.WalletPass.Bytes()
 714  	if e = ioutil.WriteFile(walletPassPath, b, 0700); E.Chk(e) {
 715  	}
 716  	D.Ln("created password cookie")
 717  	return
 718  }
 719  
 720  //
 721  // func (wg *WalletGUI) toggleNode() {
 722  // 	if wg.node.Running() {
 723  // 		wg.node.Stop()
 724  // 		*wg.cx.Config.NodeOff = true
 725  // 	} else {
 726  // 		wg.node.Start()
 727  // 		*wg.cx.Config.NodeOff = false
 728  // 	}
 729  // 	save.Save(wg.cx.Config)
 730  // }
 731  //
 732  // func (wg *WalletGUI) startNode() {
 733  // 	if !wg.node.Running() {
 734  // 		wg.node.Start()
 735  // 	}
 736  // 	D.Ln("startNode")
 737  // }
 738  //
 739  // func (wg *WalletGUI) stopNode() {
 740  // 	if wg.wallet.Running() {
 741  // 		wg.stopWallet()
 742  // 		wg.unlockPassword.Wipe()
 743  // 		// wg.walletLocked.Store(true)
 744  // 	}
 745  // 	if wg.node.Running() {
 746  // 		wg.node.Stop()
 747  // 	}
 748  // 	D.Ln("stopNode")
 749  // }
 750  //
 751  // func (wg *WalletGUI) toggleMiner() {
 752  // 	if wg.miner.Running() {
 753  // 		wg.miner.Stop()
 754  // 		*wg.cx.Config.Generate = false
 755  // 	}
 756  // 	if !wg.miner.Running() && *wg.cx.Config.GenThreads > 0 {
 757  // 		wg.miner.Start()
 758  // 		*wg.cx.Config.Generate = true
 759  // 	}
 760  // 	save.Save(wg.cx.Config)
 761  // }
 762  //
 763  // func (wg *WalletGUI) startMiner() {
 764  // 	if *wg.cx.Config.GenThreads == 0 && wg.miner.Running() {
 765  // 		wg.stopMiner()
 766  // 		D.Ln("was zero threads")
 767  // 	} else {
 768  // 		wg.miner.Start()
 769  // 		D.Ln("startMiner")
 770  // 	}
 771  // }
 772  //
 773  // func (wg *WalletGUI) stopMiner() {
 774  // 	if wg.miner.Running() {
 775  // 		wg.miner.Stop()
 776  // 	}
 777  // 	D.Ln("stopMiner")
 778  // }
 779  //
 780  // func (wg *WalletGUI) toggleWallet() {
 781  // 	if wg.wallet.Running() {
 782  // 		wg.stopWallet()
 783  // 		*wg.cx.Config.WalletOff = true
 784  // 	} else {
 785  // 		wg.startWallet()
 786  // 		*wg.cx.Config.WalletOff = false
 787  // 	}
 788  // 	save.Save(wg.cx.Config)
 789  // }
 790  //
 791  // func (wg *WalletGUI) startWallet() {
 792  // 	if !wg.node.Running() {
 793  // 		wg.startNode()
 794  // 	}
 795  // 	if !wg.wallet.Running() {
 796  // 		wg.wallet.Start()
 797  // 		wg.unlockPassword.Wipe()
 798  // 		// wg.walletLocked.Store(false)
 799  // 	}
 800  // 	D.Ln("startWallet")
 801  // }
 802  //
 803  // func (wg *WalletGUI) stopWallet() {
 804  // 	if wg.wallet.Running() {
 805  // 		wg.wallet.Stop()
 806  // 		// wg.unlockPassword.Wipe()
 807  // 		// wg.walletLocked.Store(true)
 808  // 	}
 809  // 	wg.unlockPassword.Wipe()
 810  // 	D.Ln("stopWallet")
 811  // }
 812