diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 56db52d6ab3..13e02c07db4 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1595,9 +1595,10 @@ dao.proposal.myVote.button=Vote on all proposals dao.proposal.create.selectProposalType=Select proposal type dao.proposal.create.phase.inactive=Please wait until the next proposal phase dao.proposal.create.proposalType=Proposal type -dao.proposal.create.createNew=Make new proposal -dao.proposal.create.create.button=Make proposal +dao.proposal.create.new=Make new proposal +dao.proposal.create.button=Make proposal dao.proposal.create.publish=Publish proposal +dao.proposal.create.publishing=Proposal publishing is in progress ... dao.proposal=proposal dao.proposal.display.type=Proposal type dao.proposal.display.name=Name/nickname diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 8635f7b6a86..598796a5672 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -198,10 +198,10 @@ public void createAllFields(String title, int gridRowStartIndex, double top, Pro titledGroupBg = addTitledGroupBg(gridPane, gridRow, titledGroupBgRowSpan, title, top); double proposalTypeTop = top == Layout.GROUP_DISTANCE ? Layout.FIRST_ROW_AND_GROUP_DISTANCE : Layout.FIRST_ROW_DISTANCE; - proposalTypeTextField = FormBuilder.addTopLabelTextField(gridPane, gridRow, + proposalTypeTextField = addTopLabelTextField(gridPane, gridRow, Res.get("dao.proposal.display.type"), proposalType.getDisplayName(), proposalTypeTop).second; - nameTextField = addInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name")); + nameTextField = addInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.name"), Layout.FIRST_ROW_DISTANCE); if (isMakeProposalScreen) nameTextField.setValidator(new InputValidator()); inputControls.add(nameTextField); @@ -618,6 +618,10 @@ public int incrementAndGetGridRow() { return ++gridRow; } + public int getGridRow() { + return gridRow; + } + @SuppressWarnings("Duplicates") public ScrollPane getView() { ScrollPane scrollPane = new ScrollPane(); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index c9e77192f33..2f41c4fc847 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -20,6 +20,7 @@ import bisq.desktop.Navigation; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.governance.PhasesView; @@ -55,6 +56,7 @@ import bisq.common.app.DevEnv; import bisq.common.util.Tuple3; +import bisq.common.util.Tuple4; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -67,6 +69,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.beans.property.BooleanProperty; @@ -86,7 +89,7 @@ import javax.annotation.Nullable; -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.addButtonBusyAnimationLabel; import static bisq.desktop.util.FormBuilder.addComboBox; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; import static bisq.desktop.util.FormBuilder.addTopLabelReadOnlyTextField; @@ -112,6 +115,8 @@ public class MakeProposalView extends ActivatableView implements private TextField nextProposalTextField; private TitledGroupBg proposalTitledGroup; private VBox nextProposalBox; + private BusyAnimation busyAnimation; + private Label busyLabel; private BooleanProperty isProposalPhase = new SimpleBooleanProperty(false); private StringProperty proposalGroupTitle = new SimpleStringProperty(Res.get("dao.proposal.create.phase.inactive")); @@ -321,19 +326,31 @@ private void showFeeInfoAndPublishMyProposal(Proposal proposal, Transaction tran } private void doPublishMyProposal(Proposal proposal, Transaction transaction) { + + busyLabel.setVisible(true); + busyAnimation.play(); + makeProposalButton.setDisable(true); + daoFacade.publishMyProposal(proposal, transaction, () -> { if (!DevEnv.isDevMode()) new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); + + if (proposalDisplay != null) + proposalDisplay.clearForm(); + proposalTypeComboBox.getSelectionModel().clearSelection(); + busyAnimation.stop(); + busyLabel.setVisible(false); + makeProposalButton.setDisable(false); }, - errorMessage -> new Popup<>().warning(errorMessage).show()); + errorMessage -> { + new Popup<>().warning(errorMessage).show(); + busyAnimation.stop(); + busyLabel.setVisible(false); + makeProposalButton.setDisable(false); + }); - // We reset UI without waiting for callback as callback might be slow and then the user could create multiple - // proposals. - if (proposalDisplay != null) - proposalDisplay.clearForm(); - proposalTypeComboBox.getSelectionModel().clearSelection(); } @Nullable @@ -412,10 +429,19 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) private void addProposalDisplay() { if (selectedProposalType != null) { proposalDisplay = new ProposalDisplay(root, bsqFormatter, daoFacade, changeParamValidator, navigation); - proposalDisplay.createAllFields(Res.get("dao.proposal.create.createNew"), alwaysVisibleGridRowIndex, Layout.GROUP_DISTANCE, + + proposalDisplay.createAllFields(Res.get("dao.proposal.create.new"), alwaysVisibleGridRowIndex, Layout.GROUP_DISTANCE, selectedProposalType, true); - makeProposalButton = addButtonAfterGroup(root, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.create.create.button")); + final Tuple4 makeProposalTuple = addButtonBusyAnimationLabel(root, + proposalDisplay.getGridRow(), 0, Res.get("dao.proposal.create.button"), 0); + makeProposalButton = makeProposalTuple.first; + + busyAnimation = makeProposalTuple.second; + busyLabel = makeProposalTuple.third; + busyLabel.setVisible(false); + busyLabel.setText(Res.get("dao.proposal.create.publishing")); + setMakeProposalButtonHandler(); proposalDisplay.addInputChangedListener(this::updateButtonState); updateButtonState();