mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 07:07:43 +01:00
Merge pull request #5423 from jmacxx/dupOffer_2
Functionality to duplicate an offer
This commit is contained in:
commit
c17b46fc2d
27 changed files with 471 additions and 69 deletions
|
@ -583,6 +583,9 @@ portfolio.tab.pendingTrades=Open trades
|
|||
portfolio.tab.history=History
|
||||
portfolio.tab.failed=Failed
|
||||
portfolio.tab.editOpenOffer=Edit offer
|
||||
portfolio.tab.duplicateOffer=Duplicate offer
|
||||
portfolio.context.offerLikeThis=Create new offer like this...
|
||||
portfolio.context.notYourOffer=You can only duplicate offers where you were the maker.
|
||||
|
||||
portfolio.closedTrades.deviation.help=Percentage price deviation from market
|
||||
|
||||
|
@ -2945,9 +2948,9 @@ popup.shutDownInProgress.headline=Shut down in progress
|
|||
popup.shutDownInProgress.msg=Shutting down application can take a few seconds.\nPlease don't interrupt this process.
|
||||
|
||||
popup.attention.forTradeWithId=Attention required for trade with ID {0}
|
||||
popup.attention.reasonForPaymentRuleChange=Version 1.5.5 introduces a critical trade rule change regarding \
|
||||
the \"reason for payment\" field in bank transfers. Please leave this field empty -- \
|
||||
DO NOT use the trade ID as \"reason for payment\" anymore.
|
||||
popup.attention.newFeatureDuplicateOffer=Version 1.6.3 introduces a new feature allowing easy re-entry of offers \
|
||||
by right-clicking on an existing offer or trade and choosing `Create new offer like this`. This is useful for \
|
||||
traders who frequently make the same offer.
|
||||
|
||||
popup.info.multiplePaymentAccounts.headline=Multiple payment accounts available
|
||||
popup.info.multiplePaymentAccounts.msg=You have multiple payment accounts available for this offer. Please make sure you've picked the right one.
|
||||
|
|
|
@ -48,10 +48,7 @@ public final class Navigation implements PersistedDataHost {
|
|||
private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, MarketView.class);
|
||||
|
||||
public interface Listener {
|
||||
void onNavigationRequested(ViewPath path);
|
||||
|
||||
default void onNavigationRequested(ViewPath path, @Nullable Object data) {
|
||||
}
|
||||
void onNavigationRequested(ViewPath path, @Nullable Object data);
|
||||
}
|
||||
|
||||
// New listeners can be added during iteration so we use CopyOnWriteArrayList to
|
||||
|
@ -137,7 +134,6 @@ public final class Navigation implements PersistedDataHost {
|
|||
|
||||
currentPath = newPath;
|
||||
previousPath = currentPath;
|
||||
listeners.forEach((e) -> e.onNavigationRequested(currentPath));
|
||||
listeners.forEach((e) -> e.onNavigationRequested(currentPath, data));
|
||||
requestPersistence();
|
||||
}
|
||||
|
|
|
@ -43,4 +43,8 @@ public class CachingViewLoader implements ViewLoader {
|
|||
cache.put(viewClass, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
public void removeFromCache(Class<? extends View> viewClass) {
|
||||
cache.remove(viewClass);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -367,7 +367,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
|
|||
setupBadge(supportButtonWithBadge, model.getNumOpenSupportTickets(), model.getShowOpenSupportTicketsNotification());
|
||||
setupBadge(settingsButtonWithBadge, new SimpleStringProperty(Res.get("shared.new")), model.getShowSettingsUpdatesNotification());
|
||||
|
||||
navigation.addListener(viewPath -> {
|
||||
navigation.addListener((viewPath, data) -> {
|
||||
if (viewPath.size() != 2 || viewPath.indexOf(MainView.class) != 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -278,22 +278,14 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
|
|||
|
||||
// We only show the popup if the user has already set up any fiat account. For new users it is not a rule
|
||||
// change and for altcoins its not relevant.
|
||||
String key = "reasonForPaymentChange";
|
||||
boolean hasFiatAccount = user.getPaymentAccounts() != null &&
|
||||
user.getPaymentAccounts().stream()
|
||||
.filter(e -> !(e.getPaymentAccountPayload() instanceof AssetsAccountPayload))
|
||||
.findAny()
|
||||
.isPresent();
|
||||
if (hasFiatAccount && DontShowAgainLookup.showAgain(key)) {
|
||||
String key = "newFeatureDuplicateOffer";
|
||||
if (DontShowAgainLookup.showAgain(key)) {
|
||||
UserThread.runAfter(() -> {
|
||||
new Popup().attention(Res.get("popup.attention.reasonForPaymentRuleChange")).
|
||||
new Popup().attention(Res.get("popup.attention.newFeatureDuplicateOffer")).
|
||||
dontShowAgainId(key)
|
||||
.closeButtonText(Res.get("shared.iUnderstand"))
|
||||
.show();
|
||||
}, 1);
|
||||
} else {
|
||||
// If user add a fiat account later we don't show the popup as we assume it is a new user.
|
||||
DontShowAgainLookup.dontShowAgain(key, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
walletInfoTab.setText(Res.get("account.menu.walletInfo").toUpperCase());
|
||||
backupTab.setText(Res.get("account.menu.backup").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(AccountView.class) == 1) {
|
||||
if (arbitratorRegistrationTab == null && viewPath.get(2).equals(ArbitratorRegistrationView.class)) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, FiatAccountsView.class);
|
||||
|
|
|
@ -111,7 +111,7 @@ public class DaoView extends ActivatableView<TabPane, Void> {
|
|||
root.getTabs().addAll(factsAndFiguresTab, bsqWalletTab, proposalsTab, bondingTab, burnBsqTab, monitorTab);
|
||||
}
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(DaoView.class) == 1) {
|
||||
if (proposalsTab == null && viewPath.get(2).equals(EconomyView.class))
|
||||
navigation.navigateTo(MainView.class, DaoView.class, EconomyView.class);
|
||||
|
|
|
@ -73,19 +73,12 @@ public class BondingView extends ActivatableView<AnchorPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
listener = new Navigation.Listener() {
|
||||
@Override
|
||||
public void onNavigationRequested(ViewPath path) {
|
||||
}
|
||||
listener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(bisq.desktop.main.dao.bonding.BondingView.class) != 2)
|
||||
return;
|
||||
|
||||
@Override
|
||||
public void onNavigationRequested(ViewPath viewPath, @Nullable Object data) {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(bisq.desktop.main.dao.bonding.BondingView.class) != 2)
|
||||
return;
|
||||
|
||||
selectedViewClass = viewPath.tip();
|
||||
loadView(selectedViewClass, data);
|
||||
}
|
||||
selectedViewClass = viewPath.tip();
|
||||
loadView(selectedViewClass, data);
|
||||
};
|
||||
|
||||
toggleGroup = new ToggleGroup();
|
||||
|
|
|
@ -68,7 +68,7 @@ public class BurnBsqView extends ActivatableView<AnchorPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
listener = viewPath -> {
|
||||
listener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(BurnBsqView.class) != 2)
|
||||
return;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class EconomyView extends ActivatableView<AnchorPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
listener = viewPath -> {
|
||||
listener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(EconomyView.class) != 2)
|
||||
return;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ public class GovernanceView extends ActivatableView<AnchorPane, Void> implements
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(GovernanceView.class) != 2)
|
||||
return;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public class MonitorView extends ActivatableView<AnchorPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(MonitorView.class) != 2)
|
||||
return;
|
||||
|
||||
|
|
|
@ -74,24 +74,12 @@ public class BsqWalletView extends ActivatableView<AnchorPane, Void> {
|
|||
|
||||
@Override
|
||||
public void initialize() {
|
||||
listener = new Navigation.Listener() {
|
||||
@Override
|
||||
public void onNavigationRequested(ViewPath viewPath) {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(BsqWalletView.class) != 2)
|
||||
return;
|
||||
listener = (viewPath, data) -> {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(BsqWalletView.class) != 2)
|
||||
return;
|
||||
|
||||
selectedViewClass = viewPath.tip();
|
||||
loadView(selectedViewClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNavigationRequested(ViewPath viewPath, @Nullable Object data) {
|
||||
if (viewPath.size() != 4 || viewPath.indexOf(BsqWalletView.class) != 2)
|
||||
return;
|
||||
|
||||
selectedViewClass = viewPath.tip();
|
||||
loadView(selectedViewClass, data);
|
||||
}
|
||||
selectedViewClass = viewPath.tip();
|
||||
loadView(selectedViewClass, data);
|
||||
};
|
||||
|
||||
toggleGroup = new ToggleGroup();
|
||||
|
|
|
@ -68,7 +68,7 @@ public class FundsView extends ActivatableView<TabPane, Void> {
|
|||
lockedTab.setText(Res.get("funds.tab.locked").toUpperCase());
|
||||
transactionsTab.setText(Res.get("funds.tab.transactions").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(FundsView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
|
|
@ -101,7 +101,7 @@ public class MarketView extends ActivatableView<TabPane, Void> {
|
|||
spreadTabPaymentMethod.setText(Res.get("market.tabs.spreadPayment").toUpperCase());
|
||||
tradesTab.setText(Res.get("market.tabs.trades").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(MarketView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
|
|
@ -100,7 +100,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
private final BtcValidator btcValidator;
|
||||
private final BsqValidator bsqValidator;
|
||||
protected final SecurityDepositValidator securityDepositValidator;
|
||||
private final PriceFeedService priceFeedService;
|
||||
protected final PriceFeedService priceFeedService;
|
||||
private final AccountAgeWitnessService accountAgeWitnessService;
|
||||
private final Navigation navigation;
|
||||
private final Preferences preferences;
|
||||
|
@ -179,7 +179,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
|||
|
||||
private ChangeListener<Boolean> isWalletFundedListener;
|
||||
private ChangeListener<String> errorMessageListener;
|
||||
private Offer offer;
|
||||
protected Offer offer;
|
||||
private Timer timeoutTimer;
|
||||
private boolean inputIsMarketBasedPrice;
|
||||
private ChangeListener<Boolean> useMarketBasedPriceListener;
|
||||
|
|
|
@ -94,7 +94,7 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(this.getClass()) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
|
|
@ -22,15 +22,16 @@ import bisq.desktop.common.view.ActivatableView;
|
|||
import bisq.desktop.common.view.CachingViewLoader;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.common.view.View;
|
||||
import bisq.desktop.common.view.ViewLoader;
|
||||
import bisq.desktop.main.MainView;
|
||||
import bisq.desktop.main.portfolio.closedtrades.ClosedTradesView;
|
||||
import bisq.desktop.main.portfolio.duplicateoffer.DuplicateOfferView;
|
||||
import bisq.desktop.main.portfolio.editoffer.EditOfferView;
|
||||
import bisq.desktop.main.portfolio.failedtrades.FailedTradesView;
|
||||
import bisq.desktop.main.portfolio.openoffer.OpenOffersView;
|
||||
import bisq.desktop.main.portfolio.pendingtrades.PendingTradesView;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.trade.Trade;
|
||||
import bisq.core.trade.failed.FailedTradesManager;
|
||||
|
@ -48,22 +49,25 @@ import javafx.collections.ListChangeListener;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@FxmlView
|
||||
public class PortfolioView extends ActivatableView<TabPane, Void> {
|
||||
|
||||
@FXML
|
||||
Tab openOffersTab, pendingTradesTab, closedTradesTab;
|
||||
private Tab editOpenOfferTab;
|
||||
private Tab editOpenOfferTab, duplicateOfferTab;
|
||||
private final Tab failedTradesTab = new Tab(Res.get("portfolio.tab.failed").toUpperCase());
|
||||
private Tab currentTab;
|
||||
private Navigation.Listener navigationListener;
|
||||
private ChangeListener<Tab> tabChangeListener;
|
||||
private ListChangeListener<Tab> tabListChangeListener;
|
||||
|
||||
private final ViewLoader viewLoader;
|
||||
private final CachingViewLoader viewLoader;
|
||||
private final Navigation navigation;
|
||||
private final FailedTradesManager failedTradesManager;
|
||||
private EditOfferView editOfferView;
|
||||
private DuplicateOfferView duplicateOfferView;
|
||||
private boolean editOpenOfferViewOpen;
|
||||
private OpenOffer openOffer;
|
||||
private OpenOffersView openOffersView;
|
||||
|
@ -84,9 +88,9 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
pendingTradesTab.setText(Res.get("portfolio.tab.pendingTrades").toUpperCase());
|
||||
closedTradesTab.setText(Res.get("portfolio.tab.history").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(PortfolioView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
loadView(viewPath.tip(), data);
|
||||
};
|
||||
|
||||
tabChangeListener = (ov, oldValue, newValue) -> {
|
||||
|
@ -98,12 +102,16 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
navigation.navigateTo(MainView.class, PortfolioView.class, ClosedTradesView.class);
|
||||
else if (newValue == failedTradesTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, FailedTradesView.class);
|
||||
else if (newValue == editOpenOfferTab) {
|
||||
else if (newValue == editOpenOfferTab)
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, EditOfferView.class);
|
||||
else if (newValue == duplicateOfferTab) {
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, DuplicateOfferView.class);
|
||||
}
|
||||
|
||||
if (oldValue != null && oldValue == editOpenOfferTab)
|
||||
editOfferView.onTabSelected(false);
|
||||
if (oldValue != null && oldValue == duplicateOfferTab)
|
||||
duplicateOfferView.onTabSelected(false);
|
||||
|
||||
};
|
||||
|
||||
|
@ -112,6 +120,8 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
List<? extends Tab> removedTabs = change.getRemoved();
|
||||
if (removedTabs.size() == 1 && removedTabs.get(0).equals(editOpenOfferTab))
|
||||
onEditOpenOfferRemoved();
|
||||
if (removedTabs.size() == 1 && removedTabs.get(0).equals(duplicateOfferTab))
|
||||
onDuplicateOfferRemoved();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -125,6 +135,15 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
navigation.navigateTo(MainView.class, this.getClass(), OpenOffersView.class);
|
||||
}
|
||||
|
||||
private void onDuplicateOfferRemoved() {
|
||||
if (duplicateOfferView != null) {
|
||||
duplicateOfferView.onClose();
|
||||
duplicateOfferView = null;
|
||||
}
|
||||
|
||||
navigation.navigateTo(MainView.class, this.getClass(), OpenOffersView.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
failedTradesManager.getObservableList().addListener((ListChangeListener<Trade>) c -> {
|
||||
|
@ -149,6 +168,9 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
else if (root.getSelectionModel().getSelectedItem() == editOpenOfferTab) {
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, EditOfferView.class);
|
||||
if (editOfferView != null) editOfferView.onTabSelected(true);
|
||||
} else if (root.getSelectionModel().getSelectedItem() == duplicateOfferTab) {
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, DuplicateOfferView.class);
|
||||
if (duplicateOfferView != null) duplicateOfferView.onTabSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +182,7 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
currentTab = null;
|
||||
}
|
||||
|
||||
private void loadView(Class<? extends View> viewClass) {
|
||||
private void loadView(Class<? extends View> viewClass, @Nullable Object data) {
|
||||
// we want to get activate/deactivate called, so we remove the old view on tab change
|
||||
// TODO Don't understand the check for currentTab != editOpenOfferTab
|
||||
if (currentTab != null && currentTab != editOpenOfferTab)
|
||||
|
@ -195,6 +217,26 @@ public class PortfolioView extends ActivatableView<TabPane, Void> {
|
|||
view = viewLoader.load(OpenOffersView.class);
|
||||
selectOpenOffersView((OpenOffersView) view);
|
||||
}
|
||||
} else if (view instanceof DuplicateOfferView) {
|
||||
if (duplicateOfferView == null && data instanceof OfferPayload && data != null) {
|
||||
viewLoader.removeFromCache(viewClass); // remove cached dialog
|
||||
view = viewLoader.load(viewClass); // and load a fresh one
|
||||
duplicateOfferView = (DuplicateOfferView) view;
|
||||
duplicateOfferView.initWithData((OfferPayload) data);
|
||||
duplicateOfferTab = new Tab(Res.get("portfolio.tab.duplicateOffer").toUpperCase());
|
||||
duplicateOfferView.setCloseHandler(() -> {
|
||||
root.getTabs().remove(duplicateOfferTab);
|
||||
});
|
||||
root.getTabs().add(duplicateOfferTab);
|
||||
}
|
||||
if (duplicateOfferView != null) {
|
||||
if (currentTab != duplicateOfferTab)
|
||||
duplicateOfferView.onTabSelected(true);
|
||||
currentTab = duplicateOfferTab;
|
||||
} else {
|
||||
view = viewLoader.load(OpenOffersView.class);
|
||||
selectOpenOffersView((OpenOffersView) view);
|
||||
}
|
||||
}
|
||||
|
||||
currentTab.setContent(view.getRoot());
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package bisq.desktop.main.portfolio.closedtrades;
|
||||
|
||||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.common.view.ActivatableViewAndModel;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
|
@ -25,14 +26,19 @@ import bisq.desktop.components.AutoTooltipTableColumn;
|
|||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.components.PeerInfoIcon;
|
||||
import bisq.desktop.main.MainView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.ClosedTradesSummaryWindow;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.main.portfolio.PortfolioView;
|
||||
import bisq.desktop.main.portfolio.duplicateoffer.DuplicateOfferView;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.alert.PrivateNotificationManager;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.trade.Contract;
|
||||
import bisq.core.trade.Tradable;
|
||||
|
@ -42,6 +48,7 @@ import bisq.core.user.Preferences;
|
|||
import bisq.network.p2p.NodeAddress;
|
||||
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.crypto.KeyRing;
|
||||
|
||||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
|
||||
|
@ -53,9 +60,12 @@ import javafx.fxml.FXML;
|
|||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableRow;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
@ -66,6 +76,7 @@ import javafx.scene.layout.VBox;
|
|||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
|
@ -132,6 +143,8 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
Region footerSpacer;
|
||||
|
||||
private final OfferDetailsWindow offerDetailsWindow;
|
||||
private final Navigation navigation;
|
||||
private final KeyRing keyRing;
|
||||
private final Preferences preferences;
|
||||
private final TradeDetailsWindow tradeDetailsWindow;
|
||||
private final PrivateNotificationManager privateNotificationManager;
|
||||
|
@ -143,12 +156,16 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
@Inject
|
||||
public ClosedTradesView(ClosedTradesViewModel model,
|
||||
OfferDetailsWindow offerDetailsWindow,
|
||||
Navigation navigation,
|
||||
KeyRing keyRing,
|
||||
Preferences preferences,
|
||||
TradeDetailsWindow tradeDetailsWindow,
|
||||
PrivateNotificationManager privateNotificationManager,
|
||||
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
|
||||
super(model);
|
||||
this.offerDetailsWindow = offerDetailsWindow;
|
||||
this.navigation = navigation;
|
||||
this.keyRing = keyRing;
|
||||
this.preferences = preferences;
|
||||
this.tradeDetailsWindow = tradeDetailsWindow;
|
||||
this.privateNotificationManager = privateNotificationManager;
|
||||
|
@ -232,6 +249,31 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
|
||||
tableView.setRowFactory(
|
||||
tableView -> {
|
||||
final TableRow<ClosedTradableListItem> row = new TableRow<>();
|
||||
final ContextMenu rowMenu = new ContextMenu();
|
||||
MenuItem editItem = new MenuItem(Res.get("portfolio.context.offerLikeThis"));
|
||||
editItem.setOnAction((event) -> {
|
||||
try {
|
||||
OfferPayload offerPayload = row.getItem().getTradable().getOffer().getOfferPayload();
|
||||
if (offerPayload.getPubKeyRing().equals(keyRing.getPubKeyRing())) {
|
||||
navigation.navigateToWithData(offerPayload, MainView.class, PortfolioView.class, DuplicateOfferView.class);
|
||||
} else {
|
||||
new Popup().warning(Res.get("portfolio.context.notYourOffer")).show();
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
log.warn("Unable to get offerPayload - {}", e.toString());
|
||||
}
|
||||
});
|
||||
rowMenu.getItems().add(editItem);
|
||||
row.contextMenuProperty().bind(
|
||||
Bindings.when(Bindings.isNotNull(row.itemProperty()))
|
||||
.then(rowMenu)
|
||||
.otherwise((ContextMenu) null));
|
||||
return row;
|
||||
});
|
||||
|
||||
filterLabel.setText(Res.get("shared.filter"));
|
||||
HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
|
||||
filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq 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.
|
||||
*
|
||||
* Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.portfolio.duplicateoffer;
|
||||
|
||||
|
||||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.main.offer.MutableOfferDataModel;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.btc.wallet.BsqWalletService;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.offer.CreateOfferService;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OfferUtil;
|
||||
import bisq.core.offer.OpenOfferManager;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.trade.statistics.TradeStatisticsManager;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.user.User;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
class DuplicateOfferDataModel extends MutableOfferDataModel {
|
||||
|
||||
@Inject
|
||||
DuplicateOfferDataModel(CreateOfferService createOfferService,
|
||||
OpenOfferManager openOfferManager,
|
||||
OfferUtil offerUtil,
|
||||
BtcWalletService btcWalletService,
|
||||
BsqWalletService bsqWalletService,
|
||||
Preferences preferences,
|
||||
User user,
|
||||
P2PService p2PService,
|
||||
PriceFeedService priceFeedService,
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
FeeService feeService,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
TradeStatisticsManager tradeStatisticsManager,
|
||||
Navigation navigation) {
|
||||
|
||||
super(createOfferService,
|
||||
openOfferManager,
|
||||
offerUtil,
|
||||
btcWalletService,
|
||||
bsqWalletService,
|
||||
preferences,
|
||||
user,
|
||||
p2PService,
|
||||
priceFeedService,
|
||||
accountAgeWitnessService,
|
||||
feeService,
|
||||
btcFormatter,
|
||||
tradeStatisticsManager,
|
||||
navigation);
|
||||
}
|
||||
|
||||
public void populateData(Offer offer) {
|
||||
if (offer == null)
|
||||
return;
|
||||
paymentAccount = user.getPaymentAccount(offer.getMakerPaymentAccountId());
|
||||
setMinAmount(offer.getMinAmount());
|
||||
setAmount(offer.getAmount());
|
||||
setPrice(offer.getPrice());
|
||||
setVolume(offer.getVolume());
|
||||
setUseMarketBasedPrice(offer.isUseMarketBasedPrice());
|
||||
if (offer.isUseMarketBasedPrice()) {
|
||||
setMarketPriceMargin(offer.getMarketPriceMargin());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ This file is part of Bisq.
|
||||
~
|
||||
~ Bisq 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.
|
||||
~
|
||||
~ Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<AnchorPane fx:id="root" fx:controller="bisq.desktop.main.portfolio.duplicateoffer.DuplicateOfferView"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
</AnchorPane>
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq 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.
|
||||
*
|
||||
* Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.portfolio.duplicateoffer;
|
||||
|
||||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.main.offer.MutableOfferView;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
@FxmlView
|
||||
public class DuplicateOfferView extends MutableOfferView<DuplicateOfferViewModel> {
|
||||
|
||||
@Inject
|
||||
private DuplicateOfferView(DuplicateOfferViewModel model,
|
||||
Navigation navigation,
|
||||
Preferences preferences,
|
||||
OfferDetailsWindow offerDetailsWindow,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
BsqFormatter bsqFormatter) {
|
||||
super(model, navigation, preferences, offerDetailsWindow, btcFormatter, bsqFormatter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doActivate() {
|
||||
super.doActivate();
|
||||
|
||||
updatePriceToggle();
|
||||
|
||||
// To force re-validation of payment account validation
|
||||
onPaymentAccountsComboBoxSelected();
|
||||
}
|
||||
|
||||
public void initWithData(OfferPayload offerPayload) {
|
||||
initWithData(offerPayload.getDirection(), CurrencyUtil.getTradeCurrency(offerPayload.getCurrencyCode()).get());
|
||||
model.initWithData(offerPayload);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq 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.
|
||||
*
|
||||
* Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.portfolio.duplicateoffer;
|
||||
|
||||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.main.offer.MutableOfferViewModel;
|
||||
import bisq.desktop.util.validation.AltcoinValidator;
|
||||
import bisq.desktop.util.validation.BsqValidator;
|
||||
import bisq.desktop.util.validation.BtcValidator;
|
||||
import bisq.desktop.util.validation.FiatPriceValidator;
|
||||
import bisq.desktop.util.validation.FiatVolumeValidator;
|
||||
import bisq.desktop.util.validation.SecurityDepositValidator;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.offer.OfferUtil;
|
||||
import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
class DuplicateOfferViewModel extends MutableOfferViewModel<DuplicateOfferDataModel> {
|
||||
|
||||
@Inject
|
||||
public DuplicateOfferViewModel(DuplicateOfferDataModel dataModel,
|
||||
FiatVolumeValidator fiatVolumeValidator,
|
||||
FiatPriceValidator fiatPriceValidator,
|
||||
AltcoinValidator altcoinValidator,
|
||||
BtcValidator btcValidator,
|
||||
BsqValidator bsqValidator,
|
||||
SecurityDepositValidator securityDepositValidator,
|
||||
PriceFeedService priceFeedService,
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
Navigation navigation,
|
||||
Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
BsqFormatter bsqFormatter,
|
||||
OfferUtil offerUtil) {
|
||||
super(dataModel,
|
||||
fiatVolumeValidator,
|
||||
fiatPriceValidator,
|
||||
altcoinValidator,
|
||||
btcValidator,
|
||||
bsqValidator,
|
||||
securityDepositValidator,
|
||||
priceFeedService,
|
||||
accountAgeWitnessService,
|
||||
navigation,
|
||||
preferences,
|
||||
btcFormatter,
|
||||
bsqFormatter,
|
||||
offerUtil);
|
||||
syncMinAmountWithAmount = false;
|
||||
}
|
||||
|
||||
public void initWithData(OfferPayload offerPayload) {
|
||||
this.offer = new Offer(offerPayload);
|
||||
offer.setPriceFeedService(priceFeedService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
dataModel.populateData(offer);
|
||||
triggerFocusOutOnAmountFields();
|
||||
onFocusOutPriceAsPercentageTextField(true, false);
|
||||
}
|
||||
}
|
|
@ -32,10 +32,12 @@ import bisq.desktop.main.funds.withdrawal.WithdrawalView;
|
|||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.portfolio.PortfolioView;
|
||||
import bisq.desktop.main.portfolio.duplicateoffer.DuplicateOfferView;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.user.DontShowAgainLookup;
|
||||
|
||||
|
@ -52,9 +54,12 @@ import javafx.stage.Stage;
|
|||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableRow;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
@ -66,6 +71,7 @@ import javafx.scene.layout.VBox;
|
|||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
|
@ -173,6 +179,27 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
|
||||
tableView.setRowFactory(
|
||||
tableView -> {
|
||||
final TableRow<OpenOfferListItem> row = new TableRow<>();
|
||||
final ContextMenu rowMenu = new ContextMenu();
|
||||
MenuItem editItem = new MenuItem(Res.get("portfolio.context.offerLikeThis"));
|
||||
editItem.setOnAction((event) -> {
|
||||
try {
|
||||
OfferPayload offerPayload = row.getItem().getOffer().getOfferPayload();
|
||||
navigation.navigateToWithData(offerPayload, MainView.class, PortfolioView.class, DuplicateOfferView.class);
|
||||
} catch (NullPointerException e) {
|
||||
log.warn("Unable to get offerPayload - {}", e.toString());
|
||||
}
|
||||
});
|
||||
rowMenu.getItems().add(editItem);
|
||||
row.contextMenuProperty().bind(
|
||||
Bindings.when(Bindings.isNotNull(row.itemProperty()))
|
||||
.then(rowMenu)
|
||||
.otherwise((ContextMenu) null));
|
||||
return row;
|
||||
});
|
||||
|
||||
filterLabel.setText(Res.get("shared.filter"));
|
||||
HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
|
||||
filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package bisq.desktop.main.portfolio.pendingtrades;
|
||||
|
||||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.common.view.ActivatableViewAndModel;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
|
@ -25,6 +26,8 @@ import bisq.desktop.components.PeerInfoIcon;
|
|||
import bisq.desktop.main.MainView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.main.portfolio.PortfolioView;
|
||||
import bisq.desktop.main.portfolio.duplicateoffer.DuplicateOfferView;
|
||||
import bisq.desktop.main.shared.ChatView;
|
||||
import bisq.desktop.util.CssTheme;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
@ -32,6 +35,7 @@ import bisq.desktop.util.FormBuilder;
|
|||
|
||||
import bisq.core.alert.PrivateNotificationManager;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
import bisq.core.support.dispute.mediation.MediationResultState;
|
||||
import bisq.core.support.messages.ChatMessage;
|
||||
import bisq.core.support.traderchat.TradeChatSession;
|
||||
|
@ -46,6 +50,7 @@ import bisq.network.p2p.NodeAddress;
|
|||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.crypto.KeyRing;
|
||||
import bisq.common.crypto.PubKeyRing;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
|
@ -67,8 +72,11 @@ import javafx.stage.Window;
|
|||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableRow;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.input.KeyCode;
|
||||
|
@ -86,6 +94,7 @@ import javafx.geometry.Pos;
|
|||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
|
@ -108,6 +117,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
}
|
||||
|
||||
private final TradeDetailsWindow tradeDetailsWindow;
|
||||
private final Navigation navigation;
|
||||
private final KeyRing keyRing;
|
||||
private final CoinFormatter formatter;
|
||||
private final PrivateNotificationManager privateNotificationManager;
|
||||
private final boolean useDevPrivilegeKeys;
|
||||
|
@ -149,6 +160,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
@Inject
|
||||
public PendingTradesView(PendingTradesViewModel model,
|
||||
TradeDetailsWindow tradeDetailsWindow,
|
||||
Navigation navigation,
|
||||
KeyRing keyRing,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
|
||||
PrivateNotificationManager privateNotificationManager,
|
||||
Preferences preferences,
|
||||
|
@ -156,6 +169,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
@Named(Config.USE_DEV_MODE_HEADER) boolean useDevModeHeader) {
|
||||
super(model);
|
||||
this.tradeDetailsWindow = tradeDetailsWindow;
|
||||
this.navigation = navigation;
|
||||
this.keyRing = keyRing;
|
||||
this.formatter = formatter;
|
||||
this.privateNotificationManager = privateNotificationManager;
|
||||
this.preferences = preferences;
|
||||
|
@ -213,6 +228,30 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
|
|||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
|
||||
tableView.setRowFactory(
|
||||
tableView -> {
|
||||
final TableRow<PendingTradesListItem> row = new TableRow<>();
|
||||
final ContextMenu rowMenu = new ContextMenu();
|
||||
MenuItem editItem = new MenuItem(Res.get("portfolio.context.offerLikeThis"));
|
||||
editItem.setOnAction((event) -> {
|
||||
try {
|
||||
OfferPayload offerPayload = row.getItem().getTrade().getOffer().getOfferPayload();
|
||||
if (offerPayload.getPubKeyRing().equals(keyRing.getPubKeyRing())) {
|
||||
navigation.navigateToWithData(offerPayload, MainView.class, PortfolioView.class, DuplicateOfferView.class);
|
||||
} else {
|
||||
new Popup().warning(Res.get("portfolio.context.notYourOffer")).show();
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
log.warn("Unable to get offerPayload - {}", e.toString());
|
||||
}
|
||||
});
|
||||
rowMenu.getItems().add(editItem);
|
||||
row.contextMenuProperty().bind(
|
||||
Bindings.when(Bindings.isNotNull(row.itemProperty()))
|
||||
.then(rowMenu)
|
||||
.otherwise((ContextMenu) null));
|
||||
return row;
|
||||
});
|
||||
|
||||
// we use a hidden emergency shortcut to open support ticket
|
||||
keyEventEventHandler = keyEvent -> {
|
||||
|
|
|
@ -66,7 +66,7 @@ public class SettingsView extends ActivatableView<TabPane, Void> {
|
|||
networkTab.setText(Res.get("settings.tab.network").toUpperCase());
|
||||
aboutTab.setText(Res.get("settings.tab.about").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(SettingsView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
|
|
@ -133,7 +133,7 @@ public class SupportView extends ActivatableView<TabPane, Void> {
|
|||
if (tradersArbitrationDisputesTab != null) {
|
||||
tradersArbitrationDisputesTab.setText(Res.get("support.tab.legacyArbitration.support").toUpperCase());
|
||||
}
|
||||
navigationListener = viewPath -> {
|
||||
navigationListener = (viewPath, data) -> {
|
||||
if (viewPath.size() == 3 && viewPath.indexOf(SupportView.class) == 1)
|
||||
loadView(viewPath.tip());
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue