overview.go raw

   1  package gui
   2  
   3  import (
   4  	"fmt"
   5  	"strings"
   6  	"time"
   7  
   8  	icons2 "golang.org/x/exp/shiny/materialdesign/icons"
   9  
  10  	"github.com/p9c/p9/pkg/gel/gio/text"
  11  
  12  	l "github.com/p9c/p9/pkg/gel/gio/layout"
  13  
  14  	"github.com/p9c/p9/pkg/gel"
  15  	"github.com/p9c/p9/pkg/btcjson"
  16  )
  17  
  18  func (wg *WalletGUI) balanceCard() func(gtx l.Context) l.Dimensions {
  19  
  20  	// gtx.Constraints.Min.X = int(wg.TextSize.True * sp.inputWidth)
  21  	return func(gtx l.Context) l.Dimensions {
  22  		gtx.Constraints.Min.X =
  23  			int(wg.TextSize.V * 16)
  24  		gtx.Constraints.Max.X =
  25  			int(wg.TextSize.V * 16)
  26  		return wg.VFlex().
  27  			AlignStart().
  28  			Rigid(
  29  				wg.Inset(
  30  					0.25,
  31  					wg.H5("balances").
  32  						Fn,
  33  				).Fn,
  34  			).
  35  			Rigid(
  36  				wg.Fill(
  37  					"Primary", l.E, 0, 0,
  38  					wg.Inset(
  39  						0.25,
  40  						wg.Flex().
  41  							AlignEnd().
  42  							Flexed(
  43  								1,
  44  								wg.VFlex().AlignEnd().
  45  									Rigid(
  46  										wg.ButtonLayout(wg.clickables["balanceConfirmed"]).SetClick(
  47  											func() {
  48  												go wg.WriteClipboard(
  49  													fmt.Sprintf(
  50  														"%6.8f",
  51  														wg.State.balance.Load(),
  52  													),
  53  												)
  54  											},
  55  										).Background("Transparent").Embed(
  56  											wg.Flex().AlignEnd().Flexed(
  57  												1,
  58  												wg.Inset(
  59  													0.5,
  60  													wg.Caption(
  61  														"confirmed"+leftPadTo(
  62  															14, 14,
  63  															fmt.Sprintf(
  64  																"%6.8f",
  65  																wg.State.balance.Load(),
  66  															),
  67  														),
  68  													).
  69  														Font("go regular").
  70  														Alignment(text.End).
  71  														Color("DocText").Fn,
  72  												).Fn,
  73  											).Fn,
  74  										).Fn,
  75  									).
  76  									Rigid(
  77  										wg.ButtonLayout(wg.clickables["balanceUnconfirmed"]).SetClick(
  78  											func() {
  79  												go wg.WriteClipboard(
  80  													fmt.Sprintf(
  81  														"%6.8f",
  82  														wg.State.balanceUnconfirmed.Load(),
  83  													),
  84  												)
  85  											},
  86  										).Background("Transparent").Embed(
  87  											wg.Flex().AlignEnd().Flexed(
  88  												1,
  89  												wg.Inset(
  90  													0.5,
  91  													wg.Caption(
  92  														"unconfirmed"+leftPadTo(
  93  															14, 14,
  94  															fmt.Sprintf(
  95  																"%6.8f",
  96  																wg.State.balanceUnconfirmed.Load(),
  97  															),
  98  														),
  99  													).
 100  														Font("go regular").
 101  														Alignment(text.End).
 102  														Color("DocText").Fn,
 103  
 104  												).Fn,
 105  											).Fn,
 106  										).Fn,
 107  									).
 108  									Rigid(
 109  										wg.ButtonLayout(wg.clickables["balanceTotal"]).SetClick(
 110  											func() {
 111  												go wg.WriteClipboard(
 112  													fmt.Sprintf(
 113  														"%6.8f",
 114  														wg.State.balance.Load()+wg.State.balanceUnconfirmed.Load(),
 115  													),
 116  												)
 117  											},
 118  										).Background("Transparent").Embed(
 119  											wg.Flex().AlignEnd().Flexed(
 120  												1,
 121  												wg.Inset(
 122  													0.5,
 123  													wg.H5(
 124  														"total"+leftPadTo(
 125  															14, 14, fmt.Sprintf(
 126  																"%6.8f", wg.State.balance.Load()+wg.
 127  																	State.balanceUnconfirmed.Load(),
 128  															),
 129  														),
 130  													).
 131  														Alignment(text.End).
 132  														Color("DocText").Fn,
 133  												).
 134  													Fn,
 135  											).Fn,
 136  										).Fn,
 137  									).Fn,
 138  							).Fn,
 139  					).Fn,
 140  				).Fn,
 141  			).Fn(gtx)
 142  	}
 143  }
 144  
 145  func (wg *WalletGUI) OverviewPage() l.Widget {
 146  	if wg.RecentTxsWidget == nil {
 147  		wg.RecentTxsWidget = func(gtx l.Context) l.Dimensions {
 148  			return l.Dimensions{Size: gtx.Constraints.Max}
 149  		}
 150  	}
 151  	return func(gtx l.Context) l.Dimensions {
 152  		return wg.Responsive(
 153  			wg.Size.Load(), gel.Widgets{
 154  				{
 155  					Size: 0,
 156  					Widget:
 157  					wg.VFlex().AlignStart().
 158  						Rigid(
 159  							// wg.ButtonInset(0.25,
 160  							wg.VFlex().
 161  								Rigid(
 162  									wg.Inset(
 163  										0.25,
 164  										wg.balanceCard(),
 165  									).Fn,
 166  								).Fn,
 167  							// ).Fn,
 168  						).
 169  						// Rigid(wg.Inset(0.25, gel.EmptySpace(0, 0)).Fn).
 170  						Flexed(
 171  							1,
 172  							wg.VFlex().AlignStart().
 173  								Rigid(
 174  									wg.Inset(
 175  										0.25,
 176  										wg.H5("Recent Transactions").Fn,
 177  									).Fn,
 178  								).
 179  								Flexed(
 180  									1,
 181  									// wg.Inset(0.5,
 182  									wg.RecentTxsWidget,
 183  									// p9.EmptyMaxWidth(),
 184  									// ).Fn,
 185  								).
 186  								Fn,
 187  						).
 188  						Fn,
 189  				},
 190  				{
 191  					Size: 64,
 192  					Widget: wg.Flex().AlignStart().
 193  						Rigid(
 194  							// wg.ButtonInset(0.25,
 195  							wg.VFlex(). // SpaceSides().AlignStart().
 196  								Rigid(
 197  									wg.Inset(
 198  										0.25,
 199  										wg.balanceCard(),
 200  									).Fn,
 201  								).Fn,
 202  							// ).Fn,
 203  						).
 204  						// Rigid(wg.Inset(0.25, gel.EmptySpace(0, 0)).Fn).
 205  						Flexed(
 206  							1,
 207  							// wg.Inset(
 208  							// 	0.25,
 209  							wg.VFlex().AlignStart().
 210  								Rigid(
 211  									wg.Inset(
 212  										0.25,
 213  										wg.H5("Recent transactions").Fn,
 214  									).Fn,
 215  								).
 216  								Flexed(
 217  									1,
 218  									// wg.Fill("DocBg", l.W, wg.TextSize.True, 0, wg.Inset(0.25,
 219  									wg.RecentTxsWidget,
 220  									// p9.EmptyMaxWidth(),
 221  									// ).Fn).Fn,
 222  								).
 223  								Fn,
 224  							// ).
 225  							// 	Fn,
 226  						).
 227  						Fn,
 228  				},
 229  			},
 230  		).Fn(gtx)
 231  	}
 232  }
 233  
 234  func (wg *WalletGUI) recentTxCardStub(txs *btcjson.ListTransactionsResult) l.Widget {
 235  	return wg.Inset(
 236  		0.25,
 237  		wg.Flex().
 238  			// AlignBaseline().
 239  			// AlignStart().
 240  			// SpaceEvenly().
 241  			SpaceBetween().
 242  			// Flexed(
 243  			// 	1,
 244  			// 	wg.Inset(
 245  			// 		0.25,
 246  			// 		wg.Caption(txs.Address).
 247  			// 			Font("go regular").
 248  			// 			Color("PanelText").
 249  			// 			TextScale(0.66).
 250  			// 			Alignment(text.End).
 251  			// 			Fn,
 252  			// 	).Fn,
 253  			// ).
 254  			Rigid(
 255  				wg.Caption(fmt.Sprintf("%-6.8f DUO", txs.Amount)).Font("go regular").Color("DocText").Fn,
 256  			).
 257  			Rigid(
 258  				wg.Flex().
 259  					Rigid(
 260  						wg.Icon().Color("PanelText").Scale(1).Src(&icons2.DeviceWidgets).Fn,
 261  					).
 262  					Rigid(
 263  						wg.Caption(fmt.Sprint(txs.BlockIndex)).Fn,
 264  						// wg.buttonIconText(txs.clickBlock,
 265  						// 	fmt.Sprint(*txs.BlockIndex),
 266  						// 	&icons2.DeviceWidgets,
 267  						// 	wg.blockPage(*txs.BlockIndex)),
 268  					).
 269  					Fn,
 270  			).
 271  			Rigid(
 272  				wg.Flex().
 273  					Rigid(
 274  						wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionCheckCircle).Fn,
 275  					).
 276  					Rigid(
 277  						wg.Caption(fmt.Sprintf("%d ", txs.Confirmations)).Fn,
 278  					).
 279  					Fn,
 280  			).
 281  			Rigid(
 282  				wg.Flex().
 283  					Rigid(
 284  						func(gtx l.Context) l.Dimensions {
 285  							switch txs.Category {
 286  							case "generate":
 287  								return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionStars).Fn(gtx)
 288  							case "immature":
 289  								return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ImageTimeLapse).Fn(gtx)
 290  							case "receive":
 291  								return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionPlayForWork).Fn(gtx)
 292  							case "unknown":
 293  								return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.AVNewReleases).Fn(gtx)
 294  							}
 295  							return l.Dimensions{}
 296  						},
 297  					).
 298  					Rigid(
 299  						wg.Caption(txs.Category+" ").Fn,
 300  					).
 301  					Fn,
 302  			).
 303  			// Flexed(1, gel.EmptyMaxWidth()).
 304  			Rigid(
 305  				wg.Flex().
 306  					Rigid(
 307  						wg.Icon().Color("PanelText").Scale(1).Src(&icons2.DeviceAccessTime).Fn,
 308  					).
 309  					Rigid(
 310  						wg.Caption(
 311  							time.Unix(
 312  								txs.Time,
 313  								0,
 314  							).Format("02 Jan 06 15:04:05 MST"),
 315  						).Font("go regular").
 316  							// Alignment(text.End).
 317  							Color("PanelText").Fn,
 318  					).
 319  					Fn,
 320  			).
 321  			Fn,
 322  	).
 323  		Fn
 324  }
 325  
 326  func (wg *WalletGUI) recentTxCardSummary(txs *btcjson.ListTransactionsResult) l.Widget {
 327  	return wg.VFlex().AlignStart().SpaceBetween().
 328  		Rigid(
 329  			// wg.Inset(
 330  			// 	0.25,
 331  			wg.Flex().AlignStart().SpaceBetween().
 332  				Rigid(
 333  					wg.H6(fmt.Sprintf("%-.8f DUO", txs.Amount)).Alignment(text.Start).Color("PanelText").Fn,
 334  				).
 335  				Flexed(
 336  					1,
 337  					wg.Inset(
 338  						0.25,
 339  						wg.Caption(txs.Address).
 340  							Font("go regular").
 341  							Color("PanelText").
 342  							TextScale(0.66).
 343  							Alignment(text.End).
 344  							Fn,
 345  					).Fn,
 346  				).Fn,
 347  			// ).Fn,
 348  		).
 349  		Rigid(
 350  			// wg.Inset(
 351  			// 	0.25,
 352  			wg.Flex().
 353  				Flexed(
 354  					1,
 355  					wg.Flex().
 356  						Rigid(
 357  							wg.Flex().
 358  								Rigid(
 359  									wg.Icon().Color("PanelText").Scale(1).Src(&icons2.DeviceWidgets).Fn,
 360  								).
 361  								// Rigid(
 362  								// 	wg.Caption(fmt.Sprint(*txs.BlockIndex)).Fn,
 363  								// 	// wg.buttonIconText(txs.clickBlock,
 364  								// 	// 	fmt.Sprint(*txs.BlockIndex),
 365  								// 	// 	&icons2.DeviceWidgets,
 366  								// 	// 	wg.blockPage(*txs.BlockIndex)),
 367  								// ).
 368  								Rigid(
 369  									wg.Caption(fmt.Sprintf("%d ", txs.BlockIndex)).Fn,
 370  								).
 371  								Fn,
 372  						).
 373  						Rigid(
 374  							wg.Flex().
 375  								Rigid(
 376  									wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionCheckCircle).Fn,
 377  								).
 378  								Rigid(
 379  									wg.Caption(fmt.Sprintf("%d ", txs.Confirmations)).Fn,
 380  								).
 381  								Fn,
 382  						).
 383  						Rigid(
 384  							wg.Flex().
 385  								Rigid(
 386  									func(gtx l.Context) l.Dimensions {
 387  										switch txs.Category {
 388  										case "generate":
 389  											return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionStars).Fn(gtx)
 390  										case "immature":
 391  											return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ImageTimeLapse).Fn(gtx)
 392  										case "receive":
 393  											return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.ActionPlayForWork).Fn(gtx)
 394  										case "unknown":
 395  											return wg.Icon().Color("PanelText").Scale(1).Src(&icons2.AVNewReleases).Fn(gtx)
 396  										}
 397  										return l.Dimensions{}
 398  									},
 399  								).
 400  								Rigid(
 401  									wg.Caption(txs.Category+" ").Fn,
 402  								).
 403  								Fn,
 404  						).
 405  						Rigid(
 406  							wg.Flex().
 407  								Rigid(
 408  									wg.Icon().Color("PanelText").Scale(1).Src(&icons2.DeviceAccessTime).Fn,
 409  								).
 410  								Rigid(
 411  									wg.Caption(
 412  										time.Unix(
 413  											txs.Time,
 414  											0,
 415  										).Format("02 Jan 06 15:04:05 MST"),
 416  									).Color("PanelText").Fn,
 417  								).
 418  								Fn,
 419  						).Fn,
 420  				).Fn,
 421  			// ).Fn,
 422  		).Fn
 423  }
 424  
 425  func (wg *WalletGUI) recentTxCardSummaryButton(
 426  	txs *btcjson.ListTransactionsResult,
 427  	clickable *gel.Clickable,
 428  	bgColor string, back bool,
 429  ) l.Widget {
 430  	return wg.ButtonLayout(
 431  		clickable.SetClick(
 432  			func() {
 433  				D.Ln("clicked tx")
 434  				// D.S(txs)
 435  				curr := wg.openTxID.Load()
 436  				if curr == txs.TxID {
 437  					wg.prevOpenTxID.Store(wg.openTxID.Load())
 438  					wg.openTxID.Store("")
 439  					moveto := wg.originTxDetail
 440  					if moveto == "" {
 441  						moveto = wg.MainApp.ActivePageGet()
 442  					}
 443  					wg.MainApp.ActivePage(moveto)
 444  				} else {
 445  					if wg.MainApp.ActivePageGet() == "home" {
 446  						wg.originTxDetail = "home"
 447  						wg.MainApp.ActivePage("history")
 448  					} else {
 449  						wg.originTxDetail = "history"
 450  					}
 451  					wg.openTxID.Store(txs.TxID)
 452  				}
 453  			},
 454  		),
 455  	).
 456  		Background(bgColor).
 457  		Embed(
 458  			gel.If(
 459  				back,
 460  				wg.Flex().
 461  					Rigid(
 462  						wg.Icon().Color("PanelText").Scale(4).Src(&icons2.NavigationArrowBack).Fn,
 463  					).
 464  					Rigid(
 465  						wg.Inset(0.5, gel.EmptyMinWidth()).Fn,
 466  					).
 467  					Flexed(
 468  						1,
 469  						wg.Fill(
 470  							"DocBg", l.Center, 0, 0, wg.Inset(
 471  								0.5,
 472  								wg.recentTxCardSummary(txs),
 473  							).Fn,
 474  						).Fn,
 475  					).
 476  					Fn,
 477  				wg.Flex().
 478  					Rigid(
 479  						wg.Inset(0.5, gel.EmptyMaxHeight()).Fn,
 480  					).
 481  					Flexed(
 482  						1,
 483  						wg.Fill(
 484  							"DocBg", l.Center, 0, 0, wg.Inset(
 485  								0.5,
 486  								wg.recentTxCardSummary(txs),
 487  							).Fn,
 488  						).Fn,
 489  					).
 490  					Fn,
 491  			),
 492  		).Fn
 493  }
 494  
 495  func (wg *WalletGUI) recentTxCardSummaryButtonGenerate(
 496  	txs *btcjson.ListTransactionsResult,
 497  	clickable *gel.Clickable,
 498  	bgColor string, back bool,
 499  ) l.Widget {
 500  	return wg.ButtonLayout(
 501  		clickable.SetClick(
 502  			func() {
 503  				D.Ln("clicked tx")
 504  				// D.S(txs)
 505  				curr := wg.openTxID.Load()
 506  				if curr == txs.TxID {
 507  					wg.prevOpenTxID.Store(wg.openTxID.Load())
 508  					wg.openTxID.Store("")
 509  					moveto := wg.originTxDetail
 510  					if moveto == "" {
 511  						moveto = wg.MainApp.ActivePageGet()
 512  					}
 513  					wg.MainApp.ActivePage(moveto)
 514  				} else {
 515  					if wg.MainApp.ActivePageGet() == "home" {
 516  						wg.originTxDetail = "home"
 517  						wg.MainApp.ActivePage("history")
 518  					} else {
 519  						wg.originTxDetail = "history"
 520  					}
 521  					wg.openTxID.Store(txs.TxID)
 522  				}
 523  			},
 524  		),
 525  	).
 526  		Background(bgColor).
 527  		Embed(
 528  			wg.Flex().AlignStart().
 529  				Rigid(
 530  					// wg.Fill(
 531  					// 	"Primary", l.W, 0, 0, wg.Inset(
 532  					// 		0.5,
 533  					gel.If(
 534  						back,
 535  						wg.Flex().AlignStart().
 536  							Rigid(
 537  								wg.Icon().Color("PanelText").Scale(4).Src(&icons2.NavigationArrowBack).Fn,
 538  							).
 539  							Flexed(
 540  								1,
 541  								wg.recentTxCardSummary(txs),
 542  							).
 543  							Fn,
 544  						wg.Flex().AlignStart().
 545  							Flexed(
 546  								1,
 547  								wg.recentTxCardStub(txs),
 548  							).
 549  							Fn,
 550  						// wg.Flex().
 551  						// 	Rigid(
 552  						// 		wg.Inset(0.5, gel.EmptyMaxHeight()).Fn,
 553  						// 	).
 554  						// 	Flexed(
 555  						// 		1,
 556  						// 		wg.Fill(
 557  						// 			"DocBg", l.Center, 0, 0, wg.Inset(
 558  						// 				0.5,
 559  						// 				wg.recentTxCardSummary(txs),
 560  						// 			).Fn,
 561  						// 		).Fn,
 562  						// 	).
 563  						// 	Fn,
 564  					),
 565  				).Fn,
 566  			// ).Fn,
 567  			// ).Fn,
 568  		).Fn
 569  }
 570  
 571  func (wg *WalletGUI) recentTxCardDetail(txs *btcjson.ListTransactionsResult, clickable *gel.Clickable) l.Widget {
 572  	return wg.VFlex().
 573  		Rigid(
 574  			wg.Fill(
 575  				"Primary", l.Center, wg.TextSize.V, 0,
 576  				wg.recentTxCardSummaryButton(txs, clickable, "Primary", false),
 577  			).Fn,
 578  			// ).
 579  			// Rigid(
 580  			// 	wg.Fill(
 581  			// 		"DocBg", l.Center, wg.TextSize.True, 0,
 582  			// 		wg.Flex().
 583  			// 			Flexed(
 584  			// 				1,
 585  			// 				wg.Inset(
 586  			// 					0.25,
 587  			// 					wg.VFlex().
 588  			// 						Rigid(wg.Inset(0.25, gel.EmptySpace(0, 0)).Fn).
 589  			// 						Rigid(
 590  			// 							wg.H6("Transaction Details").
 591  			// 								Color("PanelText").
 592  			// 								Fn,
 593  			// 						).
 594  			// 						Rigid(
 595  			// 							wg.Inset(
 596  			// 								0.25,
 597  			// 								wg.VFlex().
 598  			// 									Rigid(
 599  			// 										wg.txDetailEntry("Transaction ID", txs.TxID),
 600  			// 									).
 601  			// 									Rigid(
 602  			// 										wg.txDetailEntry("Address", txs.Address),
 603  			// 									).
 604  			// 									Rigid(
 605  			// 										wg.txDetailEntry("Amount", fmt.Sprintf("%0.8f", txs.Amount)),
 606  			// 									).
 607  			// 									Rigid(
 608  			// 										wg.txDetailEntry("In Block", fmt.Sprint(txs.BlockIndex)),
 609  			// 									).
 610  			// 									Rigid(
 611  			// 										wg.txDetailEntry("First Mined", fmt.Sprint(txs.BlockTime)),
 612  			// 									).
 613  			// 									Rigid(
 614  			// 										wg.txDetailEntry("Category", txs.Category),
 615  			// 									).
 616  			// 									Rigid(
 617  			// 										wg.txDetailEntry("Confirmations", fmt.Sprint(txs.Confirmations)),
 618  			// 									).
 619  			// 									Rigid(
 620  			// 										wg.txDetailEntry("Fee", fmt.Sprintf("%0.8f", txs.Fee)),
 621  			// 									).
 622  			// 									Rigid(
 623  			// 										wg.txDetailEntry("Confirmations", fmt.Sprint(txs.Confirmations)),
 624  			// 									).
 625  			// 									Rigid(
 626  			// 										wg.txDetailEntry("Involves Watch Only", fmt.Sprint(txs.InvolvesWatchOnly)),
 627  			// 									).
 628  			// 									Rigid(
 629  			// 										wg.txDetailEntry("Time", fmt.Sprint(txs.Time)),
 630  			// 									).
 631  			// 									Rigid(
 632  			// 										wg.txDetailEntry("Time Received", fmt.Sprint(txs.TimeReceived)),
 633  			// 									).
 634  			// 									Rigid(
 635  			// 										wg.txDetailEntry("Trusted", fmt.Sprint(txs.Trusted)),
 636  			// 									).
 637  			// 									Rigid(
 638  			// 										wg.txDetailEntry("Abandoned", fmt.Sprint(txs.Abandoned)),
 639  			// 									).
 640  			// 									Rigid(
 641  			// 										wg.txDetailEntry("BIP125 Replaceable", fmt.Sprint(txs.BIP125Replaceable)),
 642  			// 									).
 643  			// 									Fn,
 644  			// 							).Fn,
 645  			// 						).Fn,
 646  			// 				).Fn,
 647  			// 			).Fn,
 648  			// 	).Fn,
 649  		).Fn
 650  }
 651  
 652  func (wg *WalletGUI) txDetailEntry(name, detail string, bgColor string, small bool) l.Widget {
 653  	content := wg.Body1
 654  	if small {
 655  		content = wg.Caption
 656  	}
 657  	return wg.Fill(
 658  		bgColor, l.Center, wg.TextSize.V, 0,
 659  		wg.Flex().AlignBaseline().
 660  			Flexed(
 661  				0.25,
 662  				wg.Inset(
 663  					0.25,
 664  					wg.Body1(name).
 665  						Color("PanelText").
 666  						Font("bariol bold").
 667  						Fn,
 668  				).Fn,
 669  			).
 670  			Flexed(
 671  				0.75,
 672  				wg.Flex().SpaceStart().Rigid(
 673  					wg.Inset(
 674  						0.25,
 675  						content(detail).Font("go regular").
 676  							Color("PanelText").
 677  							Fn,
 678  					).Fn,
 679  				).Fn,
 680  			).Fn,
 681  	).Fn
 682  }
 683  
 684  // RecentTransactions generates a display showing recent transactions
 685  //
 686  // fields to use: Address, Amount, BlockIndex, BlockTime, Category, Confirmations, Generated
 687  func (wg *WalletGUI) RecentTransactions(n int, listName string) l.Widget {
 688  	wg.txMx.Lock()
 689  	defer wg.txMx.Unlock()
 690  	// wg.ready.Store(false)
 691  	var out []l.Widget
 692  	// first := true
 693  	// out = append(out)
 694  	var txList []btcjson.ListTransactionsResult
 695  	var clickables []*gel.Clickable
 696  	txList = wg.txHistoryList
 697  	switch listName {
 698  	case "history":
 699  		clickables = wg.txHistoryClickables
 700  	case "recent":
 701  		// txList = wg.txRecentList
 702  		clickables = wg.recentTxsClickables
 703  	}
 704  	ltxl := len(txList)
 705  	ltc := len(clickables)
 706  	if ltxl > ltc {
 707  		count := ltxl - ltc
 708  		for ; count > 0; count-- {
 709  			clickables = append(clickables, wg.Clickable())
 710  		}
 711  	}
 712  	if len(clickables) == 0 {
 713  		return func(gtx l.Context) l.Dimensions {
 714  			return l.Dimensions{Size: gtx.Constraints.Max}
 715  		}
 716  	}
 717  	D.Ln(">>>>>>>>>>>>>>>> iterating transactions", n, listName)
 718  	var collected int
 719  	for x := range txList {
 720  		if collected >= n && n > 0 {
 721  			break
 722  		}
 723  		txs := txList[x]
 724  		switch listName {
 725  		case "history":
 726  			collected++
 727  		case "recent":
 728  			if txs.Category == "generate" || txs.Category == "immature" || txs.Amount < 0 && txs.Fee == 0 {
 729  				continue
 730  			} else {
 731  				collected++
 732  			}
 733  		}
 734  		// spacer
 735  		// if !first {
 736  		// 	out = append(
 737  		// 		out,
 738  		// 		wg.Inset(0.25, gel.EmptyMaxWidth()).Fn,
 739  		// 	)
 740  		// } else {
 741  		// 	first = false
 742  		// }
 743  
 744  		ck := clickables[x]
 745  		out = append(
 746  			out,
 747  			func(gtx l.Context) l.Dimensions {
 748  				return gel.If(
 749  					txs.Category == "immature",
 750  					wg.recentTxCardSummaryButtonGenerate(&txs, ck, "DocBg", false),
 751  					gel.If(
 752  						txs.Category == "send",
 753  						wg.recentTxCardSummaryButton(&txs, ck, "Danger", false),
 754  						gel.If(
 755  							txs.Category == "receive",
 756  							wg.recentTxCardSummaryButton(&txs, ck, "Success", false),
 757  							gel.If(
 758  								txs.Category == "generate",
 759  								wg.recentTxCardSummaryButtonGenerate(&txs, ck, "DocBg", false),
 760  								gel.If(
 761  									wg.prevOpenTxID.Load() == txs.TxID,
 762  									wg.recentTxCardSummaryButton(&txs, ck, "Primary", false),
 763  									wg.recentTxCardSummaryButton(&txs, ck, "DocBg", false),
 764  								),
 765  							),
 766  						),
 767  					),
 768  				)(gtx)
 769  			},
 770  		)
 771  		// out = append(out,
 772  		// 	wg.Caption(txs.TxID).
 773  		// 		Font("go regular").
 774  		// 		Color("PanelText").
 775  		// 		TextScale(0.5).Fn,
 776  		// )
 777  		// out = append(
 778  		// 	out,
 779  		// 	wg.Fill(
 780  		// 		"DocBg", l.W, 0, 0,
 781  		//
 782  		// 	).Fn,
 783  		// )
 784  	}
 785  	le := func(gtx l.Context, index int) l.Dimensions {
 786  		return wg.Inset(
 787  			0.25,
 788  			out[index],
 789  		).Fn(gtx)
 790  	}
 791  	wo := func(gtx l.Context) l.Dimensions {
 792  		return wg.VFlex().AlignStart().
 793  			Rigid(
 794  				wg.lists[listName].
 795  					Vertical().
 796  					Length(len(out)).
 797  					ListElement(le).
 798  					Fn,
 799  			).Fn(gtx)
 800  	}
 801  	D.Ln(">>>>>>>>>>>>>>>> history widget completed", n, listName)
 802  	switch listName {
 803  	case "history":
 804  		wg.TxHistoryWidget = wo
 805  	case "recent":
 806  		wg.RecentTxsWidget = wo
 807  	}
 808  	return func(gtx l.Context) l.Dimensions {
 809  		return wo(gtx)
 810  	}
 811  }
 812  
 813  func leftPadTo(length, limit int, txt string) string {
 814  	if len(txt) > limit {
 815  		return txt[:limit]
 816  	}
 817  	if len(txt) == limit {
 818  		return txt
 819  	}
 820  	pad := length - len(txt)
 821  	return strings.Repeat(" ", pad) + txt
 822  }
 823