diff --git a/app/gui/src/main/scala/org/bitcoins/gui/GlobalData.scala b/app/gui/src/main/scala/org/bitcoins/gui/GlobalData.scala index b14f2b7b56..20a840ee48 100644 --- a/app/gui/src/main/scala/org/bitcoins/gui/GlobalData.scala +++ b/app/gui/src/main/scala/org/bitcoins/gui/GlobalData.scala @@ -5,7 +5,7 @@ import org.bitcoins.core.config._ import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte} import org.bitcoins.crypto.DoubleSha256DigestBE import org.bitcoins.gui.settings.Themes -import scalafx.beans.property.StringProperty +import scalafx.beans.property._ object GlobalData { val currentConfirmedBalance: StringProperty = StringProperty("0") @@ -22,6 +22,21 @@ object GlobalData { val statusText: StringProperty = StringProperty("") + private val isConnectedStr = "● Connected" + private val isDisconnectedStr = "○ Disconnected" + + val connected: BooleanProperty = BooleanProperty(true) + + connected.addListener { (_, _, newValue) => + if (newValue) { + connectedStr.value = isConnectedStr + } else { + connectedStr.value = isDisconnectedStr + } + } + + val connectedStr: StringProperty = StringProperty(isConnectedStr) + var darkThemeEnabled: Boolean = true def currentStyleSheets: Seq[String] = diff --git a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUI.scala b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUI.scala index d16163d38d..c3629c4387 100644 --- a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUI.scala +++ b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUI.scala @@ -25,6 +25,11 @@ abstract class WalletGUI extends Logging { text <== StringProperty("Sync Height: ") + GlobalData.syncHeight } + private lazy val connectedLabel = new Label { + padding = Insets(top = 0, right = 0, bottom = 10, left = 1200) + text <== GlobalData.connectedStr + } + def fetchStartingData(): Unit = { model.startWalletInfoScheduler() model.updateFeeRate() @@ -102,7 +107,7 @@ abstract class WalletGUI extends Logging { } lazy val bottomStack: StackPane = new StackPane() { - children = Vector(statusLabel, infoLabel) + children = Vector(statusLabel, infoLabel, connectedLabel) } lazy val borderPane: BorderPane = new BorderPane { diff --git a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala index c31c0fa8cc..2e3a2559b9 100644 --- a/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala +++ b/app/gui/src/main/scala/org/bitcoins/gui/WalletGUIModel.scala @@ -12,8 +12,7 @@ import org.bitcoins.gui.dlc.DLCPaneModel import org.bitcoins.gui.util.GUIUtil import scalafx.application.Platform import scalafx.beans.property._ -import scalafx.scene.control.Alert.AlertType -import scalafx.scene.control.{Alert, TextArea} +import scalafx.scene.control.TextArea import scalafx.stage.Window import scala.concurrent.duration.DurationInt @@ -35,10 +34,14 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) override def run(): Unit = { Platform.runLater { - updateBalance() - updateWalletAccounting() - updateWalletInfo() + var success = updateBalance() + success &= updateWalletAccounting() + success &= updateWalletInfo() + // updateDLCs is a future, we can't get if it succeeded or not + // it should be caught by one of the others anyways dlcModel.updateDLCs() + + GlobalData.connected.value = success } } } @@ -99,15 +102,19 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) } updateBalance() + () } def onAbout(): Unit = { AboutDialog.showAndWait(parentWindow.value) } - private def updateWalletInfo(): Unit = { + /** Updates the wallet sync height + * @return if the update was successful + */ + private def updateWalletInfo(): Boolean = { ConsoleCli.exec(WalletInfo, GlobalData.consoleCliConfig) match { - case Failure(_) => () + case Failure(_) => false case Success(commandReturn) => val json = ujson.read(commandReturn).obj("wallet").obj val height = json("height").num.toLong @@ -115,10 +122,15 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) // Only update once we start syncing filters if (height != 0) GlobalData.syncHeight.value = height.toString + + true } } - private[gui] def updateBalance(): Unit = { + /** Updates the wallet balances + * @return if the update was successful + */ + private[gui] def updateBalance(): Boolean = { ConsoleCli.exec(GetBalances(isSats = true), GlobalData.consoleCliConfig) match { case Success(commandReturn) => @@ -140,21 +152,21 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) GlobalData.currentUnconfirmedBalance.value = unconfirmedBalance GlobalData.currentReservedBalance.value = reservedBalance GlobalData.currentTotalBalance.value = totalBalance + true case Failure(err) => err.printStackTrace() - val _ = new Alert(AlertType.Error) { - initOwner(owner) - title = "Could not retrieve wallet balance" - headerText = s"Operation failed. Exception: ${err.getClass}" - contentText = err.getMessage - }.showAndWait() + false } } - private def updateWalletAccounting(): Unit = { + /** Updates the wallet's DLC accounting details + * @return if the update was successful + */ + private def updateWalletAccounting(): Boolean = { ConsoleCli.exec(GetDLCWalletAccounting, GlobalData.consoleCliConfig) match { case Failure(err) => logger.error(s"Error fetching accounting", err) + false case Success(commandReturn) => val json = ujson.read(commandReturn).obj val pnl = json(PicklerKeys.pnl).num.toLong.toString @@ -162,7 +174,7 @@ class WalletGUIModel(dlcModel: DLCPaneModel)(implicit system: ActorSystem) val rorPrettyPrint = RateOfReturnUtil.prettyPrint(rateOfReturn) GlobalData.currentPNL.value = pnl GlobalData.rateOfReturn.value = rorPrettyPrint - () + true } } }