diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 2791e23f4..ed4f091f8 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -2861,6 +2861,10 @@ public class CallActivity extends CallBaseActivity { addParticipantDisplayItem(callParticipantModel, "screen"); } } + + @Override + public void onReaction(String reaction) { + } } private class InternalSignalingMessageSender implements SignalingMessageSender { diff --git a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java index e488b9384..758f86a7b 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/ParticipantDisplayItem.java @@ -34,7 +34,16 @@ public class ParticipantDisplayItem { private final CallParticipantModel callParticipantModel; - private final CallParticipantModel.Observer callParticipantModelObserver = this::updateFromModel; + private final CallParticipantModel.Observer callParticipantModelObserver = new CallParticipantModel.Observer() { + @Override + public void onChange() { + updateFromModel(); + } + + @Override + public void onReaction(String reaction) { + } + }; private String userId; private PeerConnection.IceConnectionState iceConnectionState; diff --git a/app/src/main/java/com/nextcloud/talk/call/CallParticipant.java b/app/src/main/java/com/nextcloud/talk/call/CallParticipant.java index e0f4df295..02d3c8d2b 100644 --- a/app/src/main/java/com/nextcloud/talk/call/CallParticipant.java +++ b/app/src/main/java/com/nextcloud/talk/call/CallParticipant.java @@ -42,6 +42,7 @@ public class CallParticipant { @Override public void onReaction(String reaction) { + callParticipantModel.emitReaction(reaction); } @Override diff --git a/app/src/main/java/com/nextcloud/talk/call/CallParticipantModel.java b/app/src/main/java/com/nextcloud/talk/call/CallParticipantModel.java index c8b1491d9..4f29420d1 100644 --- a/app/src/main/java/com/nextcloud/talk/call/CallParticipantModel.java +++ b/app/src/main/java/com/nextcloud/talk/call/CallParticipantModel.java @@ -42,11 +42,15 @@ import java.util.Objects; * Getters called after receiving a notification are guaranteed to provide at least the value that triggered the * notification, but it may return even a more up to date one (so getting the value again on the following * notification may return the same value as before). + * + * Besides onChange(), which notifies about changes in the model values, CallParticipantModel.Observer provides + * additional methods to be notified about one-time events that are not reflected in the model values, like reactions. */ public class CallParticipantModel { public interface Observer { void onChange(); + void onReaction(String reaction); } protected class Data { @@ -68,7 +72,7 @@ public class CallParticipantModel { } } - private final CallParticipantModelNotifier callParticipantModelNotifier = new CallParticipantModelNotifier(); + protected final CallParticipantModelNotifier callParticipantModelNotifier = new CallParticipantModelNotifier(); protected final String sessionId; diff --git a/app/src/main/java/com/nextcloud/talk/call/CallParticipantModelNotifier.java b/app/src/main/java/com/nextcloud/talk/call/CallParticipantModelNotifier.java index ddf30c1d7..e0b6904fc 100644 --- a/app/src/main/java/com/nextcloud/talk/call/CallParticipantModelNotifier.java +++ b/app/src/main/java/com/nextcloud/talk/call/CallParticipantModelNotifier.java @@ -83,4 +83,16 @@ class CallParticipantModelNotifier { } } } + + public synchronized void notifyReaction(String reaction) { + for (CallParticipantModelObserverOn observerOn : new ArrayList<>(callParticipantModelObserversOn)) { + if (observerOn.handler == null || observerOn.handler.getLooper() == Looper.myLooper()) { + observerOn.observer.onReaction(reaction); + } else { + observerOn.handler.post(() -> { + observerOn.observer.onReaction(reaction); + }); + } + } + } } diff --git a/app/src/main/java/com/nextcloud/talk/call/MutableCallParticipantModel.java b/app/src/main/java/com/nextcloud/talk/call/MutableCallParticipantModel.java index 2772b0030..f57bd16d7 100644 --- a/app/src/main/java/com/nextcloud/talk/call/MutableCallParticipantModel.java +++ b/app/src/main/java/com/nextcloud/talk/call/MutableCallParticipantModel.java @@ -72,4 +72,8 @@ public class MutableCallParticipantModel extends CallParticipantModel { public void setScreenMediaStream(MediaStream screenMediaStream) { this.screenMediaStream.setValue(screenMediaStream); } + + public void emitReaction(String reaction) { + this.callParticipantModelNotifier.notifyReaction(reaction); + } } diff --git a/app/src/test/java/com/nextcloud/talk/call/CallParticipantModelTest.kt b/app/src/test/java/com/nextcloud/talk/call/CallParticipantModelTest.kt index efba5bd4e..29e144bb9 100644 --- a/app/src/test/java/com/nextcloud/talk/call/CallParticipantModelTest.kt +++ b/app/src/test/java/com/nextcloud/talk/call/CallParticipantModelTest.kt @@ -55,4 +55,11 @@ class CallParticipantModelTest { callParticipantModel!!.setRaisedHand(true, 4815162342L) Mockito.verify(mockedCallParticipantModelObserver, Mockito.only())?.onChange() } + + @Test + fun testEmitReaction() { + callParticipantModel!!.addObserver(mockedCallParticipantModelObserver) + callParticipantModel!!.emitReaction("theReaction") + Mockito.verify(mockedCallParticipantModelObserver, Mockito.only())?.onReaction("theReaction") + } }