Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add warning for languages not natively supported by arbitration #1621

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/main/java/bisq/desktop/main/offer/BuyOfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.ViewLoader;

import bisq.core.arbitration.ArbitratorManager;
import bisq.core.user.Preferences;

import javax.inject.Inject;
Expand All @@ -29,8 +30,8 @@
public class BuyOfferView extends OfferView {

@Inject
public BuyOfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences) {
super(viewLoader, navigation, preferences);
public BuyOfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences, ArbitratorManager arbitratorManager) {
super(viewLoader, navigation, preferences, arbitratorManager);
}
}

59 changes: 50 additions & 9 deletions src/main/java/bisq/desktop/main/offer/OfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@
import bisq.desktop.main.offer.createoffer.CreateOfferView;
import bisq.desktop.main.offer.offerbook.OfferBookView;
import bisq.desktop.main.offer.takeoffer.TakeOfferView;
import bisq.desktop.main.overlays.popups.Popup;

import bisq.core.arbitration.ArbitratorManager;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.LanguageUtil;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.user.Preferences;
import bisq.core.user.User;

import bisq.common.UserThread;
import bisq.common.handlers.ResultHandler;

import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
Expand All @@ -47,6 +52,7 @@

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public abstract class OfferView extends ActivatableView<TabPane, Void> {

Expand All @@ -60,6 +66,7 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
private final Navigation navigation;
private final Preferences preferences;
private final OfferPayload.Direction direction;
private final ArbitratorManager arbitratorManager;

private Offer offer;
private TradeCurrency tradeCurrency;
Expand All @@ -68,11 +75,12 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
private ChangeListener<Tab> tabChangeListener;
private ListChangeListener<Tab> tabListChangeListener;

protected OfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences) {
protected OfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences, ArbitratorManager arbitratorManager) {
this.viewLoader = viewLoader;
this.navigation = navigation;
this.preferences = preferences;
this.direction = (this instanceof BuyOfferView) ? OfferPayload.Direction.BUY : OfferPayload.Direction.SELL;
this.arbitratorManager = arbitratorManager;
}

@Override
Expand Down Expand Up @@ -161,10 +169,11 @@ private void loadView(Class<? extends View> viewClass) {
@Override
public void onCreateOffer(TradeCurrency tradeCurrency) {
if (!createOfferViewOpen) {
OfferView.this.createOfferViewOpen = true;
OfferView.this.tradeCurrency = tradeCurrency;
OfferView.this.navigation.navigateTo(MainView.class, OfferView.this.getClass(),
CreateOfferView.class);
if (!arbitratorManager.isArbitratorAvailableForLanguage(preferences.getUserLanguage())) {
showNoArbitratorForUserLocaleWarning();
}
openCreateOffer(tradeCurrency);

} else {
log.error("You have already a \"Create offer\" tab open.");
}
Expand All @@ -173,10 +182,11 @@ public void onCreateOffer(TradeCurrency tradeCurrency) {
@Override
public void onTakeOffer(Offer offer) {
if (!takeOfferViewOpen) {
OfferView.this.takeOfferViewOpen = true;
OfferView.this.offer = offer;
OfferView.this.navigation.navigateTo(MainView.class, OfferView.this.getClass(),
TakeOfferView.class);
if (!arbitratorManager.getArbitratorLanguages(offer.getArbitratorNodeAddresses()).stream()
.anyMatch(languages -> languages.equals(preferences.getUserLanguage()))) {
showNoArbitratorForUserLocaleWarning();
}
openTakeOffer(offer);
} else {
log.error("You have already a \"Take offer\" tab open.");
}
Expand Down Expand Up @@ -213,6 +223,37 @@ public void onTakeOffer(Offer offer) {
}
}

private void showNoArbitratorForUserLocaleWarning() {
String key = "NoArbitratorForUserLocaleWarning";
new Popup<>().information(Res.get("offerbook.info.noArbitrationInUserLanguage",
getArbitrationLanguages(), LanguageUtil.getDisplayName(preferences.getUserLanguage())))
.closeButtonText(Res.get("shared.ok"))
.dontShowAgainId(key)
.show();
}

private String getArbitrationLanguages() {
return arbitratorManager.getArbitratorsObservableMap().values().stream()
.flatMap(arbitrator -> arbitrator.getLanguageCodes().stream())
.distinct()
.map(languageCode -> LanguageUtil.getDisplayName(languageCode))
.collect(Collectors.joining(", "));
}

private void openTakeOffer(Offer offer) {
OfferView.this.takeOfferViewOpen = true;
OfferView.this.offer = offer;
OfferView.this.navigation.navigateTo(MainView.class, OfferView.this.getClass(),
TakeOfferView.class);
}

private void openCreateOffer(TradeCurrency tradeCurrency) {
OfferView.this.createOfferViewOpen = true;
OfferView.this.tradeCurrency = tradeCurrency;
OfferView.this.navigation.navigateTo(MainView.class, OfferView.this.getClass(),
CreateOfferView.class);
}

private void onCreateOfferViewRemoved() {
createOfferViewOpen = false;
if (createOfferView != null) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/bisq/desktop/main/offer/SellOfferView.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.ViewLoader;

import bisq.core.arbitration.ArbitratorManager;
import bisq.core.user.Preferences;

import javax.inject.Inject;
Expand All @@ -29,8 +30,8 @@
public class SellOfferView extends OfferView {

@Inject
public SellOfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences) {
super(viewLoader, navigation, preferences);
public SellOfferView(ViewLoader viewLoader, Navigation navigation, Preferences preferences, ArbitratorManager arbitratorManager) {
super(viewLoader, navigation, preferences, arbitratorManager);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package bisq.desktop.main.settings.preferences;

import bisq.desktop.common.model.Activatable;
import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.AutoTooltipButton;
Expand Down Expand Up @@ -85,7 +84,7 @@
import static bisq.desktop.util.FormBuilder.*;

@FxmlView
public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatable> {
public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> {

// not supported yet
//private ComboBox<String> btcDenominationComboBox;
Expand Down Expand Up @@ -129,9 +128,9 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
///////////////////////////////////////////////////////////////////////////////////////////

@Inject
public PreferencesView(Preferences preferences, FeeService feeService, ReferralIdService referralIdService,
public PreferencesView(PreferencesViewModel model, Preferences preferences, FeeService feeService, ReferralIdService referralIdService,
BSFormatter formatter) {
super();
super(model);
this.preferences = preferences;
this.feeService = feeService;
this.referralIdService = referralIdService;
Expand Down Expand Up @@ -514,6 +513,13 @@ public String fromString(String string) {
new Popup<>().information(Res.get("settings.preferences.languageChange"))
.closeButtonText(Res.get("shared.ok"))
.show();

if (model.needsArbitrationLanguageWarning()) {
new Popup<>().warning(Res.get("settings.preferences.arbitrationLanguageWarning",
model.getArbitrationLanguages()))
.closeButtonText(Res.get("shared.ok"))
.show();
}
}
// Should we apply the changed currency immediately to the language list?
// If so and the user selects a unknown language he might get lost and it is hard to find
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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.settings.preferences;


import bisq.desktop.common.model.ActivatableViewModel;

import bisq.core.arbitration.ArbitratorManager;
import bisq.core.locale.LanguageUtil;
import bisq.core.user.Preferences;

import com.google.inject.Inject;

import java.util.stream.Collectors;

public class PreferencesViewModel extends ActivatableViewModel {

private final ArbitratorManager arbitratorManager;
private final Preferences preferences;

@Inject
public PreferencesViewModel(Preferences preferences, ArbitratorManager arbitratorManager) {
this.preferences = preferences;
this.arbitratorManager = arbitratorManager;
}

boolean needsArbitrationLanguageWarning() {
return !arbitratorManager.isArbitratorAvailableForLanguage(preferences.getUserLanguage());
}

String getArbitrationLanguages() {
return arbitratorManager.getArbitratorsObservableMap().values().stream()
.flatMap(arbitrator -> arbitrator.getLanguageCodes().stream())
.distinct()
.map(languageCode -> LanguageUtil.getDisplayName(languageCode))
.collect(Collectors.joining(", "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.settings.preferences;

import bisq.core.arbitration.Arbitrator;
import bisq.core.arbitration.ArbitratorManager;
import bisq.core.user.PreferenceMakers;
import bisq.core.user.Preferences;

import bisq.network.p2p.NodeAddress;

import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;

import java.util.ArrayList;

import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ArbitratorManager.class, Preferences.class})
public class PreferencesViewModelTest {

@Before
public void setUp() {
Security.addProvider(new BouncyCastleProvider());
}

@Test
public void testGetArbitrationLanguages() {

ArbitratorManager arbitratorManager = mock(ArbitratorManager.class);

final ObservableMap<NodeAddress, Arbitrator> arbitrators = FXCollections.observableHashMap();

ArrayList<String> languagesOne = new ArrayList<String>() {{
add("en");
add("de");
}};

ArrayList<String> languagesTwo = new ArrayList<String>() {{
add("en");
add("es");
}};

Arbitrator one = new Arbitrator(new NodeAddress("arbitrator:1"), null, null, null,
languagesOne, 0L, null, "", null,
null, null);

Arbitrator two = new Arbitrator(new NodeAddress("arbitrator:2"), null, null, null,
languagesTwo, 0L, null, "", null,
null, null);

arbitrators.put(one.getNodeAddress(), one);
arbitrators.put(two.getNodeAddress(), two);

Preferences preferences = PreferenceMakers.empty;

when(arbitratorManager.getArbitratorsObservableMap()).thenReturn(arbitrators);

PreferencesViewModel model = new PreferencesViewModel(preferences, arbitratorManager);

assertEquals("English, Deutsch, español", model.getArbitrationLanguages());
}

}