Add new tab for funds

This commit is contained in:
Manfred Karrer 2015-04-05 02:00:38 +02:00
parent f498d393b0
commit bcb22ddaa3
44 changed files with 1008 additions and 610 deletions

View File

@ -17,7 +17,6 @@
package io.bitsquare;
@SuppressWarnings("serializable")
public class BitsquareException extends RuntimeException {
private static final long serialVersionUID = 556191645860856173L;

View File

@ -33,6 +33,7 @@ public class TaskRunner<T extends Model> {
private final Queue<Class<? extends Task>> tasks = new LinkedBlockingQueue<>();
protected final T sharedModel;
private final Class<? extends Model> sharedModelClass;
private final ResultHandler resultHandler;
private final ErrorMessageHandler errorMessageHandler;
private boolean failed = false;
@ -40,10 +41,16 @@ public class TaskRunner<T extends Model> {
private Class<? extends Task> currentTask;
public TaskRunner(T sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
this(sharedModel, sharedModel.getClass(), resultHandler, errorMessageHandler);
}
public TaskRunner(T sharedModel, Class<? extends Model> sharedModelClass, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
this.sharedModel = sharedModel;
this.resultHandler = resultHandler;
this.errorMessageHandler = errorMessageHandler;
this.sharedModelClass = sharedModelClass;
}
public final void addTasks(Class<? extends Task<? extends Model>>... items) {
@ -61,12 +68,7 @@ public class TaskRunner<T extends Model> {
try {
currentTask = tasks.poll();
log.trace("Run task: " + currentTask.getSimpleName());
// We use also super class as type ein tasks, so we need to support both variants
try {
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
} catch (Throwable throwable) {
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass().getSuperclass()).newInstance(this, sharedModel).run();
}
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModelClass).newInstance(this, sharedModel).run();
} catch (Throwable throwable) {
throwable.printStackTrace();
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());

View File

@ -23,6 +23,7 @@
AnchorPane.topAnchor="0.0"
xmlns:fx="http://javafx.com/fxml">
<Tab fx:id="reservedTab" text="Reserved for trades" closable="false"/>
<Tab fx:id="withdrawalTab" text="Open for withdrawal" closable="false"/>
<Tab fx:id="transactionsTab" text="Transactions" closable="false"/>

View File

@ -25,6 +25,7 @@ import io.bitsquare.common.viewfx.view.View;
import io.bitsquare.common.viewfx.view.ViewLoader;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.funds.reserved.ReservedView;
import io.bitsquare.gui.main.funds.transactions.TransactionsView;
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
@ -37,7 +38,7 @@ import javafx.scene.control.*;
@FxmlView
public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
@FXML Tab withdrawalTab, transactionsTab;
@FXML Tab reservedTab, withdrawalTab, transactionsTab;
private Navigation.Listener navigationListener;
private ChangeListener<Tab> tabChangeListener;
@ -60,7 +61,9 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
};
tabChangeListener = (ov, oldValue, newValue) -> {
if (newValue == withdrawalTab)
if (newValue == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
else if (newValue == withdrawalTab)
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (newValue == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
@ -72,10 +75,12 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
else
if (root.getSelectionModel().getSelectedItem() == reservedTab)
navigation.navigateTo(MainView.class, FundsView.class, ReservedView.class);
else if (root.getSelectionModel().getSelectedItem() == withdrawalTab)
navigation.navigateTo(MainView.class, FundsView.class, WithdrawalView.class);
else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
}
@Override
@ -92,7 +97,9 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
View view = viewLoader.load(viewClass);
if (view instanceof WithdrawalView)
if (view instanceof ReservedView)
currentTab = reservedTab;
else if (view instanceof WithdrawalView)
currentTab = withdrawalTab;
else if (view instanceof TransactionsView)
currentTab = transactionsTab;

View File

@ -0,0 +1,170 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds.reserved;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.AddressConfidenceListener;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BSFormatter;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.TransactionConfidence;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.*;
import static com.google.common.base.Preconditions.checkNotNull;
public class ReservedListItem {
private final StringProperty addressString = new SimpleStringProperty();
private final BalanceListener balanceListener;
private final Label balanceLabel;
private final AddressEntry addressEntry;
private final WalletService walletService;
private final BSFormatter formatter;
private final AddressConfidenceListener confidenceListener;
private final ConfidenceProgressIndicator progressIndicator;
private final Tooltip tooltip;
private Coin balance;
public ReservedListItem(AddressEntry addressEntry, WalletService walletService, BSFormatter formatter) {
this.addressEntry = addressEntry;
this.walletService = walletService;
this.formatter = formatter;
this.addressString.set(getAddress().toString());
// confidence
progressIndicator = new ConfidenceProgressIndicator();
progressIndicator.setId("funds-confidence");
tooltip = new Tooltip("Not used yet");
progressIndicator.setProgress(0);
progressIndicator.setPrefSize(24, 24);
Tooltip.install(progressIndicator, tooltip);
confidenceListener = walletService.addAddressConfidenceListener(new AddressConfidenceListener(getAddress()) {
@Override
public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
updateConfidence(confidence);
}
});
updateConfidence(walletService.getConfidenceForAddress(getAddress()));
// balance
balanceLabel = new Label();
balanceListener = walletService.addBalanceListener(new BalanceListener(getAddress()) {
@Override
public void onBalanceChanged(Coin balance) {
updateBalance(balance);
}
});
updateBalance(walletService.getBalanceForAddress(getAddress()));
}
public void cleanup() {
walletService.removeAddressConfidenceListener(confidenceListener);
walletService.removeBalanceListener(balanceListener);
}
private void updateBalance(Coin balance) {
this.balance = balance;
if (balance != null) {
balanceLabel.setText(formatter.formatCoin(balance));
}
}
private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) {
//log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " +
// confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks());
switch (confidence.getConfidenceType()) {
case UNKNOWN:
tooltip.setText("Unknown transaction status");
progressIndicator.setProgress(0);
break;
case PENDING:
tooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 confirmations");
progressIndicator.setProgress(-1.0);
break;
case BUILDING:
tooltip.setText("Confirmed in " + confidence.getDepthInBlocks() + " block(s)");
progressIndicator.setProgress(Math.min(1, (double) confidence.getDepthInBlocks() / 6.0));
break;
case DEAD:
tooltip.setText("Transaction is invalid.");
progressIndicator.setProgress(0);
break;
}
}
}
public final String getLabel() {
switch (addressEntry.getContext()) {
case REGISTRATION_FEE:
return "Registration fee";
case TRADE:
checkNotNull(addressEntry.getOfferId());
return "Offer ID: " + addressEntry.getOfferId();
case ARBITRATOR_DEPOSIT:
return "Arbitration deposit";
}
return "";
}
public final StringProperty addressStringProperty() {
return this.addressString;
}
Address getAddress() {
return addressEntry.getAddress();
}
public AddressEntry getAddressEntry() {
return addressEntry;
}
public ConfidenceProgressIndicator getProgressIndicator() {
return progressIndicator;
}
public Label getBalanceLabel() {
return balanceLabel;
}
public Coin getBalance() {
return balance;
}
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ This file is part of Bitsquare.
~
~ Bitsquare is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox fx:id="root" fx:controller="io.bitsquare.gui.main.funds.reserved.ReservedView"
spacing="10" xmlns:fx="http://javafx.com/fxml">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<TableView fx:id="table" VBox.vgrow="ALWAYS">
<columns>
<TableColumn text="Label" fx:id="labelColumn" minWidth="100" sortable="false"/>
<TableColumn text="Address" fx:id="addressColumn" minWidth="240" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="addressString"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Balance" fx:id="balanceColumn" minWidth="50" sortable="false"/>
<TableColumn text="Copy" fx:id="copyColumn" minWidth="30" sortable="false"/>
<TableColumn text="Status" fx:id="confidenceColumn" minWidth="30" sortable="false"/>
</columns>
</TableView>
</VBox>

View File

@ -0,0 +1,234 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.funds.reserved;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
import io.bitsquare.common.viewfx.view.FxmlView;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Coin;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.Callback;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
@FxmlView
public class ReservedView extends ActivatableViewAndModel {
@FXML TableView<ReservedListItem> table;
@FXML TableColumn<ReservedListItem, ReservedListItem> labelColumn, addressColumn, balanceColumn, copyColumn,
confidenceColumn;
private final WalletService walletService;
private final TradeManager tradeManager;
private final BSFormatter formatter;
private final ObservableList<ReservedListItem> addressList = FXCollections.observableArrayList();
@Inject
private ReservedView(WalletService walletService, TradeManager tradeManager, BSFormatter formatter) {
this.walletService = walletService;
this.tradeManager = tradeManager;
this.formatter = formatter;
}
@Override
public void initialize() {
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No funded are reserved in open offers or trades"));
setLabelColumnCellFactory();
setBalanceColumnCellFactory();
setCopyColumnCellFactory();
setConfidenceColumnCellFactory();
}
@Override
public void doActivate() {
fillList();
table.setItems(addressList);
walletService.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance) {
fillList();
}
});
}
@Override
public void doDeactivate() {
addressList.forEach(ReservedListItem::cleanup);
}
private void fillList() {
addressList.clear();
addressList.addAll(Stream.concat(tradeManager.getOpenOfferTrades().stream(), tradeManager.getPendingTrades().stream())
.map(trade -> new ReservedListItem(walletService.getAddressEntry(trade.getId()), walletService, formatter))
.collect(Collectors.toList()));
// List<AddressEntry> addressEntryList = walletService.getAddressEntryList();
/* addressList.addAll(addressEntryList.stream()
.filter(e -> walletService.getBalanceForAddress(e.getAddress()).isPositive())
.map(anAddressEntryList -> new ReservedListItem(anAddressEntryList, walletService, formatter))
.collect(Collectors.toList()));*/
}
private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<ReservedListItem, ReservedListItem>,
TableCell<ReservedListItem,
ReservedListItem>>() {
@Override
public TableCell<ReservedListItem, ReservedListItem> call(TableColumn<ReservedListItem,
ReservedListItem> column) {
return new TableCell<ReservedListItem, ReservedListItem>() {
private Hyperlink hyperlink;
@Override
public void updateItem(final ReservedListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
hyperlink = new Hyperlink(item.getLabel());
hyperlink.setId("id-link");
if (item.getAddressEntry().getOfferId() != null) {
Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId());
Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry
().getOfferId()));
}
setGraphic(hyperlink);
}
else {
setGraphic(null);
setId(null);
}
}
};
}
});
}
private void setBalanceColumnCellFactory() {
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
balanceColumn.setCellFactory(
new Callback<TableColumn<ReservedListItem, ReservedListItem>, TableCell<ReservedListItem,
ReservedListItem>>() {
@Override
public TableCell<ReservedListItem, ReservedListItem> call(TableColumn<ReservedListItem,
ReservedListItem> column) {
return new TableCell<ReservedListItem, ReservedListItem>() {
@Override
public void updateItem(final ReservedListItem item, boolean empty) {
super.updateItem(item, empty);
setGraphic((item != null && !empty) ? item.getBalanceLabel() : null);
}
};
}
});
}
private void setCopyColumnCellFactory() {
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
copyColumn.setCellFactory(
new Callback<TableColumn<ReservedListItem, ReservedListItem>, TableCell<ReservedListItem,
ReservedListItem>>() {
@Override
public TableCell<ReservedListItem, ReservedListItem> call(TableColumn<ReservedListItem,
ReservedListItem> column) {
return new TableCell<ReservedListItem, ReservedListItem>() {
final Label copyIcon = new Label();
{
copyIcon.getStyleClass().add("copy-icon");
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
}
@Override
public void updateItem(final ReservedListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
setGraphic(copyIcon);
copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(item
.addressStringProperty().get()));
}
else {
setGraphic(null);
}
}
};
}
});
}
private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) ->
new ReadOnlyObjectWrapper<>(addressListItem.getValue()));
confidenceColumn.setCellFactory(
new Callback<TableColumn<ReservedListItem, ReservedListItem>, TableCell<ReservedListItem,
ReservedListItem>>() {
@Override
public TableCell<ReservedListItem, ReservedListItem> call(TableColumn<ReservedListItem,
ReservedListItem> column) {
return new TableCell<ReservedListItem, ReservedListItem>() {
@Override
public void updateItem(final ReservedListItem item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
setGraphic(item.getProgressIndicator());
}
else {
setGraphic(null);
}
}
};
}
});
}
}

View File

@ -26,6 +26,7 @@ import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
import io.bitsquare.common.viewfx.view.FxmlView;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.AddressFormatException;
@ -37,6 +38,7 @@ import com.google.common.util.concurrent.FutureCallback;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
@ -64,12 +66,14 @@ public class WithdrawalView extends ActivatableViewAndModel {
confidenceColumn;
private final WalletService walletService;
private TradeManager tradeManager;
private final BSFormatter formatter;
private final ObservableList<WithdrawalListItem> addressList = FXCollections.observableArrayList();
@Inject
private WithdrawalView(WalletService walletService, BSFormatter formatter) {
private WithdrawalView(WalletService walletService, TradeManager tradeManager, BSFormatter formatter) {
this.walletService = walletService;
this.tradeManager = tradeManager;
this.formatter = formatter;
}
@ -77,7 +81,7 @@ public class WithdrawalView extends ActivatableViewAndModel {
@Override
public void initialize() {
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setPlaceholder(new Label("No funded wallets for withdrawal available"));
table.setPlaceholder(new Label("No funds for withdrawal available"));
setLabelColumnCellFactory();
setBalanceColumnCellFactory();
@ -176,8 +180,14 @@ public class WithdrawalView extends ActivatableViewAndModel {
private void fillList() {
addressList.clear();
List<AddressEntry> addressEntryList = walletService.getAddressEntryList();
List<String> reservedTrades = Stream.concat(tradeManager.getOpenOfferTrades().stream(), tradeManager.getPendingTrades().stream())
.map(trade -> trade.getId())
.collect(Collectors.toList());
addressList.addAll(addressEntryList.stream()
.filter(e -> walletService.getBalanceForAddress(e.getAddress()).isPositive())
.filter(e -> !reservedTrades.contains(e.getOfferId()))
.map(anAddressEntryList -> new WithdrawalListItem(anAddressEntryList, walletService, formatter))
.collect(Collectors.toList()));
}

View File

@ -76,8 +76,6 @@ public class PortfolioView extends ActivatableViewAndModel<TabPane, Activatable>
root.getSelectionModel().selectedItemProperty().addListener(tabChangeListener);
navigation.addListener(navigationListener);
// navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
/* if (tradeManager.getPendingTrades().size() == 0)
navigation.navigateTo(MainView.class, PortfolioView.class, OffersView.class);
else

View File

@ -74,7 +74,7 @@ class ClosedTradesDataModel implements Activatable, DataModel {
list.addAll(tradeManager.getClosedTrades().stream().map(ClosedTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getTakeOfferDate().compareTo(o1.getTrade().getTakeOfferDate()));
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
}
}

View File

@ -65,7 +65,7 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
}
String getDate(ClosedTradesListItem item) {
return formatter.formatDateTime(item.getTrade().getTakeOfferDate());
return formatter.formatDateTime(item.getTrade().getDate());
}
String getState(ClosedTradesListItem item) {

View File

@ -43,6 +43,8 @@ import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
@ -62,18 +64,20 @@ class PendingTradesDataModel implements Activatable, DataModel {
private Navigation navigation;
private final ObservableList<PendingTradesListItem> list = FXCollections.observableArrayList();
private PendingTradesListItem selectedItem;
private boolean isOfferer;
private final ListChangeListener<Trade> tradesListChangeListener;
private boolean isOffererRole;
final StringProperty txId = new SimpleStringProperty();
private final ObjectProperty<TradeState.ProcessState> sellerProcessState = new SimpleObjectProperty<>();
private final ObjectProperty<TradeState.ProcessState> buyerProcessState = new SimpleObjectProperty<>();
private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>();
private final StringProperty txId = new SimpleStringProperty();
private Trade trade;
final ObjectProperty<TradeState.ProcessState> sellerProcessState = new SimpleObjectProperty<>();
final ObjectProperty<TradeState.ProcessState> buyerProcessState = new SimpleObjectProperty<>();
final ObjectProperty<Trade> currentTrade = new SimpleObjectProperty<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, initialization
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user, Navigation navigation) {
@ -102,23 +106,26 @@ class PendingTradesDataModel implements Activatable, DataModel {
list.addAll(tradeManager.getPendingTrades().stream().map(PendingTradesListItem::new).collect(Collectors.toList()));
// we sort by date, earliest first
list.sort((o1, o2) -> o2.getTrade().getTakeOfferDate().compareTo(o1.getTrade().getTakeOfferDate()));
list.sort((o1, o2) -> o2.getTrade().getDate().compareTo(o1.getTrade().getDate()));
log.debug("onListChanged {}", list.size());
if (list.size() > 0)
selectTrade(list.get(0));
onSelectTrade(list.get(0));
else if (list.size() == 0)
selectTrade(null);
onSelectTrade(null);
}
boolean isBuyOffer() throws NoTradeFoundException {
if (getTrade() != null)
return getTrade().getOffer().getDirection() == Offer.Direction.BUY;
else
throw new NoTradeFoundException();
private void unbindStates() {
sellerProcessState.unbind();
buyerProcessState.unbind();
}
void selectTrade(PendingTradesListItem item) {
///////////////////////////////////////////////////////////////////////////////////////////
// UI actions
///////////////////////////////////////////////////////////////////////////////////////////
void onSelectTrade(PendingTradesListItem item) {
log.debug("selectTrade {} {}", item != null, item != null ? item.getTrade().getId() : "null");
// clean up previous selectedItem
unbindStates();
@ -126,13 +133,14 @@ class PendingTradesDataModel implements Activatable, DataModel {
selectedItem = item;
if (item == null) {
currentTrade.set(null);
trade = null;
tradeProperty.set(null);
}
else {
currentTrade.set(item.getTrade());
trade = item.getTrade();
tradeProperty.set(trade);
Trade trade = item.getTrade();
isOfferer = trade.getOffer().getP2pSigPubKey().equals(user.getP2pSigPubKey());
isOffererRole = trade.getOffer().getP2pSigPubKey().equals(user.getP2pSigPubKey());
if (trade instanceof SellerTrade)
sellerProcessState.bind(trade.processStateProperty());
@ -144,37 +152,32 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
}
void fiatPaymentStarted() {
try {
if (getTrade() instanceof BuyerTrade)
((BuyerTrade) getTrade()).onFiatPaymentStarted();
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
void onFiatPaymentStarted() {
assert trade != null;
if (trade instanceof BuyerTrade)
((BuyerTrade) trade).onFiatPaymentStarted();
}
void fiatPaymentReceived() {
try {
if (getTrade() instanceof SellerTrade)
((SellerTrade) getTrade()).onFiatPaymentReceived();
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
void onFiatPaymentReceived() {
assert trade != null;
if (trade instanceof SellerTrade)
((SellerTrade) trade).onFiatPaymentReceived();
}
void withdraw(String toAddress) {
try {
if (getTrade() != null) {
tradeManager.requestWithdraw(toAddress,
getTrade(),
() -> {
log.debug("requestWithdraw was successful");
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
},
(errorMessage, throwable) -> {
log.error(errorMessage);
Popups.openExceptionPopup(throwable);
});
void onWithdrawRequest(String toAddress) {
assert trade != null;
tradeManager.onWithdrawRequest(
toAddress,
trade,
() -> {
log.debug("requestWithdraw was successful");
Platform.runLater(() -> navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class));
},
(errorMessage, throwable) -> {
log.error(errorMessage);
Popups.openExceptionPopup(throwable);
});
/*
@ -203,27 +206,27 @@ class PendingTradesDataModel implements Activatable, DataModel {
Popups.openErrorPopup("Wrong inputs", "Please check the inputs.");
}
}*/
}
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ObservableList<PendingTradesListItem> getList() {
return list;
}
boolean isOfferer() {
return isOfferer;
boolean isBuyOffer() {
return trade.getOffer().getDirection() == Offer.Direction.BUY;
}
/* @Nullable
Trade getTrade() {
return selectedItem != null ? selectedItem.getTrade() : null;
}*/
boolean isOffererRole() {
return isOffererRole;
}
Coin getTotalFees() {
return FeePolicy.TX_FEE.add(isOfferer() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE);
return FeePolicy.TX_FEE.add(isOffererRole() ? FeePolicy.CREATE_OFFER_FEE : FeePolicy.TAKE_OFFER_FEE);
}
WalletService getWalletService() {
@ -235,56 +238,48 @@ class PendingTradesDataModel implements Activatable, DataModel {
}
String getCurrencyCode() {
return selectedItem.getTrade().getOffer().getCurrencyCode();
return trade.getOffer().getCurrencyCode();
}
Throwable getTradeException() {
try {
return getTrade().getThrowable();
} catch (NoTradeFoundException e) {
return null;
}
return trade.getThrowable();
}
String getErrorMessage() {
try {
return getTrade().getErrorMessage();
} catch (NoTradeFoundException e) {
return null;
}
return trade.getErrorMessage();
}
public Offer.Direction getDirection(Offer offer) {
return offer.getP2pSigPubKey().equals(user.getP2pSigPubKey()) ?
offer.getDirection() : offer.getMirroredDirection();
return isOffererRole ? offer.getDirection() : offer.getMirroredDirection();
}
private void unbindStates() {
sellerProcessState.unbind();
buyerProcessState.unbind();
Coin getPayoutAmount() {
return trade.getPayoutAmount();
}
public Coin getPayoutAmount() {
try {
return getTrade().getPayoutAmount();
} catch (NoTradeFoundException e) {
return Coin.ZERO;
}
Contract getContract() {
return trade.getContract();
}
public Contract getContract() {
try {
return getTrade().getContract();
} catch (NoTradeFoundException e) {
throw new MissingTradeException();
}
Trade getTrade() {
return trade;
}
public Trade getTrade() throws NoTradeFoundException {
if (currentTrade.get() != null)
return currentTrade.get();
else
throw new NoTradeFoundException();
ReadOnlyObjectProperty<TradeState.ProcessState> getSellerProcessState() {
return sellerProcessState;
}
ReadOnlyObjectProperty<TradeState.ProcessState> getBuyerProcessState() {
return buyerProcessState;
}
ReadOnlyObjectProperty<Trade> getTradeProperty() {
return tradeProperty;
}
ReadOnlyStringProperty getTxId() {
return txId;
}
}

View File

@ -65,7 +65,7 @@ public class PendingTradesListItem {
}
public Date getDate() {
return trade.getTakeOfferDate();
return trade.getDate();
}
public String getId() {

View File

@ -45,9 +45,7 @@ import javafx.util.StringConverter;
public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTradesViewModel> {
@FXML AnchorPane tradeStepPane;
@FXML TableView<PendingTradesListItem> table;
@FXML TableColumn<PendingTradesListItem, Fiat> priceColumn;
@FXML TableColumn<PendingTradesListItem, Fiat> tradeVolumeColumn;
@FXML TableColumn<PendingTradesListItem, PendingTradesListItem> directionColumn;
@ -61,6 +59,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
private ReadOnlyBooleanProperty appFocusProperty;
private ChangeListener<Trade> currentTradeChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
///////////////////////////////////////////////////////////////////////////////////////////
@ -83,8 +82,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
table.setPlaceholder(new Label("No pending trades available"));
selectedItemChangeListener = (ov, oldValue, newValue) -> {
log.debug("selectedItemChangeListener {}", newValue);
model.selectTrade(newValue);
model.onSelectTrade(newValue);
if (newValue != null)
addSubView();
@ -93,7 +91,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
};
appFocusChangeListener = (observable, oldValue, newValue) -> {
log.debug("appFocusChangeListener {}", newValue);
if (newValue && model.getSelectedItem() != null) {
// Focus selectedItem from model
int index = table.getItems().indexOf(model.getSelectedItem());
@ -105,7 +102,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
};
currentTradeChangeListener = (observable, oldValue, newValue) -> {
log.debug("currentTradeChangeListener {} {}", newValue, model.getList().size());
if (newValue != null)
addSubView();
else
@ -113,7 +109,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
};
}
@Override
public void doActivate() {
appFocusProperty = root.getScene().getWindow().focusedProperty();
@ -144,42 +139,33 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
@Override
public void doDeactivate() {
table.getSelectionModel().selectedItemProperty().removeListener(selectedItemChangeListener);
model.currentTrade().removeListener(currentTradeChangeListener);
appFocusProperty.removeListener(appFocusChangeListener);
appFocusProperty = null;
if (currentSubView != null)
currentSubView.deactivate();
appFocusProperty.removeListener(appFocusChangeListener);
model.currentTrade().removeListener(currentTradeChangeListener);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
// Subviews
///////////////////////////////////////////////////////////////////////////////////////////
private void addSubView() {
log.debug("addSubView");
removeSubView();
if (model.isOfferer()) {
try {
if (model.isBuyOffer())
currentSubView = new BuyerSubView(model);
else
currentSubView = new SellerSubView(model);
} catch (NoTradeFoundException e) {
log.warn("No trade selected");
}
if (model.isBuyOffer())
currentSubView = new BuyerSubView(model);
else
currentSubView = new SellerSubView(model);
}
else {
try {
if (model.isBuyOffer())
currentSubView = new SellerSubView(model);
else
currentSubView = new BuyerSubView(model);
} catch (NoTradeFoundException e) {
log.warn("No trade selected");
}
if (model.isBuyOffer())
currentSubView = new SellerSubView(model);
else
currentSubView = new BuyerSubView(model);
}
if (currentSubView != null) {
currentSubView.activate();
@ -189,7 +175,6 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
AnchorPane.setBottomAnchor(currentSubView, 0d);
AnchorPane.setLeftAnchor(currentSubView, 0d);
tradeStepPane.getChildren().setAll(currentSubView);
log.warn("currentSubView added");
}
else {
log.warn("currentSubView=null");
@ -197,9 +182,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
}
private void removeSubView() {
log.debug("removeSubView called");
if (currentSubView != null) {
log.debug("remove currentSubView");
currentSubView.deactivate();
tradeStepPane.getChildren().remove(currentSubView);
currentSubView = null;

View File

@ -37,6 +37,9 @@ import java.util.Date;
import javafx.beans.InvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
@ -67,17 +70,18 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
EXCEPTION
}
private final BSFormatter formatter;
private final InvalidationListener sellerStateListener;
private final InvalidationListener buyerStateListener;
private final BtcAddressValidator btcAddressValidator;
private final ObjectProperty<ViewState> viewState = new SimpleObjectProperty<>(ViewState.UNDEFINED);
private final StringProperty txId = new SimpleStringProperty();
private final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
public final StringProperty txId = new SimpleStringProperty();
public final BooleanProperty withdrawalButtonDisable = new SimpleBooleanProperty(true);
final ObjectProperty<ViewState> viewState = new SimpleObjectProperty<>(ViewState.UNDEFINED);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, initialization
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public PendingTradesViewModel(PendingTradesDataModel dataModel, BSFormatter formatter,
@ -92,46 +96,67 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
@Override
public void doActivate() {
txId.bind(dataModel.txId);
txId.bind(dataModel.getTxId());
dataModel.sellerProcessState.addListener(sellerStateListener);
dataModel.buyerProcessState.addListener(buyerStateListener);
dataModel.getSellerProcessState().addListener(sellerStateListener);
dataModel.getBuyerProcessState().addListener(buyerStateListener);
updateSellerState();
updateBuyerState();
if (dataModel.getTrade() != null) {
updateSellerState();
updateBuyerState();
}
}
@Override
public void doDeactivate() {
txId.unbind();
dataModel.sellerProcessState.removeListener(sellerStateListener);
dataModel.buyerProcessState.removeListener(buyerStateListener);
dataModel.getSellerProcessState().removeListener(sellerStateListener);
dataModel.getBuyerProcessState().removeListener(buyerStateListener);
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI actions
///////////////////////////////////////////////////////////////////////////////////////////
void selectTrade(PendingTradesListItem item) {
dataModel.selectTrade(item);
void onSelectTrade(PendingTradesListItem item) {
dataModel.onSelectTrade(item);
}
boolean isBuyOffer() throws NoTradeFoundException {
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
ReadOnlyObjectProperty<ViewState> getViewState() {
return viewState;
}
public ReadOnlyStringProperty getTxId() {
return txId;
}
public ReadOnlyBooleanProperty getWithdrawalButtonDisable() {
return withdrawalButtonDisable;
}
boolean isBuyOffer() {
return dataModel.isBuyOffer();
}
ObjectProperty<Trade> currentTrade() {
return dataModel.currentTrade;
ReadOnlyObjectProperty<Trade> currentTrade() {
return dataModel.getTradeProperty();
}
public void fiatPaymentStarted() {
dataModel.fiatPaymentStarted();
dataModel.onFiatPaymentStarted();
}
public void fiatPaymentReceived() {
dataModel.fiatPaymentReceived();
dataModel.onFiatPaymentReceived();
}
public void withdraw(String withdrawToAddress) {
dataModel.withdraw(withdrawToAddress);
public void onWithdrawRequest(String withdrawToAddress) {
dataModel.onWithdrawRequest(withdrawToAddress);
}
public void withdrawAddressFocusOut(String text) {
@ -147,7 +172,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
public boolean isOfferer() {
return dataModel.isOfferer();
return dataModel.isOffererRole();
}
public WalletService getWalletService() {
@ -162,6 +187,18 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
return dataModel.getCurrencyCode();
}
public BtcAddressValidator getBtcAddressValidator() {
return btcAddressValidator;
}
Throwable getTradeException() {
return dataModel.getTradeException();
}
String getErrorMessage() {
return dataModel.getErrorMessage();
}
// columns
String formatTradeId(String value) {
return value;
@ -194,11 +231,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
public String getFiatAmount() {
try {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
} catch (NoTradeFoundException e) {
return "";
}
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
}
public String getHolderName() {
@ -218,19 +251,11 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
// summary
public String getTradeVolume() {
try {
return formatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount());
} catch (NoTradeFoundException e) {
return "";
}
return formatter.formatCoinWithCode(dataModel.getTrade().getTradeAmount());
}
public String getFiatVolume() {
try {
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
} catch (NoTradeFoundException e) {
return "";
}
return formatter.formatFiatWithCode(dataModel.getTrade().getTradeVolume());
}
public String getTotalFees() {
@ -240,32 +265,21 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
public String getSecurityDeposit() {
// securityDeposit is handled different for offerer and taker.
// Offerer have paid in the max amount, but taker might have taken less so also paid in less securityDeposit
try {
if (dataModel.isOfferer())
return formatter.formatCoinWithCode(dataModel.getTrade().getOffer().getSecurityDeposit());
else
return formatter.formatCoinWithCode(dataModel.getTrade().getSecurityDeposit());
if (dataModel.isOffererRole())
return formatter.formatCoinWithCode(dataModel.getTrade().getOffer().getSecurityDeposit());
else
return formatter.formatCoinWithCode(dataModel.getTrade().getSecurityDeposit());
} catch (NoTradeFoundException e) {
return "";
}
}
public BtcAddressValidator getBtcAddressValidator() {
return btcAddressValidator;
}
Throwable getTradeException() {
return dataModel.getTradeException();
}
String getErrorMessage() {
return dataModel.getErrorMessage();
}
///////////////////////////////////////////////////////////////////////////////////////////
// States
///////////////////////////////////////////////////////////////////////////////////////////
private void updateSellerState() {
if (dataModel.sellerProcessState.get() instanceof TakerTradeState.ProcessState) {
TakerTradeState.ProcessState processState = (TakerTradeState.ProcessState) dataModel.sellerProcessState.get();
if (dataModel.getSellerProcessState().get() instanceof TakerTradeState.ProcessState) {
TakerTradeState.ProcessState processState = (TakerTradeState.ProcessState) dataModel.getSellerProcessState().get();
log.debug("updateSellerState (TakerTradeState) " + processState);
if (processState != null) {
switch (processState) {
@ -310,8 +324,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
}
}
else if (dataModel.sellerProcessState.get() instanceof OffererTradeState.ProcessState) {
OffererTradeState.ProcessState processState = (OffererTradeState.ProcessState) dataModel.sellerProcessState.get();
else if (dataModel.getSellerProcessState().get() instanceof OffererTradeState.ProcessState) {
OffererTradeState.ProcessState processState = (OffererTradeState.ProcessState) dataModel.getSellerProcessState().get();
log.debug("updateSellerState (OffererTradeState) " + processState);
if (processState != null) {
switch (processState) {
@ -354,8 +368,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
private void updateBuyerState() {
if (dataModel.buyerProcessState.get() instanceof TakerTradeState.ProcessState) {
TakerTradeState.ProcessState processState = (TakerTradeState.ProcessState) dataModel.buyerProcessState.get();
if (dataModel.getBuyerProcessState().get() instanceof TakerTradeState.ProcessState) {
TakerTradeState.ProcessState processState = (TakerTradeState.ProcessState) dataModel.getBuyerProcessState().get();
log.debug("updateBuyerState (TakerTradeState)" + processState);
if (processState != null) {
switch (processState) {
@ -399,8 +413,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
}
}
else if (dataModel.buyerProcessState.get() instanceof OffererTradeState.ProcessState) {
OffererTradeState.ProcessState processState = (OffererTradeState.ProcessState) dataModel.buyerProcessState.get();
else if (dataModel.getBuyerProcessState().get() instanceof OffererTradeState.ProcessState) {
OffererTradeState.ProcessState processState = (OffererTradeState.ProcessState) dataModel.getBuyerProcessState().get();
log.debug("updateBuyerState (OffererTradeState) " + processState);
if (processState != null) {
switch (processState) {
@ -436,6 +450,4 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
}
}
}
}

View File

@ -30,11 +30,11 @@ import org.slf4j.LoggerFactory;
public abstract class TradeSubView extends HBox {
private static final Logger log = LoggerFactory.getLogger(TradeSubView.class);
protected final PendingTradesViewModel model;
protected final ChangeListener<PendingTradesViewModel.ViewState> offererStateChangeListener;
protected VBox leftVBox;
protected AnchorPane contentPane;
protected PendingTradesViewModel model;
protected TradeStepDetailsView tradeStepDetailsView;
protected ChangeListener<PendingTradesViewModel.ViewState> offererStateChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -51,14 +51,12 @@ public abstract class TradeSubView extends HBox {
}
public void activate() {
log.debug("activate");
model.viewState.addListener(offererStateChangeListener);
applyState(model.viewState.get());
model.getViewState().addListener(offererStateChangeListener);
applyState(model.getViewState().get());
}
public void deactivate() {
log.debug("deactivate");
model.viewState.removeListener(offererStateChangeListener);
model.getViewState().removeListener(offererStateChangeListener);
if (tradeStepDetailsView != null)
tradeStepDetailsView.deactivate();
@ -71,7 +69,7 @@ public abstract class TradeSubView extends HBox {
protected abstract void applyState(PendingTradesViewModel.ViewState state);
protected void buildViews() {
private void buildViews() {
addLeftBox();
addContentPane();
addWizards();
@ -84,7 +82,7 @@ public abstract class TradeSubView extends HBox {
abstract protected void addWizards();
protected void createAndAddTradeStepView(Class<? extends TradeStepDetailsView> viewClass) {
private void createAndAddTradeStepView(Class<? extends TradeStepDetailsView> viewClass) {
try {
tradeStepDetailsView = viewClass.getDeclaredConstructor(PendingTradesViewModel.class).newInstance(model);
} catch (Exception e) {

View File

@ -35,6 +35,8 @@ import static io.bitsquare.gui.util.ComponentBuilder.*;
public class CompletedView extends TradeStepDetailsView {
private static final Logger log = LoggerFactory.getLogger(WaitTxInBlockchainView.class);
private final ChangeListener<Boolean> focusedPropertyListener;
private Label btcTradeAmountLabel;
private TextField btcTradeAmountTextField;
private Label fiatTradeAmountLabel;
@ -44,13 +46,10 @@ public class CompletedView extends TradeStepDetailsView {
private Label securityDepositLabel;
private TextField securityDepositTextField;
private InfoDisplay summaryInfoDisplay;
private InputTextField withdrawAddressTextField;
private TextField withdrawAmountTextField;
private Button withdrawButton;
private ChangeListener<Boolean> focusedPropertyListener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
@ -63,23 +62,6 @@ public class CompletedView extends TradeStepDetailsView {
if (oldValue && !newValue)
model.withdrawAddressFocusOut(withdrawAddressTextField.getText());
};
/* statusTextField.setText("Congratulations! Trade has successfully completed.");
infoDisplay.setText("The trade is now completed and you can withdraw your Bitcoin to any external" +
"wallet. To protect your privacy you should take care that your trades are not merged " +
"in " +
"that external wallet. For more information about privacy see our help pages.");*/
/* btcTradeAmountLabel.setText("You have bought:");
fiatTradeAmountLabel.setText("You have paid:");
btcTradeAmountTextField.setText(model.getTradeVolume());
fiatTradeAmountTextField.setText(model.getFiatVolume());
feesTextField.setText(model.getTotalFees());
securityDepositTextField.setText(model.getSecurityDeposit());
summaryInfoDisplay.setText("Your security deposit has been refunded to you. " +
"You can review the details to that trade any time in the closed trades screen.");*/
// withdrawAmountTextField.setText(model.getAmountToWithdraw());
}
@Override
@ -87,7 +69,7 @@ public class CompletedView extends TradeStepDetailsView {
super.activate();
withdrawAddressTextField.focusedProperty().addListener(focusedPropertyListener);
withdrawAddressTextField.setValidator(model.getBtcAddressValidator());
withdrawButton.disableProperty().bind(model.withdrawalButtonDisable);
withdrawButton.disableProperty().bind(model.getWithdrawalButtonDisable());
// We need to handle both cases: Address not set and address already set (when returning from other view)
// We get address validation after focus out, so first make sure we loose focus and then set it again as hint for user to put address in
@ -114,9 +96,8 @@ public class CompletedView extends TradeStepDetailsView {
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////
private void onWithdraw(ActionEvent actionEvent) {
log.debug("onWithdraw");
model.withdraw(withdrawAddressTextField.getText());
private void onWithdrawRequest(ActionEvent actionEvent) {
model.onWithdrawRequest(withdrawAddressTextField.getText());
}
@ -148,24 +129,12 @@ public class CompletedView extends TradeStepDetailsView {
getAndAddTitledGroupBg(gridPane, gridRow, 2, "Withdraw your bitcoins", Layout.GROUP_DISTANCE);
withdrawAmountTextField = getAndAddLabelTextFieldPair(gridPane, gridRow++, "Amount to withdraw:", Layout.FIRST_ROW_AND_GROUP_DISTANCE).textField;
withdrawAddressTextField = getAndAddLabelInputTextFieldPair(gridPane, gridRow++, "Withdraw to address:").inputTextField;
withdrawButton = getAndAddButton(gridPane, gridRow++, "Withdraw to external wallet", this::onWithdraw);
withdrawButton = getAndAddButton(gridPane, gridRow++, "Withdraw to external wallet", this::onWithdrawRequest);
//TODO just temp for testing
withdrawAddressTextField.setText("mxmKZruv9x9JLcEj6rZx6Hnm4LLAcQHtcr");
}
/* fiatTradeAmountLabel.setText("You have received:");
btcTradeAmountTextField.setText(model.getTradeVolume());
fiatTradeAmountTextField.setText(model.getFiatVolume());
feesTextField.setText(model.getTotalFees());
securityDepositTextField.setText(model.getSecurityDeposit());
summaryInfoDisplay.setText("Your security deposit has been refunded to you. "+
"You can review the details to that trade any time in the closed trades screen.");
withdrawAmountTextField.setText(model.getAmountToWithdraw());*/
public void setBtcTradeAmountLabelText(String text) {
btcTradeAmountLabel.setText(text);
}
@ -198,14 +167,4 @@ public class CompletedView extends TradeStepDetailsView {
withdrawAmountTextField.setText(text);
}
/* completedView.setBtcTradeAmountLabelText("You have sold:");
completedView.setFiatTradeAmountLabelText("You have received:");
completedView.setBtcTradeAmountTextFieldText(model.getTradeVolume());
completedView.setFiatTradeAmountTextFieldText(model.getFiatVolume());
completedView.setFeesTextFieldText(model.getTotalFees());
completedView.setSecurityDepositTextFieldText(model.getSecurityDeposit());
completedView.setSummaryInfoDisplayText("Your security deposit has been refunded to you. "+
"You can review the details to that trade any time in the closed trades screen.");
completedView.setWithdrawAmountTextFieldText(model.getAmountToWithdraw());*/
}

View File

@ -35,10 +35,11 @@ import static io.bitsquare.gui.util.ComponentBuilder.*;
public class ConfirmFiatReceivedView extends TradeStepDetailsView {
private static final Logger log = LoggerFactory.getLogger(ConfirmFiatReceivedView.class);
private final ChangeListener<String> txIdChangeListener;
private TxIdTextField txIdTextField;
private Label infoLabel;
private InfoDisplay infoDisplay;
private final ChangeListener<String> txIdChangeListener;
private Button confirmFiatReceivedButton;
private Label statusLabel;
private ProgressIndicator statusProgressIndicator;
@ -59,17 +60,16 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
public void activate() {
super.activate();
model.txId.addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.txId.get());
model.getTxId().addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.getTxId().get());
}
@Override
public void deactivate() {
super.deactivate();
model.txId.removeListener(txIdChangeListener);
model.getTxId().removeListener(txIdChangeListener);
txIdTextField.cleanup();
statusLabel.setText("Publishing transaction...");
if (root != null)
root.setMouseTransparent(false);
}
@ -82,11 +82,12 @@ public class ConfirmFiatReceivedView extends TradeStepDetailsView {
private void onPaymentReceived(ActionEvent actionEvent) {
log.debug("onPaymentReceived");
model.fiatPaymentReceived();
confirmFiatReceivedButton.setDisable(true);
statusLabel.setText("Publishing transaction...");
statusProgressIndicator.setVisible(true);
statusProgressIndicator.setProgress(-1);
root = statusProgressIndicator.getScene().getRoot();
// We deactivate mouse interaction to avoid that user leaves screen
root.setMouseTransparent(true);
}

View File

@ -86,15 +86,15 @@ public class StartFiatView extends TradeStepDetailsView {
log.debug("activate ##");
super.activate();
model.txId.addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.txId.get());
model.getTxId().addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.getTxId().get());
}
@Override
public void deactivate() {
super.deactivate();
model.txId.removeListener(txIdChangeListener);
model.getTxId().removeListener(txIdChangeListener);
txIdTextField.cleanup();
if (root != null)
root.setMouseTransparent(false);
@ -112,6 +112,7 @@ public class StartFiatView extends TradeStepDetailsView {
statusProgressIndicator.setProgress(-1);
statusLabel.setText("Sending message to trading partner...");
root = statusProgressIndicator.getScene().getRoot();
// We deactivate mouse interaction to avoid that user leaves screen
root.setMouseTransparent(true);
}

View File

@ -56,11 +56,9 @@ public abstract class TradeStepDetailsView extends AnchorPane {
// That is called at every state change!
public void activate() {
log.debug("activate");
}
public void deactivate() {
log.debug("deactivate");
}

View File

@ -33,10 +33,10 @@ import static io.bitsquare.gui.util.ComponentBuilder.*;
public class WaitFiatReceivedView extends TradeStepDetailsView {
private static final Logger log = LoggerFactory.getLogger(WaitFiatReceivedView.class);
private final ChangeListener<String> txIdChangeListener;
private TxIdTextField txIdTextField;
private Label infoLabel;
private InfoDisplay infoDisplay;
private final ChangeListener<String> txIdChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -53,15 +53,15 @@ public class WaitFiatReceivedView extends TradeStepDetailsView {
public void activate() {
super.activate();
model.txId.addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.txId.get());
model.getTxId().addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.getTxId().get());
}
@Override
public void deactivate() {
super.deactivate();
model.txId.removeListener(txIdChangeListener);
model.getTxId().removeListener(txIdChangeListener);
txIdTextField.cleanup();
}

View File

@ -33,10 +33,10 @@ import static io.bitsquare.gui.util.ComponentBuilder.*;
public class WaitTxInBlockchainView extends TradeStepDetailsView {
private static final Logger log = LoggerFactory.getLogger(WaitTxInBlockchainView.class);
private final ChangeListener<String> txIdChangeListener;
private TxIdTextField txIdTextField;
private Label infoLabel;
private InfoDisplay infoDisplay;
private final ChangeListener<String> txIdChangeListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -53,15 +53,15 @@ public class WaitTxInBlockchainView extends TradeStepDetailsView {
public void activate() {
super.activate();
model.txId.addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.txId.get());
model.getTxId().addListener(txIdChangeListener);
txIdTextField.setup(model.getWalletService(), model.getTxId().get());
}
@Override
public void deactivate() {
super.deactivate();
model.txId.removeListener(txIdChangeListener);
model.getTxId().removeListener(txIdChangeListener);
txIdTextField.cleanup();
}

View File

@ -49,7 +49,7 @@ import static com.google.common.base.Preconditions.checkArgument;
public class OfferBook {
private static final Logger log = LoggerFactory.getLogger(OfferBook.class);
private static final int POLLING_INTERVAL = 1000;
private static final int POLLING_INTERVAL = 5000; // in ms
private final OfferBookService offerBookService;
private final User user;

View File

@ -181,8 +181,10 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
final Map<Number640, Data> dataMap = futureGet.dataMap();
if (future.isSuccess()) {
final Map<Number640, Data> dataMap = futureGet.dataMap();
log.trace("Get offers from DHT was successful. Received data: [key: " + locationKey
+ ", values: " + futureGet.dataMap() + "]");
final List<Offer> offers = new ArrayList<>();
if (dataMap != null) {
for (Data offerData : dataMap.values()) {
@ -199,12 +201,8 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
executor.execute(() -> offerRepositoryListeners.stream().forEach(listener ->
listener.onOffersReceived(offers)));
}
log.trace("Get offers from DHT was successful. Received data: [key: " + locationKey
+ ", values: " + futureGet.dataMap() + "]");
}
else {
final Map<Number640, Data> dataMap = futureGet.dataMap();
if (dataMap == null || dataMap.size() == 0) {
log.trace("Get offers from DHT delivered empty dataMap.");
executor.execute(() -> offerRepositoryListeners.stream().forEach(listener ->
@ -282,14 +280,18 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
invalidationTimestamp.set(timeStamp);
});
}
else if (data == null) {
// OK for an empty list
// log.trace("Get invalidationTimestamp from DHT returns null. That is ok for an empty list.");
}
else if (data != null) {
log.error("Get invalidationTimestamp from DHT failed. Data = " + data);
}
}
/*else if (futureGet.data() == null) {
else if (futureGet.data() == null) {
// OK as nothing is set at the moment
log.trace("Get invalidationTimestamp from DHT returns null. That is ok for the startup.");
}*/
// log.trace("Get invalidationTimestamp from DHT returns null. That is ok for the startup.");
}
else {
log.error("Get invalidationTimestamp from DHT failed with reason:" + futureGet.failedReason());
}

View File

@ -121,7 +121,7 @@ public class BootstrappedPeerBuilder {
public SettableFuture<PeerDHT> start() {
try {
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(250);
DefaultEventExecutorGroup eventExecutorGroup = new DefaultEventExecutorGroup(20);
ChannelClientConfiguration clientConf = PeerBuilder.createDefaultChannelClientConfiguration();
clientConf.pipelineFilter(new PeerBuilder.EventExecutorGroupFilter(eventExecutorGroup));

View File

@ -20,8 +20,7 @@ package io.bitsquare.trade;
import io.bitsquare.offer.Offer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.BuyerAsOffererProtocol;
import io.bitsquare.trade.states.OffererTradeState;
import io.bitsquare.trade.states.TradeState;
import io.bitsquare.trade.protocol.trade.BuyerProtocol;
import org.bitcoinj.core.Coin;
@ -32,7 +31,7 @@ import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BuyerAsOffererTrade extends Trade implements OffererTrade, BuyerTrade, Serializable {
public class BuyerAsOffererTrade extends OffererTrade implements BuyerTrade, Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
@ -61,13 +60,6 @@ public class BuyerAsOffererTrade extends Trade implements OffererTrade, BuyerTra
tradeProtocol = new BuyerAsOffererProtocol(this);
}
@Override
protected void initStates() {
processState = OffererTradeState.ProcessState.UNDEFINED;
lifeCycleState = OffererTradeState.LifeCycleState.OFFER_OPEN;
initStateProperties();
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
@ -75,8 +67,8 @@ public class BuyerAsOffererTrade extends Trade implements OffererTrade, BuyerTra
@Override
public void onFiatPaymentStarted() {
assert tradeProtocol instanceof BuyerAsOffererProtocol;
((BuyerAsOffererProtocol) tradeProtocol).onFiatPaymentStarted();
assert tradeProtocol instanceof BuyerProtocol;
((BuyerProtocol) tradeProtocol).onFiatPaymentStarted();
}
@Override
@ -84,52 +76,4 @@ public class BuyerAsOffererTrade extends Trade implements OffererTrade, BuyerTra
return getSecurityDeposit().add(getTradeAmount());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((OffererTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(OffererTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((OffererTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(OffererTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((OffererTradeState.ProcessState) processState).ordinal() < OffererTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(OffererTradeState.ProcessState.DEPOSIT_CONFIRMED);
}
}

View File

@ -21,18 +21,18 @@ import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.BuyerAsTakerProtocol;
import io.bitsquare.trade.states.TakerTradeState;
import io.bitsquare.trade.states.TradeState;
import io.bitsquare.trade.protocol.trade.BuyerProtocol;
import org.bitcoinj.core.Coin;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BuyerAsTakerTrade extends Trade implements TakerTrade, BuyerTrade, Serializable {
public class BuyerAsTakerTrade extends TakerTrade implements BuyerTrade, Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
@ -48,7 +48,7 @@ public class BuyerAsTakerTrade extends Trade implements TakerTrade, BuyerTrade,
log.trace("Created by constructor");
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
log.trace("Created from serialized form.");
@ -57,14 +57,7 @@ public class BuyerAsTakerTrade extends Trade implements TakerTrade, BuyerTrade,
}
@Override
protected void initStates() {
processState = TakerTradeState.ProcessState.UNDEFINED;
lifeCycleState = TakerTradeState.LifeCycleState.PENDING;
initStateProperties();
}
@Override
public void createProtocol() {
protected void createProtocol() {
tradeProtocol = new BuyerAsTakerProtocol(this);
}
@ -73,68 +66,14 @@ public class BuyerAsTakerTrade extends Trade implements TakerTrade, BuyerTrade,
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void takeAvailableOffer() {
assert tradeProtocol instanceof BuyerAsTakerProtocol;
((BuyerAsTakerProtocol) tradeProtocol).takeAvailableOffer();
}
@Override
public void onFiatPaymentStarted() {
assert tradeProtocol instanceof BuyerAsTakerProtocol;
((BuyerAsTakerProtocol) tradeProtocol).onFiatPaymentStarted();
assert tradeProtocol instanceof BuyerProtocol;
((BuyerProtocol) tradeProtocol).onFiatPaymentStarted();
}
@Override
public Coin getPayoutAmount() {
return getSecurityDeposit().add(getTradeAmount());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((TakerTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(TakerTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((TakerTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(TakerTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((TakerTradeState.ProcessState) processState).ordinal() < TakerTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(TakerTradeState.ProcessState.DEPOSIT_CONFIRMED);
}
}

View File

@ -17,5 +17,80 @@
package io.bitsquare.trade;
public interface OffererTrade {
import io.bitsquare.offer.Offer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.states.OffererTradeState;
import io.bitsquare.trade.states.TradeState;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class OffererTrade extends Trade implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(BuyerAsOffererTrade.class);
public OffererTrade(Offer offer, Storage<? extends TradeList> storage) {
super(offer, storage);
log.trace("Created by constructor");
}
@Override
protected void initStates() {
processState = OffererTradeState.ProcessState.UNDEFINED;
lifeCycleState = OffererTradeState.LifeCycleState.OFFER_OPEN;
initStateProperties();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((OffererTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(OffererTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((OffererTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(OffererTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((OffererTradeState.ProcessState) processState).ordinal() < OffererTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(OffererTradeState.ProcessState.DEPOSIT_CONFIRMED);
}
}

View File

@ -20,8 +20,7 @@ package io.bitsquare.trade;
import io.bitsquare.offer.Offer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.SellerAsOffererProtocol;
import io.bitsquare.trade.states.OffererTradeState;
import io.bitsquare.trade.states.TradeState;
import io.bitsquare.trade.protocol.trade.SellerProtocol;
import java.io.IOException;
import java.io.ObjectInputStream;
@ -30,7 +29,7 @@ import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SellerAsOffererTrade extends Trade implements OffererTrade, SellerTrade, Serializable {
public class SellerAsOffererTrade extends OffererTrade implements SellerTrade, Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
@ -59,13 +58,6 @@ public class SellerAsOffererTrade extends Trade implements OffererTrade, SellerT
tradeProtocol = new SellerAsOffererProtocol(this);
}
@Override
protected void initStates() {
processState = OffererTradeState.ProcessState.UNDEFINED;
lifeCycleState = OffererTradeState.LifeCycleState.OFFER_OPEN;
initStateProperties();
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
@ -73,57 +65,7 @@ public class SellerAsOffererTrade extends Trade implements OffererTrade, SellerT
@Override
public void onFiatPaymentReceived() {
assert tradeProtocol instanceof SellerAsOffererProtocol;
((SellerAsOffererProtocol) tradeProtocol).onFiatPaymentReceived();
assert tradeProtocol instanceof SellerProtocol;
((SellerProtocol) tradeProtocol).onFiatPaymentReceived();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((OffererTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(OffererTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((OffererTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(OffererTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((OffererTradeState.ProcessState) processState).ordinal() < OffererTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(OffererTradeState.ProcessState.DEPOSIT_CONFIRMED);
}
}
}

View File

@ -21,8 +21,8 @@ import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.SellerAsTakerProtocol;
import io.bitsquare.trade.protocol.trade.SellerProtocol;
import io.bitsquare.trade.states.TakerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.bitcoinj.core.Coin;
@ -32,7 +32,7 @@ import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SellerAsTakerTrade extends Trade implements TakerTrade, SellerTrade, Serializable {
public class SellerAsTakerTrade extends TakerTrade implements SellerTrade, Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
@ -57,28 +57,7 @@ public class SellerAsTakerTrade extends Trade implements TakerTrade, SellerTrade
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((TakerTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
protected void initStates() {
processState = TakerTradeState.ProcessState.UNDEFINED;
lifeCycleState = TakerTradeState.LifeCycleState.PENDING;
initStateProperties();
}
@Override
public void createProtocol() {
protected void createProtocol() {
tradeProtocol = new SellerAsTakerProtocol(this);
}
@ -87,50 +66,9 @@ public class SellerAsTakerTrade extends Trade implements TakerTrade, SellerTrade
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void takeAvailableOffer() {
assert tradeProtocol instanceof SellerAsTakerProtocol;
((SellerAsTakerProtocol) tradeProtocol).takeAvailableOffer();
}
@Override
public void onFiatPaymentReceived() {
assert tradeProtocol instanceof SellerAsTakerProtocol;
((SellerAsTakerProtocol) tradeProtocol).onFiatPaymentReceived();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((TakerTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(TakerTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(TakerTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((TakerTradeState.ProcessState) processState).ordinal() < TakerTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(TakerTradeState.ProcessState.DEPOSIT_CONFIRMED);
assert tradeProtocol instanceof SellerProtocol;
((SellerProtocol) tradeProtocol).onFiatPaymentReceived();
}
}

View File

@ -17,6 +17,89 @@
package io.bitsquare.trade;
public interface TakerTrade {
void takeAvailableOffer();
import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.Peer;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.protocol.trade.TakerProtocol;
import io.bitsquare.trade.states.TakerTradeState;
import io.bitsquare.trade.states.TradeState;
import org.bitcoinj.core.Coin;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class TakerTrade extends Trade implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(BuyerAsTakerTrade.class);
public TakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer, Storage<? extends TradeList> storage) {
super(offer, tradeAmount, tradingPeer, storage);
log.trace("Created by constructor");
}
@Override
protected void initStates() {
processState = TakerTradeState.ProcessState.UNDEFINED;
lifeCycleState = TakerTradeState.LifeCycleState.PENDING;
initStateProperties();
}
public void takeAvailableOffer() {
assert tradeProtocol instanceof TakerProtocol;
((TakerProtocol) tradeProtocol).takeAvailableOffer();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void setProcessState(TradeState.ProcessState processState) {
super.setProcessState(processState);
switch ((TakerTradeState.ProcessState) processState) {
case EXCEPTION:
disposeProtocol();
setLifeCycleState(TakerTradeState.LifeCycleState.FAILED);
break;
}
}
@Override
public void setLifeCycleState(TradeState.LifeCycleState lifeCycleState) {
super.setLifeCycleState(lifeCycleState);
switch ((TakerTradeState.LifeCycleState) lifeCycleState) {
case FAILED:
disposeProtocol();
break;
case COMPLETED:
disposeProtocol();
break;
}
}
@Override
public void setThrowable(Throwable throwable) {
super.setThrowable(throwable);
setProcessState(TakerTradeState.ProcessState.EXCEPTION);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Protected
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void handleConfidenceResult() {
if (((TakerTradeState.ProcessState) processState).ordinal() < TakerTradeState.ProcessState.DEPOSIT_CONFIRMED.ordinal())
setProcessState(TakerTradeState.ProcessState.DEPOSIT_CONFIRMED);
}
}

View File

@ -91,6 +91,7 @@ abstract public class Trade implements Model, Serializable {
// Immutable
private final Offer offer;
private final ProcessModel processModel;
private final Date creationDate;
// Mutable
private Date takeOfferDate;
@ -124,6 +125,9 @@ abstract public class Trade implements Model, Serializable {
initStates();
initStateProperties();
// That will only be used in case of a canceled open offer trade
creationDate = new Date();
}
// taker
@ -306,8 +310,8 @@ abstract public class Trade implements Model, Serializable {
// Getter/Setter for Mutable objects
///////////////////////////////////////////////////////////////////////////////////////////
public Date getTakeOfferDate() {
return takeOfferDate;
public Date getDate() {
return takeOfferDate != null ? takeOfferDate : creationDate;
}
public void setTakeOfferDate(Date takeOfferDate) {

View File

@ -406,7 +406,7 @@ public class TradeManager {
// Trade
///////////////////////////////////////////////////////////////////////////////////////////
public void requestWithdraw(String toAddress, Trade trade, ResultHandler resultHandler, FaultHandler faultHandler) {
public void onWithdrawRequest(String toAddress, Trade trade, ResultHandler resultHandler, FaultHandler faultHandler) {
AddressEntry addressEntry = walletService.getAddressEntry(trade.getId());
String fromAddress = addressEntry.getAddressString();

View File

@ -17,13 +17,11 @@
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer;
import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.BuyerAsOffererTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
@ -50,7 +48,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.*;
public class BuyerAsOffererProtocol extends TradeProtocol {
public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtocol, OffererProtocol {
private static final Logger log = LoggerFactory.getLogger(BuyerAsOffererProtocol.class);
private final BuyerAsOffererTrade buyerAsOffererTrade;
@ -128,7 +126,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol {
buyerAsOffererTrade.setLifeCycleState(OffererTradeState.LifeCycleState.OFFER_RESERVED);
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleRequestDepositTxInputsMessage completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
@ -144,7 +142,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol {
stopTimeout();
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
@ -163,8 +161,9 @@ public class BuyerAsOffererProtocol extends TradeProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// User clicked the "bank transfer started" button
@Override
public void onFiatPaymentStarted() {
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> log.debug("taskRunner at handleBankTransferStartedUIEvent completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
@ -183,7 +182,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol {
private void handle(PayoutTxPublishedMessage tradeMessage) {
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade,
() -> {
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
// we are done!

View File

@ -17,12 +17,10 @@
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.BuyerAsTakerTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
@ -46,7 +44,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.nonEmptyStringOf;
public class BuyerAsTakerProtocol extends TradeProtocol {
public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol, TakerProtocol {
private static final Logger log = LoggerFactory.getLogger(BuyerAsTakerProtocol.class);
private final BuyerAsTakerTrade buyerAsTakerTrade;
@ -82,8 +80,9 @@ public class BuyerAsTakerProtocol extends TradeProtocol {
}
}
@Override
public void takeAvailableOffer() {
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at takeAvailableOffer completed"),
this::handleTaskRunnerFault);
@ -106,7 +105,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol {
stopTimeout();
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
@ -125,8 +124,9 @@ public class BuyerAsTakerProtocol extends TradeProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// User clicked the "bank transfer started" button
@Override
public void onFiatPaymentStarted() {
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> log.debug("taskRunner at onFiatPaymentStarted completed"),
this::handleTaskRunnerFault);
taskRunner.addTasks(
@ -145,7 +145,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol {
private void handle(PayoutTxPublishedMessage tradeMessage) {
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(buyerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade,
() -> {
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
// we are done!

View File

@ -15,16 +15,8 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio.pending;
package io.bitsquare.trade.protocol.trade;
// That is used if trade is null and it is a valid state
public class NoTradeFoundException extends Throwable {
public NoTradeFoundException(String msg) {
super(msg);
}
public NoTradeFoundException() {
super("Trade is null");
}
public interface BuyerProtocol {
void onFiatPaymentStarted();
}

View File

@ -15,16 +15,7 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.portfolio.pending;
package io.bitsquare.trade.protocol.trade;
// That is used if trade is null but must not be null in that state
public class MissingTradeException extends RuntimeException {
public MissingTradeException(String msg) {
super(msg);
}
public MissingTradeException() {
super("Trade is null.That must not happen.");
}
public interface OffererProtocol {
}

View File

@ -17,13 +17,11 @@
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer;
import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.SellerAsOffererTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
@ -48,7 +46,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.*;
public class SellerAsOffererProtocol extends TradeProtocol {
public class SellerAsOffererProtocol extends TradeProtocol implements SellerProtocol, OffererProtocol {
private static final Logger log = LoggerFactory.getLogger(SellerAsOffererProtocol.class);
private final SellerAsOffererTrade sellerAsOffererTrade;
@ -136,7 +134,7 @@ public class SellerAsOffererProtocol extends TradeProtocol {
sellerAsOffererTrade.setTradingPeer(sender);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
this::handleTaskRunnerFault);
@ -155,7 +153,7 @@ public class SellerAsOffererProtocol extends TradeProtocol {
stopTimeout();
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
this::handleTaskRunnerFault);
@ -174,7 +172,7 @@ public class SellerAsOffererProtocol extends TradeProtocol {
private void handle(FiatTransferStartedMessage tradeMessage) {
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
this::handleTaskRunnerFault);
@ -188,10 +186,11 @@ public class SellerAsOffererProtocol extends TradeProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// User clicked the "bank transfer received" button, so we release the funds for pay out
@Override
public void onFiatPaymentReceived() {
sellerAsOffererTrade.setProcessState(OffererTradeState.ProcessState.FIAT_PAYMENT_RECEIVED);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsOffererTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade,
() -> {
log.debug("taskRunner at handleFiatReceivedUIEvent completed");

View File

@ -17,12 +17,10 @@
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer;
import io.bitsquare.trade.SellerAsTakerTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
@ -48,7 +46,7 @@ import org.slf4j.LoggerFactory;
import static io.bitsquare.util.Validator.nonEmptyStringOf;
public class SellerAsTakerProtocol extends TradeProtocol {
public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtocol, TakerProtocol {
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
private final SellerAsTakerTrade sellerAsTakerTrade;
@ -87,8 +85,9 @@ public class SellerAsTakerProtocol extends TradeProtocol {
}
}
@Override
public void takeAvailableOffer() {
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at takeAvailableOffer completed"),
this::handleTaskRunnerFault);
@ -111,7 +110,7 @@ public class SellerAsTakerProtocol extends TradeProtocol {
stopTimeout();
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
this::handleTaskRunnerFault);
@ -130,7 +129,7 @@ public class SellerAsTakerProtocol extends TradeProtocol {
stopTimeout();
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
this::handleTaskRunnerFault);
@ -149,7 +148,7 @@ public class SellerAsTakerProtocol extends TradeProtocol {
private void handle(FiatTransferStartedMessage tradeMessage) {
processModel.setTradeMessage(tradeMessage);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
this::handleTaskRunnerFault);
@ -163,10 +162,11 @@ public class SellerAsTakerProtocol extends TradeProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
// User clicked the "bank transfer received" button, so we release the funds for pay out
@Override
public void onFiatPaymentReceived() {
sellerAsTakerTrade.setProcessState(TakerTradeState.ProcessState.FIAT_PAYMENT_RECEIVED);
TaskRunner<Trade> taskRunner = new TaskRunner<>(sellerAsTakerTrade,
TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade,
() -> {
log.debug("taskRunner at handleFiatReceivedUIEvent completed");

View File

@ -0,0 +1,22 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.trade.protocol.trade;
public interface SellerProtocol {
void onFiatPaymentReceived();
}

View File

@ -0,0 +1,22 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.trade.protocol.trade;
public interface TakerProtocol {
void takeAvailableOffer();
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.common.taskrunner.Model;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradeTaskRunner extends TaskRunner<Trade> {
private static final Logger log = LoggerFactory.getLogger(TradeTaskRunner.class);
public TradeTaskRunner(Trade sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
super(sharedModel, (Class<? extends Model>) sharedModel.getClass().getSuperclass().getSuperclass(), resultHandler, errorMessageHandler);
}
}

View File

@ -55,7 +55,7 @@ public class SendPayoutTxPublishedMessage extends TradeTask {
trade.setProcessState(TakerTradeState.ProcessState.PAYOUT_PUBLISHED_MSG_SENT);
else if (trade instanceof OffererTrade)
trade.setProcessState(OffererTradeState.ProcessState.PAYOUT_PUBLISHED_MSG_SENT);
complete();
}

View File

@ -32,11 +32,10 @@
<logger name="io.bitsquare.btc.AddressBasedCoinSelector" level="OFF"/>
<logger name="io.bitsquare.gui.util.Profiler" level="ERROR"/>
<!-- <logger name="io.bitsquare.persistence.Persistence" level="ERROR"/>-->
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
<logger name="org.bitcoinj" level="WARN"/>
<logger name="net.tomp2p" level="INFO"/>
<logger name="net.tomp2p" level="WARN"/>
<logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/>
<logger name="org.bitcoinj.core.Peer" level="WARN"/>