Skip to content

Commit

Permalink
Merge pull request #613 from HenrikJannsen/fix_mediation_handling
Browse files Browse the repository at this point in the history
Fix mediation handling
  • Loading branch information
alvasw authored Dec 22, 2022
2 parents 91604bb + 5714ba5 commit 7f652b0
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 99 deletions.
28 changes: 12 additions & 16 deletions chat/src/main/java/bisq/chat/channel/PrivateChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,31 @@
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public abstract class PrivateChannel<T extends PrivateChatMessage> extends Channel<T> {
protected final UserProfile peer;

public static String createChannelId(String peersId, String myId) {
// Need to have an ordering here, otherwise there would be 2 channelIds for the same participants
if (peersId.compareTo(myId) < 0) {
return peersId + "-" + myId;
} else {
return myId + "-" + peersId;
}
}

protected final UserIdentity myUserIdentity;

// We persist the messages as they are NOT persisted in the P2P data store.
protected final ObservableArray<T> chatMessages = new ObservableArray<>();

public PrivateChannel(String id,
UserProfile peer,
UserIdentity myUserIdentity,
List<T> chatMessages,
ChannelNotificationType channelNotificationType) {
super(id, channelNotificationType);
this.peer = peer;

this.myUserIdentity = myUserIdentity;
this.chatMessages.addAll(chatMessages);
this.chatMessages.sort(Comparator.comparing((T e) -> new ByteArray(e.serialize())));
}

public static String createChannelId(String peersId, String myId) {
// Need to have an ordering here, otherwise there would be 2 channelIds for the same participants
if (peersId.compareTo(myId) < 0) {
return peersId + "-" + myId;
} else {
return myId + "-" + peersId;
}
}

@Override
public String getDisplayString() {
return peer.getUserName() + " - " + myUserIdentity.getUserName();
}
public abstract UserProfile getPeer();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@Getter
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public final class PrivateDiscussionChannel extends PrivateChannel<PrivateDiscussionChatMessage> {
private final UserProfile peer;

public PrivateDiscussionChannel(UserProfile peer, UserIdentity myProfile) {
this(PrivateChannel.createChannelId(peer.getId(), myProfile.getId()),
Expand All @@ -48,7 +49,9 @@ private PrivateDiscussionChannel(String id,
UserIdentity myProfile,
List<PrivateDiscussionChatMessage> chatMessages,
ChannelNotificationType channelNotificationType) {
super(id, peer, myProfile, chatMessages, channelNotificationType);
super(id, myProfile, chatMessages, channelNotificationType);

this.peer = peer;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@Getter
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public final class PrivateEventsChannel extends PrivateChannel<PrivateEventsChatMessage> {
private final UserProfile peer;

public PrivateEventsChannel(UserProfile peer, UserIdentity myProfile) {
this(PrivateChannel.createChannelId(peer.getId(), myProfile.getId()),
Expand All @@ -48,7 +49,9 @@ private PrivateEventsChannel(String id,
UserIdentity myProfile,
List<PrivateEventsChatMessage> chatMessages,
ChannelNotificationType channelNotificationType) {
super(id, peer, myProfile, chatMessages, channelNotificationType);
super(id, myProfile, chatMessages, channelNotificationType);

this.peer = peer;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@Getter
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public final class PrivateSupportChannel extends PrivateChannel<PrivateSupportChatMessage> {
private final UserProfile peer;

public PrivateSupportChannel(UserProfile peer, UserIdentity myProfile) {
this(PrivateChannel.createChannelId(peer.getId(), myProfile.getId()),
Expand All @@ -48,7 +49,9 @@ private PrivateSupportChannel(String id,
UserIdentity myProfile,
List<PrivateSupportChatMessage> chatMessages,
ChannelNotificationType channelNotificationType) {
super(id, peer, myProfile, chatMessages, channelNotificationType);
super(id, myProfile, chatMessages, channelNotificationType);

this.peer = peer;
}

@Override
Expand Down
88 changes: 67 additions & 21 deletions chat/src/main/java/bisq/chat/trade/priv/PrivateTradeChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,78 @@
import java.util.Optional;
import java.util.stream.Collectors;

/**
* PrivateTradeChannel is either a 2 party channel of both traders or a 3 party channel with 2 traders and the mediator.
* Depending on the case the fields are differently interpreted.
* Maybe we should model a group chat channel for a cleaner API.
*/
@ToString(callSuper = true)
@Getter
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
public final class PrivateTradeChannel extends PrivateChannel<PrivateTradeChatMessage> {
private final UserProfile trader1;
private final UserProfile trader2;
private final Optional<UserProfile> mediator;
public static PrivateTradeChannel createByTrader(UserIdentity myUserIdentity,
UserProfile peer,
Optional<UserProfile> mediator) {
return new PrivateTradeChannel(peer,
myUserIdentity.getUserProfile(),
myUserIdentity,
mediator);
}

public static PrivateTradeChannel createByMediator(UserIdentity myUserIdentity,
UserProfile trader1,
UserProfile trader2) {
return new PrivateTradeChannel(trader1,
trader2,
myUserIdentity,
Optional.of(myUserIdentity.getUserProfile()));
}

private final UserProfile peerOrTrader1;
private final UserProfile myUserProfileOrTrader2;
private final UserIdentity myUserIdentity;
private final Observable<Boolean> mediationActivated = new Observable<>(false);
private final Optional<UserProfile> mediator;
private final Observable<Boolean> inMediation = new Observable<>(false);

public PrivateTradeChannel(UserIdentity myUserIdentity, UserProfile trader1, UserProfile trader2, Optional<UserProfile> mediator) {
super(PrivateChannel.createChannelId(trader1.getId(), trader2.getId()),
trader1,
private PrivateTradeChannel(UserProfile peerOrTrader1,
UserProfile myUserProfileOrTrader2,
UserIdentity myUserIdentity,
Optional<UserProfile> mediator) {
super(PrivateChannel.createChannelId(peerOrTrader1.getId(), myUserProfileOrTrader2.getId()),
myUserIdentity,
new ArrayList<>(),
ChannelNotificationType.ALL);
this.trader1 = trader1;
this.trader2 = trader2;
this.mediator = mediator;
this.peerOrTrader1 = peerOrTrader1;
this.myUserProfileOrTrader2 = myUserProfileOrTrader2;
this.myUserIdentity = myUserIdentity;
this.mediator = mediator;
}

private PrivateTradeChannel(String id,
UserProfile peer,
UserProfile peerOrTrader1,
UserProfile myUserProfileOrTrader2,
UserIdentity myUserIdentity,
Optional<UserProfile> mediator,
List<PrivateTradeChatMessage> chatMessages,
ChannelNotificationType channelNotificationType) {
super(id, peer, myUserIdentity, chatMessages, channelNotificationType);
super(id, myUserIdentity, chatMessages, channelNotificationType);

this.trader1 = peer;
this.trader2 = myUserIdentity.getUserProfile();
this.mediator = mediator;
this.peerOrTrader1 = peerOrTrader1;
this.myUserProfileOrTrader2 = myUserProfileOrTrader2;
this.myUserIdentity = myUserIdentity;
this.mediator = mediator;
}

@Override
public bisq.chat.protobuf.Channel toProto() {
bisq.chat.protobuf.PrivateTradeChannel.Builder builder = bisq.chat.protobuf.PrivateTradeChannel.newBuilder()
.setPeer(peer.toProto())
.setPeerOrTrader1(peerOrTrader1.toProto())
.setMyUserProfileOrTrader2(myUserProfileOrTrader2.toProto())
.setMyUserIdentity(this.myUserIdentity.toProto())
.addAllChatMessages(chatMessages.stream()
.map(PrivateTradeChatMessage::toChatMessageProto)
.collect(Collectors.toList()))
.setMediationActivated(mediationActivated.get());
.setInMediation(inMediation.get());
mediator.ifPresent(mediator -> builder.setMediator(mediator.toProto()));
return getChannelBuilder().setPrivateTradeChannel(builder).build();
}
Expand All @@ -86,14 +113,15 @@ public static PrivateTradeChannel fromProto(bisq.chat.protobuf.Channel baseProto
bisq.chat.protobuf.PrivateTradeChannel proto) {
PrivateTradeChannel privateTradeChannel = new PrivateTradeChannel(
baseProto.getId(),
UserProfile.fromProto(proto.getPeer()),
UserProfile.fromProto(proto.getPeerOrTrader1()),
UserProfile.fromProto(proto.getMyUserProfileOrTrader2()),
UserIdentity.fromProto(proto.getMyUserIdentity()),
proto.hasMediator() ? Optional.of(UserProfile.fromProto(proto.getMediator())) : Optional.empty(),
proto.getChatMessagesList().stream()
.map(PrivateTradeChatMessage::fromProto)
.collect(Collectors.toList()),
ChannelNotificationType.fromProto(baseProto.getChannelNotificationType()));
privateTradeChannel.getMediationActivated().set(proto.getMediationActivated());
privateTradeChannel.getInMediation().set(proto.getInMediation());
return privateTradeChannel;
}

Expand All @@ -119,9 +147,27 @@ public boolean isMediator() {
@Override
public String getDisplayString() {
String mediatorLabel = "";
if (mediator.isPresent() && mediationActivated.get()) {
if (mediator.isPresent() && inMediation.get()) {
mediatorLabel = " (" + Res.get("mediator") + ": " + mediator.get().getUserName() + ")";
}
return peer.getUserName() + " - " + myUserIdentity.getUserName() + mediatorLabel;
if (isMediator()) {
return peerOrTrader1.getUserName() + " - " + myUserProfileOrTrader2.getUserName() + mediatorLabel;
} else {
return peerOrTrader1.getUserName() + " - " + myUserIdentity.getUserName() + mediatorLabel;
}
}

public String getChannelSelectionDisplayString() {
if (isMediator()) {
return peerOrTrader1.getUserName() + ", " + myUserProfileOrTrader2.getUserName();
} else if (mediator.isPresent() && inMediation.get()) {
return peerOrTrader1.getUserName() + ", " + mediator.get().getUserName();
} else {
return peerOrTrader1.getUserName();
}
}

public UserProfile getPeer() {
return peerOrTrader1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public PrivateTradeChannelService(PersistenceService persistenceService,
}

public void setMediationActivated(PrivateTradeChannel channel, boolean mediationActivated) {
channel.getMediationActivated().set(mediationActivated);
channel.getInMediation().set(mediationActivated);
persist();
}

Expand Down Expand Up @@ -97,15 +97,14 @@ protected PrivateTradeChannel createNewChannel(UserProfile peer, UserIdentity my
public PrivateTradeChannel mediatorCreatesNewChannel(UserIdentity myUserIdentity, UserProfile trader1, UserProfile trader2) {
Optional<PrivateTradeChannel> existingChannel = getChannels().stream()
.filter(channel -> channel.getMyUserIdentity().equals(myUserIdentity) &&
channel.getTrader1().equals(trader1) &&
channel.getTrader2().equals(trader1))
channel.getPeerOrTrader1().equals(trader1) &&
channel.getMyUserProfileOrTrader2().equals(trader1))
.findAny();
if (existingChannel.isPresent()) {
return existingChannel.get();
}

Optional<UserProfile> mediator = Optional.of(myUserIdentity.getUserProfile());
PrivateTradeChannel channel = new PrivateTradeChannel(myUserIdentity, trader1, trader2, mediator);
PrivateTradeChannel channel = PrivateTradeChannel.createByMediator(myUserIdentity, trader1, trader2);
getChannels().add(channel);
persist();
return channel;
Expand All @@ -120,7 +119,7 @@ public PrivateTradeChannel traderCreatesNewChannel(UserIdentity myUserIdentity,
return existingChannel.get();
}

PrivateTradeChannel channel = new PrivateTradeChannel(myUserIdentity, peersUserProfile, myUserIdentity.getUserProfile(), mediator);
PrivateTradeChannel channel = PrivateTradeChannel.createByTrader(myUserIdentity, peersUserProfile, mediator);
getChannels().add(channel);
persist();
return channel;
Expand Down Expand Up @@ -151,17 +150,17 @@ public CompletableFuture<NetworkService.SendMessageResult> sendPrivateChatMessag
PrivateTradeChannel channel) {
UserIdentity myUserIdentity = channel.getMyUserIdentity();
String messageId = StringUtils.createShortUid();
if (!channel.getMediationActivated().get() || channel.getMediator().isEmpty()) {
if (!channel.getInMediation().get() || channel.getMediator().isEmpty()) {
return super.sendPrivateChatMessage(messageId, text, quotedMessage, channel, myUserIdentity, channel.getPeer());
}
// If mediation has been activated we send all messages to the 2 other peers
UserProfile receiver1, receiver2;
if (channel.isMediator()) {
receiver1 = channel.getTrader1();
receiver2 = channel.getTrader2();
receiver1 = channel.getPeerOrTrader1();
receiver2 = channel.getMyUserProfileOrTrader2();
} else {
receiver1 = channel.getPeer();
receiver2 = channel.getMediator().orElseThrow();
receiver2 = channel.getMediator().get();
}

UserProfile senderUserProfile = myUserIdentity.getUserProfile();
Expand Down
9 changes: 5 additions & 4 deletions chat/src/main/proto/chat.proto
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,12 @@ message PublicTradeChatMessage {
}

message PrivateTradeChannel {
user.UserProfile peer = 1;
user.UserIdentity myUserIdentity = 2;
repeated ChatMessage chatMessages = 3;
user.UserProfile peerOrTrader1 = 1;
user.UserProfile myUserProfileOrTrader2 = 2;
user.UserIdentity myUserIdentity = 3;
optional user.UserProfile mediator = 4;
bool mediationActivated = 5;
repeated ChatMessage chatMessages = 5;
bool inMediation = 6;
}

message PublicTradeChannel {
Expand Down
Loading

0 comments on commit 7f652b0

Please sign in to comment.